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.
5 // Build initialization (after flag parsing).
10 "cmd/go/internal/base"
12 "cmd/go/internal/fsys"
13 "cmd/go/internal/modload"
26 if err := fsys.Init(base.Cwd()); err != nil {
27 base.Fatalf("go: %v", err)
30 // Make sure -pkgdir is absolute, because we run commands
31 // in different directories.
32 if cfg.BuildPkgdir != "" && !filepath.IsAbs(cfg.BuildPkgdir) {
33 p, err := filepath.Abs(cfg.BuildPkgdir)
35 fmt.Fprintf(os.Stderr, "go %s: evaluating -pkgdir: %v\n", flag.Args()[0], err)
42 // Make sure CC and CXX are absolute paths
43 for _, key := range []string{"CC", "CXX"} {
44 if path := cfg.Getenv(key); !filepath.IsAbs(path) && path != "" && path != filepath.Base(path) {
45 base.Fatalf("go %s: %s environment variable is relative; must be absolute path: %s\n", flag.Args()[0], key, path)
50 func FuzzInstrumentFlags() []string {
51 if cfg.Goarch != "amd64" && cfg.Goarch != "arm64" {
52 // Instrumentation is only supported on 64-bit architectures.
55 return []string{"-d=libfuzzer"}
58 func instrumentInit() {
59 if !cfg.BuildRace && !cfg.BuildMSan {
62 if cfg.BuildRace && cfg.BuildMSan {
63 fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0])
67 if cfg.BuildMSan && !sys.MSanSupported(cfg.Goos, cfg.Goarch) {
68 fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
73 if !sys.RaceDetectorSupported(cfg.Goos, cfg.Goarch) {
74 fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, linux/ppc64le, linux/arm64, freebsd/amd64, netbsd/amd64, darwin/amd64, darwin/arm64, and windows/amd64\n", flag.Args()[0])
82 // MSAN does not support non-PIE binaries on ARM64.
83 // See issue #33712 for details.
84 if cfg.Goos == "linux" && cfg.Goarch == "arm64" && cfg.BuildBuildmode == "default" {
85 cfg.BuildBuildmode = "pie"
88 modeFlag := "-" + mode
90 if !cfg.BuildContext.CgoEnabled {
91 if runtime.GOOS != cfg.Goos || runtime.GOARCH != cfg.Goarch {
92 fmt.Fprintf(os.Stderr, "go %s: %s requires cgo\n", flag.Args()[0], modeFlag)
94 fmt.Fprintf(os.Stderr, "go %s: %s requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0], modeFlag)
100 forcedGcflags = append(forcedGcflags, modeFlag)
101 forcedLdflags = append(forcedLdflags, modeFlag)
103 if cfg.BuildContext.InstallSuffix != "" {
104 cfg.BuildContext.InstallSuffix += "_"
106 cfg.BuildContext.InstallSuffix += mode
107 cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, mode)
110 func buildModeInit() {
111 gccgo := cfg.BuildToolchainName == "gccgo"
112 var codegenArg string
114 // Configure the build mode first, then verify that it is supported.
115 // That way, if the flag is completely bogus we will prefer to error out with
116 // "-buildmode=%s not supported" instead of naming the specific platform.
118 switch cfg.BuildBuildmode {
120 pkgsFilter = pkgsNotMain
122 pkgsFilter = oneMainPkg
127 case "darwin", "ios":
130 codegenArg = "-shared"
133 case "dragonfly", "freebsd", "illumos", "linux", "netbsd", "openbsd", "solaris":
134 // Use -shared so that the result is
135 // suitable for inclusion in a PIE or
137 codegenArg = "-shared"
141 ldBuildmode = "c-archive"
143 pkgsFilter = oneMainPkg
148 case "linux", "android", "freebsd":
149 codegenArg = "-shared"
151 // Do not add usual .exe suffix to the .dll file.
155 ldBuildmode = "c-shared"
159 codegenArg = "-shared"
164 codegenArg = "-shared"
169 codegenArg = "-shared"
179 pkgsFilter = pkgsMain
181 // Set the pkgsFilter to oneMainPkg if the user passed a specific binary output
182 // and is using buildmode=exe for a better error message.
184 if cfg.BuildO != "" {
185 pkgsFilter = oneMainPkg
189 base.Fatalf("-buildmode=pie not supported when -race is enabled")
195 case "aix", "windows":
197 codegenArg = "-shared"
202 pkgsFilter = pkgsNotMain
206 codegenArg = "-dynlink"
208 if cfg.BuildO != "" {
209 base.Fatalf("-buildmode=shared and -o not supported together")
211 ldBuildmode = "shared"
213 pkgsFilter = oneMainPkg
217 codegenArg = "-dynlink"
219 cfg.ExeSuffix = ".so"
220 ldBuildmode = "plugin"
222 base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
225 if !sys.BuildModeSupported(cfg.BuildToolchainName, cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) {
226 base.Fatalf("-buildmode=%s not supported on %s/%s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch)
229 if cfg.BuildLinkshared {
230 if !sys.BuildModeSupported(cfg.BuildToolchainName, "shared", cfg.Goos, cfg.Goarch) {
231 base.Fatalf("-linkshared not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
236 forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1",
238 codegenArg = "-dynlink"
239 forcedGcflags = append(forcedGcflags, "-linkshared")
240 // TODO(mwhudson): remove -w when that gets fixed in linker.
241 forcedLdflags = append(forcedLdflags, "-linkshared", "-w")
244 if codegenArg != "" {
246 forcedGccgoflags = append([]string{codegenArg}, forcedGccgoflags...)
248 forcedAsmflags = append([]string{codegenArg}, forcedAsmflags...)
249 forcedGcflags = append([]string{codegenArg}, forcedGcflags...)
251 // Don't alter InstallSuffix when modifying default codegen args.
252 if cfg.BuildBuildmode != "default" || cfg.BuildLinkshared {
253 if cfg.BuildContext.InstallSuffix != "" {
254 cfg.BuildContext.InstallSuffix += "_"
256 cfg.BuildContext.InstallSuffix += codegenArg[1:]
260 switch cfg.BuildMod {
262 // Behavior will be determined automatically, as if no flag were passed.
263 case "readonly", "vendor", "mod":
264 if !cfg.ModulesEnabled && !base.InGOFLAGS("-mod") {
265 base.Fatalf("build flag -mod=%s only valid when using modules", cfg.BuildMod)
268 base.Fatalf("-mod=%s not supported (can be '', 'mod', 'readonly', or 'vendor')", cfg.BuildMod)
270 if !cfg.ModulesEnabled {
271 if cfg.ModCacheRW && !base.InGOFLAGS("-modcacherw") {
272 base.Fatalf("build flag -modcacherw only valid when using modules")
274 if cfg.ModFile != "" && !base.InGOFLAGS("-mod") {
275 base.Fatalf("build flag -modfile only valid when using modules")