mirror of
https://github.com/golang/go
synced 2024-11-17 16:14:42 -07:00
cmd/go: add -trimpath build flag
"go build -trimpath" trims the recorded file paths in the resulting packages and executables to avoid recording the names of any local directories. Instead, the files appear to be stored in directories named either "go/src/..." (for the standard library) or named after the module or package in which the files appear. Fixes #16860. Change-Id: I433afeeb1fdeea641286b21693fee5e0a66d607e Reviewed-on: https://go-review.googlesource.com/c/go/+/173345 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com>
This commit is contained in:
parent
8a20fde697
commit
74695644e0
@ -155,6 +155,12 @@
|
||||
// a space-separated list of build tags to consider satisfied during the
|
||||
// build. For more information about build tags, see the description of
|
||||
// build constraints in the documentation for the go/build package.
|
||||
// -trimpath
|
||||
// remove all file system paths from the resulting executable.
|
||||
// Instead of absolute file system paths, the recorded file names
|
||||
// will begin with either "go" (for the standard library),
|
||||
// or a module path@version (when using modules),
|
||||
// or a plain import path (when using GOPATH).
|
||||
// -toolexec 'cmd args'
|
||||
// a program to use to invoke toolchain programs like vet and asm.
|
||||
// For example, instead of running asm, the go command will run
|
||||
|
@ -38,6 +38,7 @@ var (
|
||||
BuildToolchainName string
|
||||
BuildToolchainCompiler func() string
|
||||
BuildToolchainLinker func() string
|
||||
BuildTrimpath bool // -trimpath flag
|
||||
BuildV bool // -v flag
|
||||
BuildWork bool // -work flag
|
||||
BuildX bool // -x flag
|
||||
|
@ -108,6 +108,12 @@ and test commands:
|
||||
a space-separated list of build tags to consider satisfied during the
|
||||
build. For more information about build tags, see the description of
|
||||
build constraints in the documentation for the go/build package.
|
||||
-trimpath
|
||||
remove all file system paths from the resulting executable.
|
||||
Instead of absolute file system paths, the recorded file names
|
||||
will begin with either "go" (for the standard library),
|
||||
or a module path@version (when using modules),
|
||||
or a plain import path (when using GOPATH).
|
||||
-toolexec 'cmd args'
|
||||
a program to use to invoke toolchain programs like vet and asm.
|
||||
For example, instead of running asm, the go command will run
|
||||
@ -229,6 +235,7 @@ func AddBuildFlags(cmd *base.Command) {
|
||||
cmd.Flag.BoolVar(&cfg.BuildMSan, "msan", false, "")
|
||||
cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildContext.BuildTags), "tags", "")
|
||||
cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildToolexec), "toolexec", "")
|
||||
cmd.Flag.BoolVar(&cfg.BuildTrimpath, "trimpath", false, "")
|
||||
cmd.Flag.BoolVar(&cfg.BuildWork, "work", false, "")
|
||||
|
||||
// Undocumented, unstable debugging flags.
|
||||
|
@ -1930,7 +1930,8 @@ func joinUnambiguously(a []string) string {
|
||||
q := strconv.Quote(s)
|
||||
// A gccgo command line can contain -( and -).
|
||||
// Make sure we quote them since they are special to the shell.
|
||||
if s == "" || strings.ContainsAny(s, " ()") || len(q) > len(s)+2 {
|
||||
// The trimpath argument can also contain > (part of =>) and ;. Quote those too.
|
||||
if s == "" || strings.ContainsAny(s, " ()>;") || len(q) > len(s)+2 {
|
||||
buf.WriteString(q)
|
||||
} else {
|
||||
buf.WriteString(s)
|
||||
|
@ -117,7 +117,7 @@ func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, s
|
||||
}
|
||||
}
|
||||
|
||||
args := []interface{}{cfg.BuildToolexec, base.Tool("compile"), "-o", ofile, "-trimpath", trimDir(a.Objdir), gcflags, gcargs, "-D", p.Internal.LocalPrefix}
|
||||
args := []interface{}{cfg.BuildToolexec, base.Tool("compile"), "-o", ofile, "-trimpath", a.trimpath(), gcflags, gcargs, "-D", p.Internal.LocalPrefix}
|
||||
if importcfg != nil {
|
||||
if err := b.writeFile(objdir+"importcfg", importcfg); err != nil {
|
||||
return "", nil, err
|
||||
@ -215,17 +215,33 @@ CheckFlags:
|
||||
return c
|
||||
}
|
||||
|
||||
func trimDir(dir string) string {
|
||||
if len(dir) > 1 && dir[len(dir)-1] == filepath.Separator {
|
||||
dir = dir[:len(dir)-1]
|
||||
// trimpath returns the -trimpath argument to use
|
||||
// when compiling the action.
|
||||
func (a *Action) trimpath() string {
|
||||
// Strip the object directory entirely.
|
||||
objdir := a.Objdir
|
||||
if len(objdir) > 1 && objdir[len(objdir)-1] == filepath.Separator {
|
||||
objdir = objdir[:len(objdir)-1]
|
||||
}
|
||||
return dir
|
||||
rewrite := objdir + "=>"
|
||||
|
||||
// For "go build -trimpath", rewrite package source directory
|
||||
// to a file system-independent path (just the import path).
|
||||
if cfg.BuildTrimpath {
|
||||
if m := a.Package.Module; m != nil {
|
||||
rewrite += ";" + m.Dir + "=>" + m.Path + "@" + m.Version
|
||||
} else {
|
||||
rewrite += ";" + a.Package.Dir + "=>" + a.Package.ImportPath
|
||||
}
|
||||
}
|
||||
|
||||
return rewrite
|
||||
}
|
||||
|
||||
func asmArgs(a *Action, p *load.Package) []interface{} {
|
||||
// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
|
||||
inc := filepath.Join(cfg.GOROOT, "pkg", "include")
|
||||
args := []interface{}{cfg.BuildToolexec, base.Tool("asm"), "-trimpath", trimDir(a.Objdir), "-I", a.Objdir, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, forcedAsmflags, p.Internal.Asmflags}
|
||||
args := []interface{}{cfg.BuildToolexec, base.Tool("asm"), "-trimpath", a.trimpath(), "-I", a.Objdir, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, forcedAsmflags, p.Internal.Asmflags}
|
||||
if p.ImportPath == "runtime" && cfg.Goarch == "386" {
|
||||
for _, arg := range forcedAsmflags {
|
||||
if arg == "-dynlink" {
|
||||
@ -567,7 +583,11 @@ func (gcToolchain) ld(b *Builder, root *Action, out, importcfg, mainpkg string)
|
||||
dir, out = filepath.Split(out)
|
||||
}
|
||||
|
||||
return b.run(root, dir, root.Package.ImportPath, nil, cfg.BuildToolexec, base.Tool("link"), "-o", out, "-importcfg", importcfg, ldflags, mainpkg)
|
||||
env := []string{}
|
||||
if cfg.BuildTrimpath {
|
||||
env = append(env, "GOROOT_FINAL=go")
|
||||
}
|
||||
return b.run(root, dir, root.Package.ImportPath, env, cfg.BuildToolexec, base.Tool("link"), "-o", out, "-importcfg", importcfg, ldflags, mainpkg)
|
||||
}
|
||||
|
||||
func (gcToolchain) ldShared(b *Builder, root *Action, toplevelactions []*Action, out, importcfg string, allactions []*Action) error {
|
||||
|
@ -539,6 +539,13 @@ func (ts *testScript) cmdEnv(neg bool, args []string) {
|
||||
if neg {
|
||||
ts.fatalf("unsupported: ! env")
|
||||
}
|
||||
|
||||
conv := func(s string) string { return s }
|
||||
if len(args) > 0 && args[0] == "-r" {
|
||||
conv = regexp.QuoteMeta
|
||||
args = args[1:]
|
||||
}
|
||||
|
||||
if len(args) == 0 {
|
||||
printed := make(map[string]bool) // env list can have duplicates; only print effective value (from envMap) once
|
||||
for _, kv := range ts.env {
|
||||
@ -556,8 +563,9 @@ func (ts *testScript) cmdEnv(neg bool, args []string) {
|
||||
fmt.Fprintf(&ts.log, "%s=%s\n", env, ts.envMap[env])
|
||||
continue
|
||||
}
|
||||
ts.env = append(ts.env, env)
|
||||
ts.envMap[env[:i]] = env[i+1:]
|
||||
key, val := env[:i], conv(env[i+1:])
|
||||
ts.env = append(ts.env, key+"="+val)
|
||||
ts.envMap[key] = val
|
||||
}
|
||||
}
|
||||
|
||||
@ -743,6 +751,11 @@ func scriptMatch(ts *testScript, neg bool, args []string, text, name string) {
|
||||
}
|
||||
args = args[1:]
|
||||
}
|
||||
quiet := false
|
||||
if len(args) >= 1 && args[0] == "-q" {
|
||||
quiet = true
|
||||
args = args[1:]
|
||||
}
|
||||
|
||||
extraUsage := ""
|
||||
want := 1
|
||||
@ -773,14 +786,14 @@ func scriptMatch(ts *testScript, neg bool, args []string, text, name string) {
|
||||
|
||||
if neg {
|
||||
if re.MatchString(text) {
|
||||
if isGrep {
|
||||
if isGrep && !quiet {
|
||||
fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text)
|
||||
}
|
||||
ts.fatalf("unexpected match for %#q found in %s: %s", pattern, name, re.FindString(text))
|
||||
}
|
||||
} else {
|
||||
if !re.MatchString(text) {
|
||||
if isGrep {
|
||||
if isGrep && !quiet {
|
||||
fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text)
|
||||
}
|
||||
ts.fatalf("no match for %#q found in %s", pattern, name)
|
||||
@ -788,7 +801,7 @@ func scriptMatch(ts *testScript, neg bool, args []string, text, name string) {
|
||||
if n > 0 {
|
||||
count := len(re.FindAllString(text, -1))
|
||||
if count != n {
|
||||
if isGrep {
|
||||
if isGrep && !quiet {
|
||||
fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text)
|
||||
}
|
||||
ts.fatalf("have %d matches for %#q, want %d", count, pattern, n)
|
||||
|
7
src/cmd/go/testdata/script/README
vendored
7
src/cmd/go/testdata/script/README
vendored
@ -111,9 +111,11 @@ The commands are:
|
||||
src can include "stdout" or "stderr" to use the standard output or standard error
|
||||
from the most recent exec or go command.
|
||||
|
||||
- env [key=value...]
|
||||
- env [-r] [key=value...]
|
||||
With no arguments, print the environment (useful for debugging).
|
||||
Otherwise add the listed key=value pairs to the environment.
|
||||
The -r flag causes the values to be escaped using regexp.QuoteMeta
|
||||
before being recorded.
|
||||
|
||||
- [!] exec program [args...] [&]
|
||||
Run the given executable program with the arguments.
|
||||
@ -135,9 +137,10 @@ The commands are:
|
||||
Run the (test copy of the) go command with the given arguments.
|
||||
It must (or must not) succeed.
|
||||
|
||||
- [!] grep [-count=N] pattern file
|
||||
- [!] grep [-count=N] [-q] pattern file
|
||||
The file's content must (or must not) match the regular expression pattern.
|
||||
For positive matches, -count=N specifies an exact number of matches to require.
|
||||
The -q flag disables printing the file content on a mismatch.
|
||||
|
||||
- mkdir path...
|
||||
Create the listed directories, if they do not already exists.
|
||||
|
19
src/cmd/go/testdata/script/build_trimpath.txt
vendored
Normal file
19
src/cmd/go/testdata/script/build_trimpath.txt
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
env -r GOROOT_REGEXP=$GOROOT
|
||||
env -r WORK_REGEXP=$WORK
|
||||
env GOROOT GOROOT_REGEXP WORK WORK_REGEXP
|
||||
|
||||
go build -trimpath -o hello.exe hello.go
|
||||
! grep -q $GOROOT_REGEXP hello.exe
|
||||
! grep -q $WORK_REGEXP hello.exe
|
||||
|
||||
env GO111MODULE=on
|
||||
go build -trimpath -o fortune.exe rsc.io/fortune
|
||||
! grep -q $GOROOT_REGEXP fortune.exe
|
||||
! grep -q $WORK_REGEXP fortune.exe
|
||||
|
||||
-- hello.go --
|
||||
package main
|
||||
func main() { println("hello") }
|
||||
|
||||
-- go.mod --
|
||||
module m
|
Loading…
Reference in New Issue
Block a user