Skip to content

Commit de74ea5

Browse files
committed
cmd/go: set TOOLEXEC_IMPORTPATH for -toolexec tools
This way, a -toolexec tool can tell precisely what package is being built when it's run. This was very hard to do before, because the tool had to piece together that information given the build action's arguments or flags. Since there wasn't a good set of tests for -toolexec, add one in the form of a test script. It builds a simple set of packages with a variety of build tools, to ensure that all the cases behave as expected. Like other recent master changes, include the changelog item for this user-facing change too. Fixes #15677. Change-Id: I0a5a1d9485840323ec138b2e64b7e7dd803fdf90 Reviewed-on: https://go-review.googlesource.com/c/go/+/263357 Run-TryBot: Daniel Martí <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]> Trust: Daniel Martí <[email protected]>
1 parent 61313da commit de74ea5

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

doc/go1.16.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,15 @@ <h4 id="all-pattern">The <code>all</code> pattern</h4>
122122
by <code>go</code> <code>mod</code> <code>vendor</code> since Go 1.11.
123123
</p>
124124

125+
<h4 id="toolexec">The <code>-toolexec</code> build flag</h4>
126+
127+
<p><!-- golang.org/cl/263357 -->
128+
When the <code>-toolexec</code> build flag is specified to use a program when
129+
invoking toolchain programs like compile or asm, the environment variable
130+
<code>TOOLEXEC_IMPORTPATH</code> is now set to the import path of the package
131+
being built.
132+
</p>
133+
125134
<h3 id="cgo">Cgo</h3>
126135

127136
<p> <!-- CL 252378 -->

src/cmd/go/internal/work/exec.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,6 +2001,13 @@ func (b *Builder) runOut(a *Action, dir string, env []string, cmdargs ...interfa
20012001
defer cleanup()
20022002
cmd.Dir = dir
20032003
cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir)
2004+
2005+
// Add the TOOLEXEC_IMPORTPATH environment variable for -toolexec tools.
2006+
// It doesn't really matter if -toolexec isn't being used.
2007+
if a != nil && a.Package != nil {
2008+
cmd.Env = append(cmd.Env, "TOOLEXEC_IMPORTPATH="+a.Package.ImportPath)
2009+
}
2010+
20042011
cmd.Env = append(cmd.Env, env...)
20052012
start := time.Now()
20062013
err := cmd.Run()
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
[short] skip
2+
3+
# Build our simple toolexec program.
4+
go build ./cmd/mytool
5+
6+
# Build the main package with our toolexec program. For each action, it will
7+
# print the tool's name and the TOOLEXEC_IMPORTPATH value. We expect to compile
8+
# each package once, and link the main package once.
9+
# Don't check the entire output at once, because the order in which the tools
10+
# are run is irrelevant here.
11+
# Finally, note that asm and cgo are run twice.
12+
13+
go build -toolexec=$PWD/mytool
14+
stderr -count=2 '^asm'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withasm$'
15+
stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withasm$'
16+
[cgo] stderr -count=2 '^cgo'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withcgo$'
17+
[cgo] stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main/withcgo$'
18+
stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main$'
19+
stderr -count=1 '^link'${GOEXE}' TOOLEXEC_IMPORTPATH=test/main$'
20+
21+
-- go.mod --
22+
module test/main
23+
-- foo.go --
24+
// Simple package so we can test a program build with -toolexec.
25+
// With a dummy import, to test different TOOLEXEC_IMPORTPATH values.
26+
// Includes dummy uses of cgo and asm, to cover those tools as well.
27+
package main
28+
29+
import (
30+
_ "test/main/withasm"
31+
_ "test/main/withcgo"
32+
)
33+
34+
func main() {}
35+
-- withcgo/withcgo.go --
36+
package withcgo
37+
38+
// int fortytwo()
39+
// {
40+
// return 42;
41+
// }
42+
import "C"
43+
-- withcgo/stub.go --
44+
package withcgo
45+
46+
// Stub file to ensure we build without cgo too.
47+
-- withasm/withasm.go --
48+
package withasm
49+
-- withasm/withasm.s --
50+
TEXT ·Add(SB),$0-24
51+
MOVQ a+0(FP), AX
52+
ADDQ b+8(FP), AX
53+
MOVQ AX, ret+16(FP)
54+
RET
55+
-- cmd/mytool/main.go --
56+
package main
57+
58+
import (
59+
"fmt"
60+
"os"
61+
"os/exec"
62+
"path/filepath"
63+
)
64+
65+
func main() {
66+
tool, args := os.Args[1], os.Args[2:]
67+
toolName := filepath.Base(tool)
68+
if len(args) > 0 && args[0] == "-V=full" {
69+
// We can't alter the version output.
70+
} else {
71+
// Print which tool we're running, and on what package.
72+
fmt.Fprintf(os.Stdout, "%s TOOLEXEC_IMPORTPATH=%s\n", toolName, os.Getenv("TOOLEXEC_IMPORTPATH"))
73+
}
74+
75+
// Simply run the tool.
76+
cmd := exec.Command(tool, args...)
77+
cmd.Stdout = os.Stdout
78+
cmd.Stderr = os.Stderr
79+
if err := cmd.Run(); err != nil {
80+
fmt.Fprintln(os.Stderr, err)
81+
os.Exit(1)
82+
}
83+
}

0 commit comments

Comments
 (0)