Skip to content

Commit 60b1253

Browse files
committed
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 <[email protected]> Run-TryBot: Michael Matloob <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Jay Conrod <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent 062e0e5 commit 60b1253

File tree

3 files changed

+51
-40
lines changed

3 files changed

+51
-40
lines changed

src/cmd/go/internal/work/action.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,12 @@ type Action struct {
9393
output []byte // output redirect buffer (nil means use b.Print)
9494

9595
// Execution state.
96-
pending int // number of deps yet to complete
97-
priority int // relative execution priority
98-
Failed bool // whether the action failed
99-
json *actionJSON // action graph information
100-
traceSpan *trace.Span
96+
pending int // number of deps yet to complete
97+
priority int // relative execution priority
98+
Failed bool // whether the action failed
99+
json *actionJSON // action graph information
100+
nonGoOverlay map[string]string // map from non-.go source files to copied files in objdir. Nil if no overlay is used.
101+
traceSpan *trace.Span
101102
}
102103

103104
// BuildActionID returns the action ID section of a's build ID.

src/cmd/go/internal/work/exec.go

+33-32
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,34 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) {
538538
}
539539
}
540540

541+
// Compute overlays for .c/.cc/.h/etc. and if there are any overlays
542+
// put correct contents of all those files in the objdir, to ensure
543+
// the correct headers are included. nonGoOverlay is the overlay that
544+
// points from nongo files to the copied files in objdir.
545+
nonGoFileLists := [][]string{a.Package.CFiles, a.Package.SFiles, a.Package.CXXFiles, a.Package.HFiles, a.Package.FFiles}
546+
OverlayLoop:
547+
for _, fs := range nonGoFileLists {
548+
for _, f := range fs {
549+
if _, ok := fsys.OverlayPath(mkAbs(p.Dir, f)); ok {
550+
a.nonGoOverlay = make(map[string]string)
551+
break OverlayLoop
552+
}
553+
}
554+
}
555+
if a.nonGoOverlay != nil {
556+
for _, fs := range nonGoFileLists {
557+
for i := range fs {
558+
from := mkAbs(p.Dir, fs[i])
559+
opath, _ := fsys.OverlayPath(from)
560+
dst := objdir + filepath.Base(fs[i])
561+
if err := b.copyFile(dst, opath, 0666, false); err != nil {
562+
return err
563+
}
564+
a.nonGoOverlay[from] = dst
565+
}
566+
}
567+
}
568+
541569
// Run SWIG on each .swig and .swigcxx file.
542570
// Each run will generate two files, a .go file and a .c or .cxx file.
543571
// 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
22692297
}
22702298
}
22712299

2272-
output, err := b.runOut(a, filepath.Dir(file), b.cCompilerEnv(), compiler, flags, "-o", outfile, "-c", filepath.Base(file))
2300+
overlayPath := file
2301+
if p, ok := a.nonGoOverlay[overlayPath]; ok {
2302+
overlayPath = p
2303+
}
2304+
output, err := b.runOut(a, filepath.Dir(overlayPath), b.cCompilerEnv(), compiler, flags, "-o", outfile, "-c", filepath.Base(overlayPath))
22732305
if len(output) > 0 {
22742306
// On FreeBSD 11, when we pass -g to clang 3.8 it
22752307
// invokes its internal assembler with -dwarf-version=2.
@@ -2655,8 +2687,6 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo
26552687
cfiles = append(cfiles, f+".cgo2.c")
26562688
}
26572689

2658-
hfiles := append([]string{}, p.HFiles...)
2659-
26602690
// TODO: make cgo not depend on $GOARCH?
26612691

26622692
cgoflags := []string{}
@@ -2703,35 +2733,6 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo
27032733

27042734
execdir := p.Dir
27052735

2706-
// If any of the Cgo, C, or H files are overlaid, copy them all to
2707-
// objdir to ensure that they refer to the right header files.
2708-
// TODO(#39958): Ideally, we'd always do this, but this could
2709-
// subtly break some cgo files that include .h files across directory
2710-
// boundaries, even though they shouldn't.
2711-
hasOverlay := false
2712-
cgoFileLists := [][]string{gccfiles, gxxfiles, mfiles, ffiles, hfiles}
2713-
OverlayLoop:
2714-
for _, fs := range cgoFileLists {
2715-
for _, f := range fs {
2716-
if _, ok := fsys.OverlayPath(mkAbs(p.Dir, f)); ok {
2717-
hasOverlay = true
2718-
break OverlayLoop
2719-
}
2720-
}
2721-
}
2722-
if hasOverlay {
2723-
execdir = objdir
2724-
for _, fs := range cgoFileLists {
2725-
for i := range fs {
2726-
opath, _ := fsys.OverlayPath(mkAbs(p.Dir, fs[i]))
2727-
fs[i] = objdir + filepath.Base(fs[i])
2728-
if err := b.copyFile(fs[i], opath, 0666, false); err != nil {
2729-
return nil, nil, err
2730-
}
2731-
}
2732-
}
2733-
}
2734-
27352736
// Rewrite overlaid paths in cgo files.
27362737
// cgo adds //line and #line pragmas in generated files with these paths.
27372738
var trimpath []string

src/cmd/go/testdata/script/build_overlay.txt

+12-3
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ the actual code is in the overlay
106106
"printpath/main.go": "overlay/printpath.go",
107107
"printpath/other.go": "overlay2/printpath2.go",
108108
"cgo_hello_replace/cgo_header.h": "overlay/cgo_head.h",
109+
"cgo_hello_replace/hello.c": "overlay/hello.c",
109110
"cgo_hello_quote/cgo_hello.go": "overlay/cgo_hello_quote.go",
110111
"cgo_hello_quote/cgo_header.h": "overlay/cgo_head.h",
111112
"cgo_hello_angle/cgo_hello.go": "overlay/cgo_hello_angle.go",
@@ -125,10 +126,10 @@ func main() {
125126
// Test that this header is replaced with one that has the proper declaration.
126127
void say_goodbye();
127128

128-
-- m/cgo_hello_replace/goodbye.c --
129+
-- m/cgo_hello_replace/hello.c --
129130
#include <stdio.h>
130131

131-
void say_hello() { puts("hello cgo\n"); fflush(stdout); }
132+
void say_goodbye() { puts("goodbye cgo\n"); fflush(stdout); }
132133

133134
-- m/overlay/f.go --
134135
package main
@@ -204,6 +205,14 @@ func main() {
204205
}
205206
-- m/overlay/cgo_head.h --
206207
void say_hello();
208+
-- m/overlay/hello.c --
209+
#include <stdio.h>
210+
211+
void say_hello() { puts("hello cgo\n"); fflush(stdout); }
212+
-- m/overlay/asm_file.s --
213+
TEXT ·foo(SB),0,$0
214+
RET
215+
207216
-- m/cgo_hello_quote/hello.c --
208217
#include <stdio.h>
209218

@@ -242,4 +251,4 @@ func main() {
242251
}
243252
}
244253
}
245-
}
254+
}

0 commit comments

Comments
 (0)