From: Michael Matloob Date: Thu, 29 Oct 2020 23:05:56 +0000 (-0400) Subject: cmd/go: pass in overlaid file paths to C compiler X-Git-Tag: go1.16beta1~240 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=60b12532932fe40a8d756619474a00f820faacc8;p=gostls13.git cmd/go: pass in overlaid file paths to C compiler This change moves the code in work.(*Builder).cgo that, when there is an overlay, copies non-Go files to objdir into work.(*Builder).Build, and creates an overlay structure mapping from the nominal file paths into the copies in objdir. That's propagated through to work.(*Builder).ccompile, which will use it to pass in the path to the overlaid contents in objdir when calling the compiler. This allows for overlays of C/C++/Fortran files. For #39958 Change-Id: I9a2e3d3ba6afdf7ce19be1dbf4eee34805cdc05f Reviewed-on: https://go-review.googlesource.com/c/go/+/266376 Trust: Michael Matloob Run-TryBot: Michael Matloob TryBot-Result: Go Bot Reviewed-by: Jay Conrod Reviewed-by: Bryan C. Mills --- diff --git a/src/cmd/go/internal/work/action.go b/src/cmd/go/internal/work/action.go index 825e763c03..f461c5780f 100644 --- a/src/cmd/go/internal/work/action.go +++ b/src/cmd/go/internal/work/action.go @@ -93,11 +93,12 @@ type Action struct { output []byte // output redirect buffer (nil means use b.Print) // Execution state. - pending int // number of deps yet to complete - priority int // relative execution priority - Failed bool // whether the action failed - json *actionJSON // action graph information - traceSpan *trace.Span + pending int // number of deps yet to complete + priority int // relative execution priority + Failed bool // whether the action failed + json *actionJSON // action graph information + nonGoOverlay map[string]string // map from non-.go source files to copied files in objdir. Nil if no overlay is used. + traceSpan *trace.Span } // BuildActionID returns the action ID section of a's build ID. diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index eb76ad4e27..2c40a4bf00 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -538,6 +538,34 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) { } } + // Compute overlays for .c/.cc/.h/etc. and if there are any overlays + // put correct contents of all those files in the objdir, to ensure + // the correct headers are included. nonGoOverlay is the overlay that + // points from nongo files to the copied files in objdir. + nonGoFileLists := [][]string{a.Package.CFiles, a.Package.SFiles, a.Package.CXXFiles, a.Package.HFiles, a.Package.FFiles} +OverlayLoop: + for _, fs := range nonGoFileLists { + for _, f := range fs { + if _, ok := fsys.OverlayPath(mkAbs(p.Dir, f)); ok { + a.nonGoOverlay = make(map[string]string) + break OverlayLoop + } + } + } + if a.nonGoOverlay != nil { + for _, fs := range nonGoFileLists { + for i := range fs { + from := mkAbs(p.Dir, fs[i]) + opath, _ := fsys.OverlayPath(from) + dst := objdir + filepath.Base(fs[i]) + if err := b.copyFile(dst, opath, 0666, false); err != nil { + return err + } + a.nonGoOverlay[from] = dst + } + } + } + // Run SWIG on each .swig and .swigcxx file. // Each run will generate two files, a .go file and a .c or .cxx file. // The .go file will use import "C" and is to be processed by cgo. @@ -2269,7 +2297,11 @@ func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []s } } - output, err := b.runOut(a, filepath.Dir(file), b.cCompilerEnv(), compiler, flags, "-o", outfile, "-c", filepath.Base(file)) + overlayPath := file + if p, ok := a.nonGoOverlay[overlayPath]; ok { + overlayPath = p + } + output, err := b.runOut(a, filepath.Dir(overlayPath), b.cCompilerEnv(), compiler, flags, "-o", outfile, "-c", filepath.Base(overlayPath)) if len(output) > 0 { // On FreeBSD 11, when we pass -g to clang 3.8 it // invokes its internal assembler with -dwarf-version=2. @@ -2655,8 +2687,6 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo cfiles = append(cfiles, f+".cgo2.c") } - hfiles := append([]string{}, p.HFiles...) - // TODO: make cgo not depend on $GOARCH? cgoflags := []string{} @@ -2703,35 +2733,6 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo execdir := p.Dir - // If any of the Cgo, C, or H files are overlaid, copy them all to - // objdir to ensure that they refer to the right header files. - // TODO(#39958): Ideally, we'd always do this, but this could - // subtly break some cgo files that include .h files across directory - // boundaries, even though they shouldn't. - hasOverlay := false - cgoFileLists := [][]string{gccfiles, gxxfiles, mfiles, ffiles, hfiles} -OverlayLoop: - for _, fs := range cgoFileLists { - for _, f := range fs { - if _, ok := fsys.OverlayPath(mkAbs(p.Dir, f)); ok { - hasOverlay = true - break OverlayLoop - } - } - } - if hasOverlay { - execdir = objdir - for _, fs := range cgoFileLists { - for i := range fs { - opath, _ := fsys.OverlayPath(mkAbs(p.Dir, fs[i])) - fs[i] = objdir + filepath.Base(fs[i]) - if err := b.copyFile(fs[i], opath, 0666, false); err != nil { - return nil, nil, err - } - } - } - } - // Rewrite overlaid paths in cgo files. // cgo adds //line and #line pragmas in generated files with these paths. var trimpath []string diff --git a/src/cmd/go/testdata/script/build_overlay.txt b/src/cmd/go/testdata/script/build_overlay.txt index f9487da9f1..58c0de9a55 100644 --- a/src/cmd/go/testdata/script/build_overlay.txt +++ b/src/cmd/go/testdata/script/build_overlay.txt @@ -106,6 +106,7 @@ the actual code is in the overlay "printpath/main.go": "overlay/printpath.go", "printpath/other.go": "overlay2/printpath2.go", "cgo_hello_replace/cgo_header.h": "overlay/cgo_head.h", + "cgo_hello_replace/hello.c": "overlay/hello.c", "cgo_hello_quote/cgo_hello.go": "overlay/cgo_hello_quote.go", "cgo_hello_quote/cgo_header.h": "overlay/cgo_head.h", "cgo_hello_angle/cgo_hello.go": "overlay/cgo_hello_angle.go", @@ -125,10 +126,10 @@ func main() { // Test that this header is replaced with one that has the proper declaration. void say_goodbye(); --- m/cgo_hello_replace/goodbye.c -- +-- m/cgo_hello_replace/hello.c -- #include -void say_hello() { puts("hello cgo\n"); fflush(stdout); } +void say_goodbye() { puts("goodbye cgo\n"); fflush(stdout); } -- m/overlay/f.go -- package main @@ -204,6 +205,14 @@ func main() { } -- m/overlay/cgo_head.h -- void say_hello(); +-- m/overlay/hello.c -- +#include + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } +-- m/overlay/asm_file.s -- +TEXT ·foo(SB),0,$0 + RET + -- m/cgo_hello_quote/hello.c -- #include @@ -242,4 +251,4 @@ func main() { } } } -} \ No newline at end of file +}