@@ -495,6 +495,8 @@ set GOCACHE=%cd%\\{gotmp}\\gocache
495495set GOPATH=%cd%"\\ {gotmp}\\ gopath
496496set GOTOOLCHAIN=local
497497set GO111MODULE=off
498+ set GOTELEMETRY=off
499+ set GOENV=off
498500{go} build -o {out} -trimpath -ldflags \" -buildid='' {ldflags}\" {srcs}
499501set GO_EXIT_CODE=%ERRORLEVEL%
500502RMDIR /S /Q "{gotmp}"
@@ -523,26 +525,40 @@ exit /b %GO_EXIT_CODE%
523525 mnemonic = "GoToolchainBinaryBuild" ,
524526 )
525527 else :
526- # Note: GOPATH is needed for Go 1.16.
527- cmd = """
528- GOTMP=$(mktemp -d)
529- trap "rm -rf \" $GOTMP\" " EXIT
530- GOMAXPROCS=1 \
531- GOCACHE="$GOTMP"/gocache \
532- GOPATH="$GOTMP"/gopath \
533- GOTOOLCHAIN=local \
534- GO111MODULE=off \
535- {go} build -o {out} -trimpath -ldflags '-buildid="" {ldflags}' {srcs}
536- """ .format (
537- go = sdk .go .path ,
538- out = out .path ,
539- srcs = " " .join ([f .path for f in ctx .files .srcs ]),
540- ldflags = ctx .attr .ldflags ,
541- )
528+ # -a flag instructs the compiler to not read from GOCACHE and force a rebuild.
529+ # This provides extra safety in cases of unsandboxed execution.
530+ args = ctx .actions .args ()
531+ args .add ("build" )
532+ args .add ("-a" )
533+ args .add ("-o" , out )
534+ args .add ("-trimpath" )
535+ args .add ("-ldflags" , ctx .attr .ldflags , format = '-buildid="" %s' )
536+ args .add_all (ctx .files .srcs )
537+
542538 ctx .actions .run_shell (
543- command = cmd ,
544- tools = depset (
545- ctx .files .srcs + [sdk .go ],
539+ command = """
540+ trap "HOME={HOME} GOROOT={GOROOT} {go} clean -cache" EXIT;
541+ HOME={HOME} {go} "$@" """ .format (
542+ go = sdk .go .path ,
543+ GOROOT = sdk .root_file .dirname ,
544+ # The value of GOCACHE/GOPATH are determined from HOME.
545+ # We place them in the execroot to avoid dependency on `mktemp` and because we don't know
546+ # a safe scratch space on all systems. Note that HOME must be an absolute path, otherwise the
547+ # Go toolchain will write some outputs to the wrong place and the result will be uncacheable.
548+ # We use a hardcoded UUID to prevent collisions with anything else under unsandboxed strategy.
549+ HOME = "$(pwd)/_go_tool_binary-fake-home-85e96dea-541b-4188-8d13-5c2c42bdbd06" ,
550+ ),
551+ arguments = [args ],
552+ tools = [sdk .go ],
553+ env = {
554+ "GOMAXPROCS" : "1" ,
555+ "GOTOOLCHAIN" : "local" ,
556+ "GO111MODULE" : "off" ,
557+ "GOTELEMETRY" : "off" ,
558+ "GOENV" : "off" ,
559+ },
560+ inputs = depset (
561+ ctx .files .srcs ,
546562 transitive = [sdk .headers , sdk .srcs , sdk .libs , sdk .tools ],
547563 ),
548564 toolchain = None ,
0 commit comments