mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
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 <matloob@golang.org> 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
062e0e5ce6
commit
60b1253293
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
15
src/cmd/go/testdata/script/build_overlay.txt
vendored
15
src/cmd/go/testdata/script/build_overlay.txt
vendored
|
@ -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 <stdio.h>
|
||||
|
||||
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 <stdio.h>
|
||||
|
||||
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 <stdio.h>
|
||||
|
||||
|
@ -242,4 +251,4 @@ func main() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue