github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/go/not-internal/work/init.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Build initialization (after flag parsing). 6 7 package work 8 9 import ( 10 "github.com/gagliardetto/golang-go/cmd/go/not-internal/base" 11 "github.com/gagliardetto/golang-go/cmd/go/not-internal/cfg" 12 "github.com/gagliardetto/golang-go/cmd/go/not-internal/load" 13 "github.com/gagliardetto/golang-go/cmd/internal/sys" 14 "flag" 15 "fmt" 16 "os" 17 "path/filepath" 18 "strings" 19 ) 20 21 func BuildInit() { 22 load.ModInit() 23 instrumentInit() 24 buildModeInit() 25 26 // Make sure -pkgdir is absolute, because we run commands 27 // in different directories. 28 if cfg.BuildPkgdir != "" && !filepath.IsAbs(cfg.BuildPkgdir) { 29 p, err := filepath.Abs(cfg.BuildPkgdir) 30 if err != nil { 31 fmt.Fprintf(os.Stderr, "go %s: evaluating -pkgdir: %v\n", flag.Args()[0], err) 32 base.SetExitStatus(2) 33 base.Exit() 34 } 35 cfg.BuildPkgdir = p 36 } 37 } 38 39 func instrumentInit() { 40 if !cfg.BuildRace && !cfg.BuildMSan { 41 return 42 } 43 if cfg.BuildRace && cfg.BuildMSan { 44 fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0]) 45 base.SetExitStatus(2) 46 base.Exit() 47 } 48 if cfg.BuildMSan && !sys.MSanSupported(cfg.Goos, cfg.Goarch) { 49 fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch) 50 base.SetExitStatus(2) 51 base.Exit() 52 } 53 if cfg.BuildRace { 54 if !sys.RaceDetectorSupported(cfg.Goos, cfg.Goarch) { 55 fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, linux/ppc64le, linux/arm64, freebsd/amd64, netbsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0]) 56 base.SetExitStatus(2) 57 base.Exit() 58 } 59 } 60 mode := "race" 61 if cfg.BuildMSan { 62 mode = "msan" 63 // MSAN does not support non-PIE binaries on ARM64. 64 // See issue #33712 for details. 65 if cfg.Goos == "linux" && cfg.Goarch == "arm64" && cfg.BuildBuildmode == "default" { 66 cfg.BuildBuildmode = "pie" 67 } 68 } 69 modeFlag := "-" + mode 70 71 if !cfg.BuildContext.CgoEnabled { 72 fmt.Fprintf(os.Stderr, "go %s: %s requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0], modeFlag) 73 base.SetExitStatus(2) 74 base.Exit() 75 } 76 forcedGcflags = append(forcedGcflags, modeFlag) 77 forcedLdflags = append(forcedLdflags, modeFlag) 78 79 if cfg.BuildContext.InstallSuffix != "" { 80 cfg.BuildContext.InstallSuffix += "_" 81 } 82 cfg.BuildContext.InstallSuffix += mode 83 cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, mode) 84 } 85 86 func buildModeInit() { 87 gccgo := cfg.BuildToolchainName == "gccgo" 88 var codegenArg string 89 90 // Configure the build mode first, then verify that it is supported. 91 // That way, if the flag is completely bogus we will prefer to error out with 92 // "-buildmode=%s not supported" instead of naming the specific platform. 93 94 switch cfg.BuildBuildmode { 95 case "archive": 96 pkgsFilter = pkgsNotMain 97 case "c-archive": 98 pkgsFilter = oneMainPkg 99 if gccgo { 100 codegenArg = "-fPIC" 101 } else { 102 switch cfg.Goos { 103 case "darwin": 104 switch cfg.Goarch { 105 case "arm", "arm64": 106 codegenArg = "-shared" 107 } 108 109 case "dragonfly", "freebsd", "illumos", "linux", "netbsd", "openbsd", "solaris": 110 // Use -shared so that the result is 111 // suitable for inclusion in a PIE or 112 // shared library. 113 codegenArg = "-shared" 114 } 115 } 116 cfg.ExeSuffix = ".a" 117 ldBuildmode = "c-archive" 118 case "c-shared": 119 pkgsFilter = oneMainPkg 120 if gccgo { 121 codegenArg = "-fPIC" 122 } else { 123 switch cfg.Goos { 124 case "linux", "android", "freebsd": 125 codegenArg = "-shared" 126 case "windows": 127 // Do not add usual .exe suffix to the .dll file. 128 cfg.ExeSuffix = "" 129 } 130 } 131 ldBuildmode = "c-shared" 132 case "default": 133 switch cfg.Goos { 134 case "android": 135 codegenArg = "-shared" 136 ldBuildmode = "pie" 137 case "darwin": 138 switch cfg.Goarch { 139 case "arm", "arm64": 140 codegenArg = "-shared" 141 } 142 fallthrough 143 default: 144 ldBuildmode = "exe" 145 } 146 if gccgo { 147 codegenArg = "" 148 } 149 case "exe": 150 pkgsFilter = pkgsMain 151 ldBuildmode = "exe" 152 // Set the pkgsFilter to oneMainPkg if the user passed a specific binary output 153 // and is using buildmode=exe for a better error message. 154 // See issue #20017. 155 if cfg.BuildO != "" { 156 pkgsFilter = oneMainPkg 157 } 158 case "pie": 159 if cfg.BuildRace { 160 base.Fatalf("-buildmode=pie not supported when -race is enabled") 161 } 162 if gccgo { 163 codegenArg = "-fPIE" 164 } else if cfg.Goos != "aix" { 165 codegenArg = "-shared" 166 } 167 ldBuildmode = "pie" 168 case "shared": 169 pkgsFilter = pkgsNotMain 170 if gccgo { 171 codegenArg = "-fPIC" 172 } else { 173 codegenArg = "-dynlink" 174 } 175 if cfg.BuildO != "" { 176 base.Fatalf("-buildmode=shared and -o not supported together") 177 } 178 ldBuildmode = "shared" 179 case "plugin": 180 pkgsFilter = oneMainPkg 181 if gccgo { 182 codegenArg = "-fPIC" 183 } else { 184 codegenArg = "-dynlink" 185 } 186 cfg.ExeSuffix = ".so" 187 ldBuildmode = "plugin" 188 default: 189 base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode) 190 } 191 192 if !sys.BuildModeSupported(cfg.BuildToolchainName, cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) { 193 base.Fatalf("-buildmode=%s not supported on %s/%s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) 194 } 195 196 if cfg.BuildLinkshared { 197 if !sys.BuildModeSupported(cfg.BuildToolchainName, "shared", cfg.Goos, cfg.Goarch) { 198 base.Fatalf("-linkshared not supported on %s/%s\n", cfg.Goos, cfg.Goarch) 199 } 200 if gccgo { 201 codegenArg = "-fPIC" 202 } else { 203 forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1") 204 codegenArg = "-dynlink" 205 forcedGcflags = append(forcedGcflags, "-linkshared") 206 // TODO(mwhudson): remove -w when that gets fixed in linker. 207 forcedLdflags = append(forcedLdflags, "-linkshared", "-w") 208 } 209 } 210 if codegenArg != "" { 211 if gccgo { 212 forcedGccgoflags = append([]string{codegenArg}, forcedGccgoflags...) 213 } else { 214 forcedAsmflags = append([]string{codegenArg}, forcedAsmflags...) 215 forcedGcflags = append([]string{codegenArg}, forcedGcflags...) 216 } 217 // Don't alter InstallSuffix when modifying default codegen args. 218 if cfg.BuildBuildmode != "default" || cfg.BuildLinkshared { 219 if cfg.BuildContext.InstallSuffix != "" { 220 cfg.BuildContext.InstallSuffix += "_" 221 } 222 cfg.BuildContext.InstallSuffix += codegenArg[1:] 223 } 224 } 225 226 switch cfg.BuildMod { 227 case "": 228 // ok 229 case "readonly", "vendor", "mod": 230 if !cfg.ModulesEnabled && !inGOFLAGS("-mod") { 231 base.Fatalf("build flag -mod=%s only valid when using modules", cfg.BuildMod) 232 } 233 default: 234 base.Fatalf("-mod=%s not supported (can be '', 'mod', 'readonly', or 'vendor')", cfg.BuildMod) 235 } 236 if !cfg.ModulesEnabled { 237 if cfg.ModCacheRW && !inGOFLAGS("-modcacherw") { 238 base.Fatalf("build flag -modcacherw only valid when using modules") 239 } 240 if cfg.ModFile != "" && !inGOFLAGS("-mod") { 241 base.Fatalf("build flag -modfile only valid when using modules") 242 } 243 } 244 } 245 246 func inGOFLAGS(flag string) bool { 247 for _, goflag := range base.GOFLAGS() { 248 name := goflag 249 if strings.HasPrefix(name, "--") { 250 name = name[1:] 251 } 252 if i := strings.Index(name, "="); i >= 0 { 253 name = name[:i] 254 } 255 if name == flag { 256 return true 257 } 258 } 259 return false 260 }