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"
27 if err := fsys.Init(base.Cwd); err != nil {
28 base.Fatalf("go: %v", err)
31 // Make sure -pkgdir is absolute, because we run commands
32 // in different directories.
33 if cfg.BuildPkgdir != "" && !filepath.IsAbs(cfg.BuildPkgdir) {
34 p, err := filepath.Abs(cfg.BuildPkgdir)
36 fmt.Fprintf(os.Stderr, "go %s: evaluating -pkgdir: %v\n", flag.Args()[0], err)
43 // Make sure CC and CXX are absolute paths
44 for _, key := range []string{"CC", "CXX"} {
45 if path := cfg.Getenv(key); !filepath.IsAbs(path) && path != "" && path != filepath.Base(path) {
46 base.Fatalf("go %s: %s environment variable is relative; must be absolute path: %s\n", flag.Args()[0], key, path)
50 // For each experiment that has been enabled in the toolchain, define a
51 // build tag with the same name but prefixed by "goexperiment." which can be
52 // used for compiling alternative files for the experiment. This allows
53 // changes for the experiment, like extra struct fields in the runtime,
54 // without affecting the base non-experiment code at all.
55 for _, expt := range buildcfg.EnabledExperiments() {
56 cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "goexperiment."+expt)
60 func instrumentInit() {
61 if !cfg.BuildRace && !cfg.BuildMSan {
64 if cfg.BuildRace && cfg.BuildMSan {
65 fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0])
69 if cfg.BuildMSan && !sys.MSanSupported(cfg.Goos, cfg.Goarch) {
70 fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
75 if !sys.RaceDetectorSupported(cfg.Goos, cfg.Goarch) {
76 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])
84 // MSAN does not support non-PIE binaries on ARM64.
85 // See issue #33712 for details.
86 if cfg.Goos == "linux" && cfg.Goarch == "arm64" && cfg.BuildBuildmode == "default" {
87 cfg.BuildBuildmode = "pie"
90 modeFlag := "-" + mode
92 if !cfg.BuildContext.CgoEnabled {
93 if runtime.GOOS != cfg.Goos || runtime.GOARCH != cfg.Goarch {
94 fmt.Fprintf(os.Stderr, "go %s: %s requires cgo\n", flag.Args()[0], modeFlag)
96 fmt.Fprintf(os.Stderr, "go %s: %s requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0], modeFlag)
102 forcedGcflags = append(forcedGcflags, modeFlag)
103 forcedLdflags = append(forcedLdflags, modeFlag)
105 if cfg.BuildContext.InstallSuffix != "" {
106 cfg.BuildContext.InstallSuffix += "_"
108 cfg.BuildContext.InstallSuffix += mode
109 cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, mode)
112 func buildModeInit() {
113 gccgo := cfg.BuildToolchainName == "gccgo"
114 var codegenArg string
116 // Configure the build mode first, then verify that it is supported.
117 // That way, if the flag is completely bogus we will prefer to error out with
118 // "-buildmode=%s not supported" instead of naming the specific platform.
120 switch cfg.BuildBuildmode {
122 pkgsFilter = pkgsNotMain
124 pkgsFilter = oneMainPkg
129 case "darwin", "ios":
132 codegenArg = "-shared"
135 case "dragonfly", "freebsd", "illumos", "linux", "netbsd", "openbsd", "solaris":
136 // Use -shared so that the result is
137 // suitable for inclusion in a PIE or
139 codegenArg = "-shared"
143 ldBuildmode = "c-archive"
145 pkgsFilter = oneMainPkg
150 case "linux", "android", "freebsd":
151 codegenArg = "-shared"
153 // Do not add usual .exe suffix to the .dll file.
157 ldBuildmode = "c-shared"
161 codegenArg = "-shared"
166 codegenArg = "-shared"
171 codegenArg = "-shared"
181 pkgsFilter = pkgsMain
183 // Set the pkgsFilter to oneMainPkg if the user passed a specific binary output
184 // and is using buildmode=exe for a better error message.
186 if cfg.BuildO != "" {
187 pkgsFilter = oneMainPkg
191 base.Fatalf("-buildmode=pie not supported when -race is enabled")
197 case "aix", "windows":
199 codegenArg = "-shared"
204 pkgsFilter = pkgsNotMain
208 codegenArg = "-dynlink"
210 if cfg.BuildO != "" {
211 base.Fatalf("-buildmode=shared and -o not supported together")
213 ldBuildmode = "shared"
215 pkgsFilter = oneMainPkg
219 codegenArg = "-dynlink"
221 cfg.ExeSuffix = ".so"
222 ldBuildmode = "plugin"
224 base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
227 if !sys.BuildModeSupported(cfg.BuildToolchainName, cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) {
228 base.Fatalf("-buildmode=%s not supported on %s/%s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch)
231 if cfg.BuildLinkshared {
232 if !sys.BuildModeSupported(cfg.BuildToolchainName, "shared", cfg.Goos, cfg.Goarch) {
233 base.Fatalf("-linkshared not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
238 forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1",
240 codegenArg = "-dynlink"
241 forcedGcflags = append(forcedGcflags, "-linkshared")
242 // TODO(mwhudson): remove -w when that gets fixed in linker.
243 forcedLdflags = append(forcedLdflags, "-linkshared", "-w")
246 if codegenArg != "" {
248 forcedGccgoflags = append([]string{codegenArg}, forcedGccgoflags...)
250 forcedAsmflags = append([]string{codegenArg}, forcedAsmflags...)
251 forcedGcflags = append([]string{codegenArg}, forcedGcflags...)
253 // Don't alter InstallSuffix when modifying default codegen args.
254 if cfg.BuildBuildmode != "default" || cfg.BuildLinkshared {
255 if cfg.BuildContext.InstallSuffix != "" {
256 cfg.BuildContext.InstallSuffix += "_"
258 cfg.BuildContext.InstallSuffix += codegenArg[1:]
262 switch cfg.BuildMod {
264 // Behavior will be determined automatically, as if no flag were passed.
265 case "readonly", "vendor", "mod":
266 if !cfg.ModulesEnabled && !base.InGOFLAGS("-mod") {
267 base.Fatalf("build flag -mod=%s only valid when using modules", cfg.BuildMod)
270 base.Fatalf("-mod=%s not supported (can be '', 'mod', 'readonly', or 'vendor')", cfg.BuildMod)
272 if !cfg.ModulesEnabled {
273 if cfg.ModCacheRW && !base.InGOFLAGS("-modcacherw") {
274 base.Fatalf("build flag -modcacherw only valid when using modules")
276 if cfg.ModFile != "" && !base.InGOFLAGS("-mod") {
277 base.Fatalf("build flag -modfile only valid when using modules")