1From c403b45995c5daa6747ac4d95b39bc9a6feb2cda Mon Sep 17 00:00:00 2001 2From: Alex Kube <alexander.j.kube@gmail.com> 3Date: Wed, 23 Oct 2019 21:14:22 +0430 4Subject: [PATCH] cmd/go: make content-based hash generation less pedantic 5 6Upstream-Status: Inappropriate [OE specific] 7 8Go 1.10's build tool now uses content-based hashes to 9determine when something should be built or re-built. 10This same mechanism is used to maintain a built-artifact 11cache for speeding up builds. 12 13However, the hashes it generates include information that 14doesn't work well with OE, nor with using a shared runtime 15library. 16 17First, it embeds path names to source files, unless 18building within GOROOT. This prevents the building 19of a package in GOPATH for later staging into GOROOT. 20 21This patch adds support for the environment variable 22GOPATH_OMIT_IN_ACTIONID. If present, path name 23embedding is disabled. 24 25Second, if cgo is enabled, the build ID for cgo-related 26packages will include the current value of the environment 27variables for invoking the compiler (CC, CXX, FC) and 28any CGO_xxFLAGS variables. Only if the settings used 29during a compilation exactly match, character for character, 30the values used for compiling runtime/cgo or any other 31cgo-enabled package being imported, will the tool 32decide that the imported package is up-to-date. 33 34This is done to help ensure correctness, but is overly 35simplistic and effectively prevents the reuse of built 36artifacts that use cgo (or shared runtime, which includes 37runtime/cgo). 38 39This patch filters out all compiler flags except those 40beginning with '-m'. The default behavior can be restored 41by setting the CGO_PEDANTIC environment variable. 42 43Adapted to Go 1.13 from patches originally submitted to 44the meta/recipes-devtools/go tree by 45Matt Madison <matt@madison.systems>. 46 47Signed-off-by: Alexander J Kube <alexander.j.kube@gmail.com> 48--- 49 src/cmd/go/internal/envcmd/env.go | 2 +- 50 src/cmd/go/internal/work/exec.go | 66 ++++++++++++++++++++++--------- 51 2 files changed, 49 insertions(+), 19 deletions(-) 52 53diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go 54index 20d0587..ff6f0d8 100644 55--- a/src/cmd/go/internal/envcmd/env.go 56+++ b/src/cmd/go/internal/envcmd/env.go 57@@ -160,7 +160,7 @@ func ExtraEnvVars() []cfg.EnvVar { 58 func ExtraEnvVarsCostly() []cfg.EnvVar { 59 var b work.Builder 60 b.Init() 61- cppflags, cflags, cxxflags, fflags, ldflags, err := b.CFlags(&load.Package{}) 62+ cppflags, cflags, cxxflags, fflags, ldflags, err := b.CFlags(&load.Package{}, false) 63 if err != nil { 64 // Should not happen - b.CFlags was given an empty package. 65 fmt.Fprintf(os.Stderr, "go: invalid cflags: %v\n", err) 66diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go 67index 5a225fb..a37872e 100644 68--- a/src/cmd/go/internal/work/exec.go 69+++ b/src/cmd/go/internal/work/exec.go 70@@ -38,6 +38,8 @@ import ( 71 "cmd/go/internal/trace" 72 ) 73 74+var omitGopath = os.Getenv("GOPATH_OMIT_IN_ACTIONID") != "" 75+ 76 // actionList returns the list of actions in the dag rooted at root 77 // as visited in a depth-first post-order traversal. 78 func actionList(root *Action) []*Action { 79@@ -229,7 +231,7 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID { 80 // Assume b.WorkDir is being trimmed properly. 81 // When -trimpath is used with a package built from the module cache, 82 // use the module path and version instead of the directory. 83- if !p.Goroot && !cfg.BuildTrimpath && !strings.HasPrefix(p.Dir, b.WorkDir) { 84+ if !p.Goroot && !omitGopath && !cfg.BuildTrimpath && !strings.HasPrefix(p.Dir, b.WorkDir) { 85 fmt.Fprintf(h, "dir %s\n", p.Dir) 86 } else if cfg.BuildTrimpath && p.Module != nil { 87 fmt.Fprintf(h, "module %s@%s\n", p.Module.Path, p.Module.Version) 88@@ -248,9 +250,9 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID { 89 } 90 if len(p.CgoFiles)+len(p.SwigFiles)+len(p.SwigCXXFiles) > 0 { 91 fmt.Fprintf(h, "cgo %q\n", b.toolID("cgo")) 92- cppflags, cflags, cxxflags, fflags, ldflags, _ := b.CFlags(p) 93+ cppflags, cflags, cxxflags, fflags, ldflags, _ := b.CFlags(p, true) 94 95- ccExe := b.ccExe() 96+ ccExe := b.ccExe(true) 97 fmt.Fprintf(h, "CC=%q %q %q %q\n", ccExe, cppflags, cflags, ldflags) 98 // Include the C compiler tool ID so that if the C 99 // compiler changes we rebuild the package. 100@@ -263,14 +265,14 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID { 101 } 102 } 103 if len(p.CXXFiles)+len(p.SwigCXXFiles) > 0 { 104- cxxExe := b.cxxExe() 105+ cxxExe := b.cxxExe(true) 106 fmt.Fprintf(h, "CXX=%q %q\n", cxxExe, cxxflags) 107 if cxxID, err := b.gccToolID(cxxExe[0], "c++"); err == nil { 108 fmt.Fprintf(h, "CXX ID=%q\n", cxxID) 109 } 110 } 111 if len(p.FFiles) > 0 { 112- fcExe := b.fcExe() 113+ fcExe := b.fcExe(true) 114 fmt.Fprintf(h, "FC=%q %q\n", fcExe, fflags) 115 if fcID, err := b.gccToolID(fcExe[0], "f95"); err == nil { 116 fmt.Fprintf(h, "FC ID=%q\n", fcID) 117@@ -2438,33 +2440,48 @@ var ( 118 // gccCmd returns a gcc command line prefix 119 // defaultCC is defined in zdefaultcc.go, written by cmd/dist. 120 func (b *Builder) GccCmd(incdir, workdir string) []string { 121- return b.compilerCmd(b.ccExe(), incdir, workdir) 122+ return b.compilerCmd(b.ccExe(false), incdir, workdir) 123 } 124 125 // gxxCmd returns a g++ command line prefix 126 // defaultCXX is defined in zdefaultcc.go, written by cmd/dist. 127 func (b *Builder) GxxCmd(incdir, workdir string) []string { 128- return b.compilerCmd(b.cxxExe(), incdir, workdir) 129+ return b.compilerCmd(b.cxxExe(false), incdir, workdir) 130 } 131 132 // gfortranCmd returns a gfortran command line prefix. 133 func (b *Builder) gfortranCmd(incdir, workdir string) []string { 134- return b.compilerCmd(b.fcExe(), incdir, workdir) 135+ return b.compilerCmd(b.fcExe(false), incdir, workdir) 136 } 137 138 // ccExe returns the CC compiler setting without all the extra flags we add implicitly. 139-func (b *Builder) ccExe() []string { 140- return b.compilerExe(origCC, cfg.DefaultCC(cfg.Goos, cfg.Goarch)) 141+func (b *Builder) ccExe(filtered bool) []string { 142+ return b.compilerExe(origCC, cfg.DefaultCC(cfg.Goos, cfg.Goarch), filtered) 143 } 144 145 // cxxExe returns the CXX compiler setting without all the extra flags we add implicitly. 146-func (b *Builder) cxxExe() []string { 147- return b.compilerExe(origCXX, cfg.DefaultCXX(cfg.Goos, cfg.Goarch)) 148+func (b *Builder) cxxExe(filtered bool) []string { 149+ return b.compilerExe(origCXX, cfg.DefaultCXX(cfg.Goos, cfg.Goarch), filtered) 150 } 151 152 // fcExe returns the FC compiler setting without all the extra flags we add implicitly. 153-func (b *Builder) fcExe() []string { 154- return b.compilerExe(cfg.Getenv("FC"), "gfortran") 155+func (b *Builder) fcExe(filtered bool) []string { 156+ return b.compilerExe(os.Getenv("FC"), "gfortran", filtered) 157+} 158+ 159+var filterFlags = os.Getenv("CGO_PEDANTIC") == "" 160+ 161+func filterCompilerFlags(flags []string) []string { 162+ var newflags []string 163+ if !filterFlags { 164+ return flags 165+ } 166+ for _, flag := range flags { 167+ if strings.HasPrefix(flag, "-m") { 168+ newflags = append(newflags, flag) 169+ } 170+ } 171+ return newflags 172 } 173 174 // compilerExe returns the compiler to use given an 175@@ -2473,11 +2490,16 @@ func (b *Builder) fcExe() []string { 176 // of the compiler but can have additional arguments if they 177 // were present in the environment value. 178 // For example if CC="gcc -DGOPHER" then the result is ["gcc", "-DGOPHER"]. 179-func (b *Builder) compilerExe(envValue string, def string) []string { 180+func (b *Builder) compilerExe(envValue string, def string, filtered bool) []string { 181 compiler := strings.Fields(envValue) 182 if len(compiler) == 0 { 183 compiler = strings.Fields(def) 184 } 185+ 186+ if filtered { 187+ return append(compiler[0:1], filterCompilerFlags(compiler[1:])...) 188+ } 189+ 190 return compiler 191 } 192 193@@ -2667,7 +2689,7 @@ func envList(key, def string) []string { 194 } 195 196 // CFlags returns the flags to use when invoking the C, C++ or Fortran compilers, or cgo. 197-func (b *Builder) CFlags(p *load.Package) (cppflags, cflags, cxxflags, fflags, ldflags []string, err error) { 198+func (b *Builder) CFlags(p *load.Package, filtered bool) (cppflags, cflags, cxxflags, fflags, ldflags []string, err error) { 199 defaults := "-g -O2" 200 201 if cppflags, err = buildFlags("CPPFLAGS", "", p.CgoCPPFLAGS, checkCompilerFlags); err != nil { 202@@ -2686,6 +2708,14 @@ func (b *Builder) CFlags(p *load.Package) (cppflags, cflags, cxxflags, fflags, l 203 return 204 } 205 206+ if filtered { 207+ cppflags = filterCompilerFlags(cppflags) 208+ cflags = filterCompilerFlags(cflags) 209+ cxxflags = filterCompilerFlags(cxxflags) 210+ fflags = filterCompilerFlags(fflags) 211+ ldflags = filterCompilerFlags(ldflags) 212+ } 213+ 214 return 215 } 216 217@@ -2700,7 +2730,7 @@ var cgoRe = lazyregexp.New(`[/\\:]`) 218 219 func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) { 220 p := a.Package 221- cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS, err := b.CFlags(p) 222+ cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS, err := b.CFlags(p, false) 223 if err != nil { 224 return nil, nil, err 225 } 226@@ -3151,7 +3181,7 @@ func (b *Builder) swigIntSize(objdir string) (intsize string, err error) { 227 228 // Run SWIG on one SWIG input file. 229 func (b *Builder) swigOne(a *Action, p *load.Package, file, objdir string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) { 230- cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _, err := b.CFlags(p) 231+ cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _, err := b.CFlags(p, false) 232 if err != nil { 233 return "", "", err 234 } 235-- 2362.20.1 237 238