mirror of
https://github.com/golang/go
synced 2024-11-08 13:56:21 -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.
|
// when -trimpath is enabled.
|
||||||
if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") {
|
if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") {
|
||||||
if cfg.BuildTrimpath {
|
if cfg.BuildTrimpath {
|
||||||
|
// TODO(#39958): handle overlays
|
||||||
|
|
||||||
// Keep in sync with Action.trimpath.
|
// Keep in sync with Action.trimpath.
|
||||||
// The trimmed paths are a little different, but we need to trim in the
|
// The trimmed paths are a little different, but we need to trim in the
|
||||||
// same situations.
|
// 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.
|
// so these paths can be handed directly to tools.
|
||||||
// Deleted files won't show up in when scanning directories earlier,
|
// Deleted files won't show up in when scanning directories earlier,
|
||||||
// so OverlayPath will never return "" (meaning a deleted file) here.
|
// 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
|
// TODO(#39958): Handle cases where the package directory
|
||||||
// doesn't exist on disk (this can happen when all the package's
|
// doesn't exist on disk (this can happen when all the package's
|
||||||
// files are in an overlay): the code expects the package directory
|
// 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)
|
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
|
return ofile, output, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,17 +254,28 @@ func (a *Action) trimpath() string {
|
|||||||
}
|
}
|
||||||
rewrite := objdir + "=>"
|
rewrite := objdir + "=>"
|
||||||
|
|
||||||
// For "go build -trimpath", rewrite package source directory
|
rewriteDir := a.Package.Dir
|
||||||
// to a file system-independent path (just the import path).
|
|
||||||
if cfg.BuildTrimpath {
|
if cfg.BuildTrimpath {
|
||||||
if m := a.Package.Module; m != nil && m.Version != "" {
|
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 {
|
} 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
|
return rewrite
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
|
|
||||||
"cmd/go/internal/base"
|
"cmd/go/internal/base"
|
||||||
"cmd/go/internal/cfg"
|
"cmd/go/internal/cfg"
|
||||||
|
"cmd/go/internal/fsys"
|
||||||
"cmd/go/internal/load"
|
"cmd/go/internal/load"
|
||||||
"cmd/go/internal/str"
|
"cmd/go/internal/str"
|
||||||
"cmd/internal/pkgpath"
|
"cmd/internal/pkgpath"
|
||||||
@ -93,13 +94,37 @@ func (tools gccgoToolchain) gc(b *Builder, a *Action, archive string, importcfg
|
|||||||
args = append(args, "-I", root)
|
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+"=.")
|
if b.gccSupportsFlag(args[:1], "-ffile-prefix-map=a=b") {
|
||||||
args = append(args, "-ffile-prefix-map="+b.WorkDir+"=/tmp/go-build")
|
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...)
|
args = append(args, a.Package.Internal.Gccgoflags...)
|
||||||
for _, f := range gofiles {
|
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)
|
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,
|
# file in an overlay and one file outside the overlay, which in turn imports m/dir,
|
||||||
# which only has source files in the overlay.
|
# which only has source files in the overlay.
|
||||||
|
|
||||||
|
cd m
|
||||||
|
|
||||||
! go build .
|
! go build .
|
||||||
go build -overlay overlay.json -o main$GOEXE .
|
go build -overlay overlay.json -o main$GOEXE .
|
||||||
exec ./main$goexe
|
exec ./main$goexe
|
||||||
stdout '^hello$'
|
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)
|
// TODO(matloob): how do overlays work with go.mod (especially if mod=readonly)
|
||||||
module m
|
module m
|
||||||
|
|
||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
-- dir2/h.go --
|
-- m/dir2/h.go --
|
||||||
package dir2
|
package dir2
|
||||||
|
|
||||||
func PrintMessage() {
|
func PrintMessage() {
|
||||||
printMessage()
|
printMessage()
|
||||||
}
|
}
|
||||||
-- dir/foo.txt --
|
-- m/dir/foo.txt --
|
||||||
The build action code currently expects the package directory
|
The build action code currently expects the package directory
|
||||||
to exist, so it can run the compiler in that directory.
|
to exist, so it can run the compiler in that directory.
|
||||||
TODO(matloob): Remove this requirement.
|
TODO(matloob): Remove this requirement.
|
||||||
-- overlay.json --
|
-- m/printpath/about.txt --
|
||||||
|
the actual code is in the overlay
|
||||||
|
-- m/overlay.json --
|
||||||
{
|
{
|
||||||
"Replace": {
|
"Replace": {
|
||||||
"f.go": "overlay/f.go",
|
"f.go": "overlay/f.go",
|
||||||
"dir/g.go": "overlay/dir_g.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
|
package main
|
||||||
|
|
||||||
import "m/dir2"
|
import "m/dir2"
|
||||||
@ -46,7 +76,7 @@ import "m/dir2"
|
|||||||
func main() {
|
func main() {
|
||||||
dir2.PrintMessage()
|
dir2.PrintMessage()
|
||||||
}
|
}
|
||||||
-- overlay/dir_g.go --
|
-- m/overlay/dir_g.go --
|
||||||
package dir
|
package dir
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
@ -54,7 +84,19 @@ import "fmt"
|
|||||||
func PrintMessage() {
|
func PrintMessage() {
|
||||||
fmt.Println("hello")
|
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
|
package dir2
|
||||||
|
|
||||||
import "m/dir"
|
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
|
mkdir $WORK/a/src/paths $WORK/b/src/paths
|
||||||
cp paths.go $WORK/a/src/paths
|
cp paths.go $WORK/a/src/paths
|
||||||
cp paths.go $WORK/b/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/a/src/paths/
|
||||||
cp go.mod $WORK/b/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
|
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.
|
# Same sequence of tests but in GOPATH mode.
|
||||||
# A binary built without -trimpath should contain GOPATH and GOROOT.
|
# A binary built without -trimpath should contain GOPATH and GOROOT.
|
||||||
env GO111MODULE=off
|
env GO111MODULE=off
|
||||||
@ -129,7 +154,8 @@ func check(data []byte, desc, dir string) {
|
|||||||
containsSlashDir := bytes.Contains(data, []byte(filepath.ToSlash(dir)))
|
containsSlashDir := bytes.Contains(data, []byte(filepath.ToSlash(dir)))
|
||||||
fmt.Printf("binary contains %s: %v\n", desc, containsDir || containsSlashDir)
|
fmt.Printf("binary contains %s: %v\n", desc, containsDir || containsSlashDir)
|
||||||
}
|
}
|
||||||
|
-- overlay.json --
|
||||||
|
{ "Replace": { "overlaydir/paths.go": "paths.go" } }
|
||||||
-- go.mod --
|
-- go.mod --
|
||||||
module paths
|
module paths
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user