# Note that this is the only test with a module where we rely on the detection # of GOPRIVATE. # Also note that, since this is the only test using "real" external modules # fetched via GOPROXY, go.mod and go.sum should declare the dependencies. garble build -tags buildtag exec cat go.sum exec ./main cmp stdout main.stdout ! binsubstr main$exe 'ImportedVar' 'ImportedConst' 'ImportedFunc' 'ImportedType' 'main.go' 'test/main' 'imported.' 'NormalStruct' 'NormalExportedField' 'normalUnexportedField' binsubstr main$exe 'ReflectInDefined' 'ExportedField2' 'unexportedField2' [short] stop # checking that the build is reproducible is slow # Also check that the binary is reproducible when many imports are involved. # No packages should be rebuilt either, thanks to the build cache. cp main$exe main_old$exe rm main$exe garble build -tags buildtag -v ! stderr . bincmp main$exe main_old$exe go build -tags buildtag exec ./main cmp stdout main.stdout # Also check that -literals doesn't break anything garble -literals build -tags buildtag exec ./main cmp stdout main.stdout -- go.mod -- module test/main go 1.15 require rsc.io/quote v1.5.2 -- go.sum -- golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0= rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -- main.go -- package main import ( "fmt" "strings" "reflect" _ "unsafe" "test/main/imported" "rsc.io/quote" ) //go:linkname linkedPrintln fmt.Println func linkedPrintln(a ...interface{}) (n int, err error) func main() { fmt.Println(imported.ImportedVar) fmt.Println(imported.ImportedConst) fmt.Println(imported.ImportedFunc('x')) fmt.Println(imported.ImportedType(3)) fmt.Println(imported.ReflectInDefinedVar.ExportedField2) fmt.Println(imported.ReflectInDefined{ExportedField2: 5}) fmt.Println(imported.NormalStruct{SharedName: 3}) printfWithoutPackage("%T\n", imported.ReflectTypeOf(2)) printfWithoutPackage("%T\n", imported.ReflectTypeOfIndirect(4)) v := imported.ReflectValueOfVar printfWithoutPackage("%#v\n", v) method := reflect.ValueOf(&v).MethodByName("ExportedMethodName") if method.IsValid() { fmt.Println(method.Call(nil)) } else { fmt.Println("method not found") } linkedPrintln(nil) fmt.Println(quote.Go()) } func printfWithoutPackage(format string, v interface{}) { fmt.Print(strings.Split(fmt.Sprintf(format, v), ".")[1]) } -- notag_fail.go -- // +build !buildtag package main var foo int = "should be omitted by -tags" -- withtag_success.go -- // +build buildtag package main import "fmt" func init() { fmt.Println("buildtag init func") } -- imported/imported.go -- package imported import "reflect" var ImportedVar = "imported var value" const ImportedConst = "imported const value" func ImportedFunc(param rune) string { return string(param) } type ReflectTypeOf int var _ = reflect.TypeOf(ReflectTypeOf(0)) type ReflectTypeOfIndirect int var _ = reflect.TypeOf(new([]*ReflectTypeOfIndirect)) type ReflectValueOf struct { ExportedField string unexportedField string } func (r *ReflectValueOf) ExportedMethodName() string { return "method: "+r.ExportedField } var ReflectValueOfVar = ReflectValueOf{ExportedField: "abc"} var _ = reflect.TypeOf(ReflectValueOfVar) type ReflectInDefined struct { ExportedField2 int unexportedField2 int } var ReflectInDefinedVar = ReflectInDefined{ExportedField2: 9000} var _ = reflect.TypeOf(ReflectInDefinedVar) const SharedName = 2 type NormalStruct struct { SharedName int normalUnexportedField int } // ImportedType comes after the calls to reflect, to ensure no false positives. type ImportedType int -- main.stdout -- buildtag init func imported var value imported const value x 3 9000 {5 0} {3 0} ReflectTypeOf ReflectTypeOfIndirect ReflectValueOf{ExportedField:"abc", unexportedField:""} [method: abc] Don't communicate by sharing memory, share memory by communicating.