1 From 47db69e20ed66fb62b01affd83d829654b829893 Mon Sep 17 00:00:00 2001
2 From: Matt Madison <matt@madison.systems>
3 Date: Mon, 19 Feb 2018 08:50:59 -0800
4 Subject: [PATCH] cmd/go: make content-based hash generation less pedantic
6 Go 1.10's build tool now uses content-based hashes to
7 determine when something should be built or re-built.
8 This same mechanism is used to maintain a built-artifact
9 cache for speeding up builds.
11 However, the hashes it generates include information that
12 doesn't work well with OE, nor with using a shared runtime
15 First, it embeds path names to source files, unless
16 building within GOROOT. This prevents the building
17 of a package in GOPATH for later staging into GOROOT.
19 This patch adds support for the environment variable
20 GOPATH_OMIT_IN_ACTIONID. If present, path name
21 embedding is disabled.
23 Second, if cgo is enabled, the build ID for cgo-related
24 packages will include the current value of the environment
25 variables for invoking the compiler (CC, CXX, FC) and
26 any CGO_xxFLAGS variables. Only if the settings used
27 during a compilation exactly match, character for character,
28 the values used for compiling runtime/cgo or any other
29 cgo-enabled package being imported, will the tool
30 decide that the imported package is up-to-date.
32 This is done to help ensure correctness, but is overly
33 simplistic and effectively prevents the reuse of built
34 artifacts that use cgo (or shared runtime, which includes
37 This patch filters out all compiler flags except those
38 beginning with '-m'. The default behavior can be restored
39 by setting the CGO_PEDANTIC environment variable.
41 Upstream-Status: Inappropriate [OE specific]
43 Signed-off-by: Matt Madison <matt@madison.systems>
46 src/cmd/go/internal/envcmd/env.go | 2 +-
47 src/cmd/go/internal/work/exec.go | 63 ++++++++++++++++++++++---------
48 2 files changed, 46 insertions(+), 19 deletions(-)
50 diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go
51 index cedbfbf..5763a0d 100644
52 --- a/src/cmd/go/internal/envcmd/env.go
53 +++ b/src/cmd/go/internal/envcmd/env.go
54 @@ -128,7 +128,7 @@ func ExtraEnvVars() []cfg.EnvVar {
55 func ExtraEnvVarsCostly() []cfg.EnvVar {
58 - cppflags, cflags, cxxflags, fflags, ldflags, err := b.CFlags(&load.Package{})
59 + cppflags, cflags, cxxflags, fflags, ldflags, err := b.CFlags(&load.Package{}, false)
61 // Should not happen - b.CFlags was given an empty package.
62 fmt.Fprintf(os.Stderr, "go: invalid cflags: %v\n", err)
63 diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
64 index 12e1527..e41bfac 100644
65 --- a/src/cmd/go/internal/work/exec.go
66 +++ b/src/cmd/go/internal/work/exec.go
67 @@ -174,6 +174,8 @@ func (b *Builder) Do(root *Action) {
71 +var omitGopath = os.Getenv("GOPATH_OMIT_IN_ACTIONID") != ""
73 // buildActionID computes the action ID for a build action.
74 func (b *Builder) buildActionID(a *Action) cache.ActionID {
76 @@ -190,7 +192,7 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID {
77 // but it does not hide the exact value of $GOPATH.
78 // Include the full dir in that case.
79 // Assume b.WorkDir is being trimmed properly.
80 - if !p.Goroot && !strings.HasPrefix(p.Dir, b.WorkDir) {
81 + if !p.Goroot && !omitGopath && !strings.HasPrefix(p.Dir, b.WorkDir) {
82 fmt.Fprintf(h, "dir %s\n", p.Dir)
84 fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch)
85 @@ -201,13 +203,13 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID {
87 if len(p.CgoFiles)+len(p.SwigFiles) > 0 {
88 fmt.Fprintf(h, "cgo %q\n", b.toolID("cgo"))
89 - cppflags, cflags, cxxflags, fflags, ldflags, _ := b.CFlags(p)
90 - fmt.Fprintf(h, "CC=%q %q %q %q\n", b.ccExe(), cppflags, cflags, ldflags)
91 + cppflags, cflags, cxxflags, fflags, ldflags, _ := b.CFlags(p, true)
92 + fmt.Fprintf(h, "CC=%q %q %q %q\n", b.ccExe(true), cppflags, cflags, ldflags)
93 if len(p.CXXFiles)+len(p.SwigFiles) > 0 {
94 - fmt.Fprintf(h, "CXX=%q %q\n", b.cxxExe(), cxxflags)
95 + fmt.Fprintf(h, "CXX=%q %q\n", b.cxxExe(true), cxxflags)
97 if len(p.FFiles) > 0 {
98 - fmt.Fprintf(h, "FC=%q %q\n", b.fcExe(), fflags)
99 + fmt.Fprintf(h, "FC=%q %q\n", b.fcExe(true), fflags)
101 // TODO(rsc): Should we include the SWIG version or Fortran/GCC/G++/Objective-C compiler versions?
103 @@ -2096,33 +2098,33 @@ var (
104 // gccCmd returns a gcc command line prefix
105 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
106 func (b *Builder) GccCmd(incdir, workdir string) []string {
107 - return b.compilerCmd(b.ccExe(), incdir, workdir)
108 + return b.compilerCmd(b.ccExe(false), incdir, workdir)
111 // gxxCmd returns a g++ command line prefix
112 // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
113 func (b *Builder) GxxCmd(incdir, workdir string) []string {
114 - return b.compilerCmd(b.cxxExe(), incdir, workdir)
115 + return b.compilerCmd(b.cxxExe(false), incdir, workdir)
118 // gfortranCmd returns a gfortran command line prefix.
119 func (b *Builder) gfortranCmd(incdir, workdir string) []string {
120 - return b.compilerCmd(b.fcExe(), incdir, workdir)
121 + return b.compilerCmd(b.fcExe(false), incdir, workdir)
124 // ccExe returns the CC compiler setting without all the extra flags we add implicitly.
125 -func (b *Builder) ccExe() []string {
126 - return b.compilerExe(origCC, cfg.DefaultCC(cfg.Goos, cfg.Goarch))
127 +func (b *Builder) ccExe(filtered bool) []string {
128 + return b.compilerExe(origCC, cfg.DefaultCC(cfg.Goos, cfg.Goarch), filtered)
131 // cxxExe returns the CXX compiler setting without all the extra flags we add implicitly.
132 -func (b *Builder) cxxExe() []string {
133 - return b.compilerExe(origCXX, cfg.DefaultCXX(cfg.Goos, cfg.Goarch))
134 +func (b *Builder) cxxExe(filtered bool) []string {
135 + return b.compilerExe(origCXX, cfg.DefaultCXX(cfg.Goos, cfg.Goarch), filtered)
138 // fcExe returns the FC compiler setting without all the extra flags we add implicitly.
139 -func (b *Builder) fcExe() []string {
140 - return b.compilerExe(os.Getenv("FC"), "gfortran")
141 +func (b *Builder) fcExe(filtered bool) []string {
142 + return b.compilerExe(os.Getenv("FC"), "gfortran", filtered)
145 // compilerExe returns the compiler to use given an
146 @@ -2131,11 +2133,14 @@ func (b *Builder) fcExe() []string {
147 // of the compiler but can have additional arguments if they
148 // were present in the environment value.
149 // For example if CC="gcc -DGOPHER" then the result is ["gcc", "-DGOPHER"].
150 -func (b *Builder) compilerExe(envValue string, def string) []string {
151 +func (b *Builder) compilerExe(envValue string, def string, filtered bool) []string {
152 compiler := strings.Fields(envValue)
153 if len(compiler) == 0 {
154 compiler = []string{def}
157 + return append(compiler[0:1], filterCompilerFlags(compiler[1:])...)
162 @@ -2285,8 +2290,23 @@ func envList(key, def string) []string {
163 return strings.Fields(v)
166 +var filterFlags = os.Getenv("CGO_PEDANTIC") == ""
168 +func filterCompilerFlags(flags []string) []string {
169 + var newflags []string
173 + for _, flag := range flags {
174 + if strings.HasPrefix(flag, "-m") {
175 + newflags = append(newflags, flag)
181 // CFlags returns the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
182 -func (b *Builder) CFlags(p *load.Package) (cppflags, cflags, cxxflags, fflags, ldflags []string, err error) {
183 +func (b *Builder) CFlags(p *load.Package, filtered bool) (cppflags, cflags, cxxflags, fflags, ldflags []string, err error) {
186 if cppflags, err = buildFlags("CPPFLAGS", "", p.CgoCPPFLAGS, checkCompilerFlags); err != nil {
187 @@ -2304,6 +2324,13 @@ func (b *Builder) CFlags(p *load.Package) (cppflags, cflags, cxxflags, fflags, l
188 if ldflags, err = buildFlags("LDFLAGS", defaults, p.CgoLDFLAGS, checkLinkerFlags); err != nil {
192 + cppflags = filterCompilerFlags(cppflags)
193 + cflags = filterCompilerFlags(cflags)
194 + cxxflags = filterCompilerFlags(cxxflags)
195 + fflags = filterCompilerFlags(fflags)
196 + ldflags = filterCompilerFlags(ldflags)
201 @@ -2319,7 +2346,7 @@ var cgoRe = regexp.MustCompile(`[/\\:]`)
203 func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) {
205 - cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS, err := b.CFlags(p)
206 + cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS, err := b.CFlags(p, false)
210 @@ -2679,7 +2706,7 @@ func (b *Builder) swigIntSize(objdir string) (intsize string, err error) {
212 // Run SWIG on one SWIG input file.
213 func (b *Builder) swigOne(a *Action, p *load.Package, file, objdir string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
214 - cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _, err := b.CFlags(p)
215 + cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _, err := b.CFlags(p, false)