# Ensure that "does not match any packages" works. env GOGARBLE=match-absolutely/nothing ! exec garble build -o=out ./standalone stderr '^GOGARBLE="match-absolutely/nothing" does not match any packages to be built$' # A build where just some packages are obfuscated. env GOGARBLE=test/main/imported exec garble -literals build -o=out ./importer ! binsubstr out 'some long string to obfuscate' binsubstr out 'some long string to not obfuscate' # Obfuscated packages which import non-obfuscated std packages. # Some of the imported std packages use "import maps" due to vendoring, # and a past bug made this case fail for "garble build". env GOGARBLE=test/main exec garble build -o=out ./stdimporter [short] stop # rebuilding std is slow # Go back to the default of obfuscating all packages. env GOGARBLE='*' # Try garbling all of std, given some std packages. # No need for a main package here; building the std packages directly works the # same, and is faster as we don't need to link a binary. # This used to cause multiple errors, mainly since std vendors some external # packages so we must properly support ImportMap. # Plus, some packages like net make heavy use of complex features like Cgo. # Note that we won't obfuscate a few std packages just yet, mainly those around runtime. exec garble build std ! stderr . # no warnings # Link a binary importing net/http, which will catch whether or not we # support ImportMap when linking. # Also ensure we are obfuscating low-level std packages. exec garble build -o=out ./stdimporter ! stderr . # no warnings ! binsubstr out 'http.ListenAndServe' 'debug.WriteHeapDump' 'time.Now' # The same low-level std packages appear in plain sight in regular builds. go build -o=out_regular ./stdimporter binsubstr out_regular 'http.ListenAndServe' 'debug.WriteHeapDump' 'time.Now' # Also check that a full rebuild is reproducible, via a new GOCACHE. # This is slow, but necessary to uncover bugs hidden by the build cache. # We also forcibly rebuild runtime on its own, given it used to be non-reproducible # due to its use of linknames pointing at std packages it doesn't depend upon. [darwin] skip 'see https://github.com/burrowers/garble/issues/609' env GOCACHE=${WORK}/gocache-empty exec garble build -a runtime exec garble build -o=out_rebuild ./stdimporter bincmp out_rebuild out -- go.mod -- module test/main go 1.22 -- standalone/main.go -- package main func main() {} -- importer/importer.go -- package main import "test/main/imported" func main() { println(imported.LongString) println("some long string to not obfuscate") } -- imported/imported.go -- package imported var LongString = "some long string to obfuscate" -- stdimporter/main.go -- package main import ( "net/http" "runtime/debug" "time" ) func main() { http.ListenAndServe("", nil) // debug.WriteHeapDump is particularly interesting, // as it is implemented by runtime via a linkname. debug.WriteHeapDump(1) time.Now() }