garble build -tags buildtag exec ./main cmp stdout main.stdout ! binsubstr main$exe 'ImportedVar' 'ImportedConst' 'ImportedFunc' 'ImportedType' 'main.go' 'imported.go' [short] stop # checking that the build is reproducible is slow # Also check that the binary is reproducible when many imports are involved. cp main$exe main_old$exe rm main$exe garble build -tags buildtag 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 -- main.go -- package main import ( "fmt" "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.Printf("%T\n", imported.ReflectTypeOf(2)) fmt.Printf("%T\n", imported.ReflectTypeOfIndirect(4)) v := imported.ReflectValueOfVar fmt.Printf("%#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()) } -- 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) // 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 imported.ReflectTypeOf imported.ReflectTypeOfIndirect imported.ReflectValueOf{ExportedField:"abc", unexportedField:""} [method: abc] Don't communicate by sharing memory, share memory by communicating.