mirror of
https://github.com/golang/go
synced 2024-11-08 11:56:16 -07:00
cmd/go: rewrite paths for overlaid files using -trimpath
Pass the trimpath flag to cmd/compile to use the correct file paths for files that are overlaid: that is, the "destination" path in the overlay's Replace mapping rather than the "source" path. Also fix paths to go source files provided to the gccgo compiler. For #39958 Change-Id: I3741aeb2272bd0d5aa32cb28133b61e58264fd39 Reviewed-on: https://go-review.googlesource.com/c/go/+/257198 Trust: Michael Matloob <matloob@golang.org> Trust: Bryan C. Mills <bcmills@google.com> Run-TryBot: Michael Matloob <matloob@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com> Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
parent
748c0d87e2
commit
21e441c461
@ -2214,6 +2214,8 @@ func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []s
|
||||
// when -trimpath is enabled.
|
||||
if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") {
|
||||
if cfg.BuildTrimpath {
|
||||
// TODO(#39958): handle overlays
|
||||
|
||||
// Keep in sync with Action.trimpath.
|
||||
// The trimmed paths are a little different, but we need to trim in the
|
||||
// same situations.
|
||||
|
@ -152,8 +152,6 @@ func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, s
|
||||
// so these paths can be handed directly to tools.
|
||||
// Deleted files won't show up in when scanning directories earlier,
|
||||
// so OverlayPath will never return "" (meaning a deleted file) here.
|
||||
// TODO(#39958): Handle -trimprefix and other cases where
|
||||
// tools depend on the names of the files that are passed in.
|
||||
// TODO(#39958): Handle cases where the package directory
|
||||
// doesn't exist on disk (this can happen when all the package's
|
||||
// files are in an overlay): the code expects the package directory
|
||||
@ -167,7 +165,7 @@ func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, s
|
||||
args = append(args, f)
|
||||
}
|
||||
|
||||
output, err = b.runOut(a, p.Dir, nil, args...)
|
||||
output, err = b.runOut(a, base.Cwd, nil, args...)
|
||||
return ofile, output, err
|
||||
}
|
||||
|
||||
@ -256,17 +254,28 @@ func (a *Action) trimpath() string {
|
||||
}
|
||||
rewrite := objdir + "=>"
|
||||
|
||||
// For "go build -trimpath", rewrite package source directory
|
||||
// to a file system-independent path (just the import path).
|
||||
rewriteDir := a.Package.Dir
|
||||
if cfg.BuildTrimpath {
|
||||
if m := a.Package.Module; m != nil && m.Version != "" {
|
||||
rewrite += ";" + a.Package.Dir + "=>" + m.Path + "@" + m.Version + strings.TrimPrefix(a.Package.ImportPath, m.Path)
|
||||
rewriteDir = m.Path + "@" + m.Version + strings.TrimPrefix(a.Package.ImportPath, m.Path)
|
||||
} else {
|
||||
rewrite += ";" + a.Package.Dir + "=>" + a.Package.ImportPath
|
||||
rewriteDir = a.Package.ImportPath
|
||||
}
|
||||
rewrite += ";" + a.Package.Dir + "=>" + rewriteDir
|
||||
}
|
||||
|
||||
// TODO(#39958): Add rewrite rules for overlaid files.
|
||||
// Add rewrites for overlays. The 'from' and 'to' paths in overlays don't need to have
|
||||
// same basename, so go from the overlay contents file path (passed to the compiler)
|
||||
// to the path the disk path would be rewritten to.
|
||||
if fsys.OverlayFile != "" {
|
||||
for _, filename := range a.Package.AllFiles() {
|
||||
overlayPath, ok := fsys.OverlayPath(filepath.Join(a.Package.Dir, filename))
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
rewrite += ";" + overlayPath + "=>" + filepath.Join(rewriteDir, filename)
|
||||
}
|
||||
}
|
||||
|
||||
return rewrite
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
|
||||
"cmd/go/internal/base"
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/fsys"
|
||||
"cmd/go/internal/load"
|
||||
"cmd/go/internal/str"
|
||||
"cmd/internal/pkgpath"
|
||||
@ -93,13 +94,37 @@ func (tools gccgoToolchain) gc(b *Builder, a *Action, archive string, importcfg
|
||||
args = append(args, "-I", root)
|
||||
}
|
||||
}
|
||||
if cfg.BuildTrimpath && b.gccSupportsFlag(args[:1], "-ffile-prefix-map=a=b") {
|
||||
args = append(args, "-ffile-prefix-map="+base.Cwd+"=.")
|
||||
args = append(args, "-ffile-prefix-map="+b.WorkDir+"=/tmp/go-build")
|
||||
|
||||
if b.gccSupportsFlag(args[:1], "-ffile-prefix-map=a=b") {
|
||||
if cfg.BuildTrimpath {
|
||||
args = append(args, "-ffile-prefix-map="+base.Cwd+"=.")
|
||||
args = append(args, "-ffile-prefix-map="+b.WorkDir+"=/tmp/go-build")
|
||||
}
|
||||
if fsys.OverlayFile != "" {
|
||||
for _, name := range gofiles {
|
||||
absPath := mkAbs(p.Dir, name)
|
||||
overlayPath, ok := fsys.OverlayPath(absPath)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
toPath := absPath
|
||||
// gccgo only applies the last matching rule, so also handle the case where
|
||||
// BuildTrimpath is true and the path is relative to base.Cwd.
|
||||
if cfg.BuildTrimpath && str.HasFilePathPrefix(toPath, base.Cwd) {
|
||||
toPath = "." + toPath[len(base.Cwd):]
|
||||
}
|
||||
args = append(args, "-ffile-prefix-map="+overlayPath+"="+toPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
args = append(args, a.Package.Internal.Gccgoflags...)
|
||||
for _, f := range gofiles {
|
||||
args = append(args, mkAbs(p.Dir, f))
|
||||
f := mkAbs(p.Dir, f)
|
||||
// Overlay files if necessary.
|
||||
// See comment on gctoolchain.gc about overlay TODOs
|
||||
f, _ = fsys.OverlayPath(f)
|
||||
args = append(args, f)
|
||||
}
|
||||
|
||||
output, err = b.runOut(a, p.Dir, nil, args)
|
||||
|
58
src/cmd/go/testdata/script/build_overlay.txt
vendored
58
src/cmd/go/testdata/script/build_overlay.txt
vendored
@ -9,36 +9,66 @@
|
||||
# file in an overlay and one file outside the overlay, which in turn imports m/dir,
|
||||
# which only has source files in the overlay.
|
||||
|
||||
cd m
|
||||
|
||||
! go build .
|
||||
go build -overlay overlay.json -o main$GOEXE .
|
||||
exec ./main$goexe
|
||||
stdout '^hello$'
|
||||
|
||||
-- go.mod --
|
||||
go build -overlay overlay.json -o print_abspath$GOEXE ./printpath
|
||||
exec ./print_abspath$GOEXE
|
||||
stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go
|
||||
|
||||
go build -overlay overlay.json -o print_trimpath$GOEXE -trimpath ./printpath
|
||||
exec ./print_trimpath$GOEXE
|
||||
stdout ^m[/\\]printpath[/\\]main.go
|
||||
|
||||
# Run same tests but with gccgo.
|
||||
env GO111MODULE=off
|
||||
[!exec:gccgo] stop
|
||||
|
||||
! go build -compiler=gccgo .
|
||||
go build -compiler=gccgo -overlay overlay.json -o main_gccgo$GOEXE .
|
||||
exec ./main_gccgo$goexe
|
||||
stdout '^hello$'
|
||||
|
||||
go build -compiler=gccgo -overlay overlay.json -o print_abspath_gccgo$GOEXE ./printpath
|
||||
exec ./print_abspath_gccgo$GOEXE
|
||||
stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go
|
||||
|
||||
go build -compiler=gccgo -overlay overlay.json -o print_trimpath_gccgo$GOEXE -trimpath ./printpath
|
||||
exec ./print_trimpath_gccgo$GOEXE
|
||||
stdout ^\.[/\\]printpath[/\\]main.go
|
||||
|
||||
-- m/go.mod --
|
||||
// TODO(matloob): how do overlays work with go.mod (especially if mod=readonly)
|
||||
module m
|
||||
|
||||
go 1.16
|
||||
|
||||
-- dir2/h.go --
|
||||
-- m/dir2/h.go --
|
||||
package dir2
|
||||
|
||||
func PrintMessage() {
|
||||
printMessage()
|
||||
}
|
||||
-- dir/foo.txt --
|
||||
-- m/dir/foo.txt --
|
||||
The build action code currently expects the package directory
|
||||
to exist, so it can run the compiler in that directory.
|
||||
TODO(matloob): Remove this requirement.
|
||||
-- overlay.json --
|
||||
-- m/printpath/about.txt --
|
||||
the actual code is in the overlay
|
||||
-- m/overlay.json --
|
||||
{
|
||||
"Replace": {
|
||||
"f.go": "overlay/f.go",
|
||||
"dir/g.go": "overlay/dir_g.go",
|
||||
"dir2/i.go": "overlay/dir2_i.go"
|
||||
"dir2/i.go": "overlay/dir2_i.go",
|
||||
"printpath/main.go": "overlay/printpath.go"
|
||||
}
|
||||
}
|
||||
-- overlay/f.go --
|
||||
-- m/overlay/f.go --
|
||||
package main
|
||||
|
||||
import "m/dir2"
|
||||
@ -46,7 +76,7 @@ import "m/dir2"
|
||||
func main() {
|
||||
dir2.PrintMessage()
|
||||
}
|
||||
-- overlay/dir_g.go --
|
||||
-- m/overlay/dir_g.go --
|
||||
package dir
|
||||
|
||||
import "fmt"
|
||||
@ -54,7 +84,19 @@ import "fmt"
|
||||
func PrintMessage() {
|
||||
fmt.Println("hello")
|
||||
}
|
||||
-- overlay/dir2_i.go --
|
||||
-- m/overlay/printpath.go --
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_, file, _, _ := runtime.Caller(0)
|
||||
fmt.Println(file)
|
||||
}
|
||||
-- m/overlay/dir2_i.go --
|
||||
package dir2
|
||||
|
||||
import "m/dir"
|
||||
|
28
src/cmd/go/testdata/script/build_trimpath.txt
vendored
28
src/cmd/go/testdata/script/build_trimpath.txt
vendored
@ -9,6 +9,8 @@ env GO111MODULE=on
|
||||
mkdir $WORK/a/src/paths $WORK/b/src/paths
|
||||
cp paths.go $WORK/a/src/paths
|
||||
cp paths.go $WORK/b/src/paths
|
||||
cp overlay.json $WORK/a/src/paths
|
||||
cp overlay.json $WORK/b/src/paths
|
||||
cp go.mod $WORK/a/src/paths/
|
||||
cp go.mod $WORK/b/src/paths/
|
||||
|
||||
@ -43,6 +45,29 @@ go build -trimpath -o $WORK/paths-b.exe
|
||||
cmp -q $WORK/paths-a.exe $WORK/paths-b.exe
|
||||
|
||||
|
||||
# Same sequence of tests but with overlays.
|
||||
# A binary built without -trimpath should contain the module root dir
|
||||
# and GOROOT for debugging and stack traces.
|
||||
cd $WORK/a/src/paths
|
||||
go build -overlay overlay.json -o $WORK/paths-dbg.exe ./overlaydir
|
||||
exec $WORK/paths-dbg.exe $WORK/paths-dbg.exe
|
||||
stdout 'binary contains module root: true'
|
||||
stdout 'binary contains GOROOT: true'
|
||||
|
||||
# A binary built with -trimpath should not contain the current workspace
|
||||
# or GOROOT.
|
||||
go build -overlay overlay.json -trimpath -o $WORK/paths-a.exe ./overlaydir
|
||||
exec $WORK/paths-a.exe $WORK/paths-a.exe
|
||||
stdout 'binary contains module root: false'
|
||||
stdout 'binary contains GOROOT: false'
|
||||
|
||||
# Two binaries built from identical packages in different directories
|
||||
# should be identical.
|
||||
cd $WORK/b/src/paths
|
||||
go build -overlay overlay.json -trimpath -o $WORK/paths-b.exe ./overlaydir
|
||||
cmp -q $WORK/paths-a.exe $WORK/paths-b.exe
|
||||
|
||||
|
||||
# Same sequence of tests but in GOPATH mode.
|
||||
# A binary built without -trimpath should contain GOPATH and GOROOT.
|
||||
env GO111MODULE=off
|
||||
@ -129,7 +154,8 @@ func check(data []byte, desc, dir string) {
|
||||
containsSlashDir := bytes.Contains(data, []byte(filepath.ToSlash(dir)))
|
||||
fmt.Printf("binary contains %s: %v\n", desc, containsDir || containsSlashDir)
|
||||
}
|
||||
|
||||
-- overlay.json --
|
||||
{ "Replace": { "overlaydir/paths.go": "paths.go" } }
|
||||
-- go.mod --
|
||||
module paths
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user