1
2
3
4
5
6
7 package work
8
9 import (
10 "cmd/go/internal/base"
11 "cmd/go/internal/cfg"
12 "cmd/go/internal/fsys"
13 "cmd/go/internal/modload"
14 "cmd/internal/quoted"
15 "cmd/internal/sys"
16 "fmt"
17 "os"
18 "path/filepath"
19 "runtime"
20 )
21
22 func BuildInit() {
23 modload.Init()
24 instrumentInit()
25 buildModeInit()
26 if err := fsys.Init(base.Cwd()); err != nil {
27 base.Fatalf("go: %v", err)
28 }
29
30
31
32 if cfg.BuildPkgdir != "" && !filepath.IsAbs(cfg.BuildPkgdir) {
33 p, err := filepath.Abs(cfg.BuildPkgdir)
34 if err != nil {
35 fmt.Fprintf(os.Stderr, "go: evaluating -pkgdir: %v\n", err)
36 base.SetExitStatus(2)
37 base.Exit()
38 }
39 cfg.BuildPkgdir = p
40 }
41
42 if cfg.BuildP <= 0 {
43 base.Fatalf("go: -p must be a positive integer: %v\n", cfg.BuildP)
44 }
45
46
47 for _, key := range []string{"CC", "CXX", "FC"} {
48 value := cfg.Getenv(key)
49 args, err := quoted.Split(value)
50 if err != nil {
51 base.Fatalf("go: %s environment variable could not be parsed: %v", key, err)
52 }
53 if len(args) == 0 {
54 continue
55 }
56 path := args[0]
57 if !filepath.IsAbs(path) && path != filepath.Base(path) {
58 base.Fatalf("go: %s environment variable is relative; must be absolute path: %s\n", key, path)
59 }
60 }
61 }
62
63
64
65
66
67
68
69 func fuzzInstrumentFlags() []string {
70 if !sys.FuzzInstrumented(cfg.Goos, cfg.Goarch) {
71 return nil
72 }
73 return []string{"-d=libfuzzer"}
74 }
75
76 func instrumentInit() {
77 if !cfg.BuildRace && !cfg.BuildMSan && !cfg.BuildASan {
78 return
79 }
80 if cfg.BuildRace && cfg.BuildMSan {
81 fmt.Fprintf(os.Stderr, "go: may not use -race and -msan simultaneously\n")
82 base.SetExitStatus(2)
83 base.Exit()
84 }
85 if cfg.BuildRace && cfg.BuildASan {
86 fmt.Fprintf(os.Stderr, "go: may not use -race and -asan simultaneously\n")
87 base.SetExitStatus(2)
88 base.Exit()
89 }
90 if cfg.BuildMSan && cfg.BuildASan {
91 fmt.Fprintf(os.Stderr, "go: may not use -msan and -asan simultaneously\n")
92 base.SetExitStatus(2)
93 base.Exit()
94 }
95 if cfg.BuildMSan && !sys.MSanSupported(cfg.Goos, cfg.Goarch) {
96 fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
97 base.SetExitStatus(2)
98 base.Exit()
99 }
100 if cfg.BuildRace && !sys.RaceDetectorSupported(cfg.Goos, cfg.Goarch) {
101 fmt.Fprintf(os.Stderr, "-race is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
102 base.SetExitStatus(2)
103 base.Exit()
104 }
105 if cfg.BuildASan && !sys.ASanSupported(cfg.Goos, cfg.Goarch) {
106 fmt.Fprintf(os.Stderr, "-asan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
107 base.SetExitStatus(2)
108 base.Exit()
109 }
110 mode := "race"
111 if cfg.BuildMSan {
112 mode = "msan"
113
114
115 if cfg.Goos == "linux" && cfg.Goarch == "arm64" && cfg.BuildBuildmode == "default" {
116 cfg.BuildBuildmode = "pie"
117 }
118 }
119 if cfg.BuildASan {
120 mode = "asan"
121 }
122 modeFlag := "-" + mode
123
124 if !cfg.BuildContext.CgoEnabled {
125 if runtime.GOOS != cfg.Goos || runtime.GOARCH != cfg.Goarch {
126 fmt.Fprintf(os.Stderr, "go: %s requires cgo\n", modeFlag)
127 } else {
128 fmt.Fprintf(os.Stderr, "go: %s requires cgo; enable cgo by setting CGO_ENABLED=1\n", modeFlag)
129 }
130
131 base.SetExitStatus(2)
132 base.Exit()
133 }
134 forcedGcflags = append(forcedGcflags, modeFlag)
135 forcedLdflags = append(forcedLdflags, modeFlag)
136
137 if cfg.BuildContext.InstallSuffix != "" {
138 cfg.BuildContext.InstallSuffix += "_"
139 }
140 cfg.BuildContext.InstallSuffix += mode
141 cfg.BuildContext.ToolTags = append(cfg.BuildContext.ToolTags, mode)
142 }
143
144 func buildModeInit() {
145 gccgo := cfg.BuildToolchainName == "gccgo"
146 var codegenArg string
147
148
149
150
151
152 switch cfg.BuildBuildmode {
153 case "archive":
154 pkgsFilter = pkgsNotMain
155 case "c-archive":
156 pkgsFilter = oneMainPkg
157 if gccgo {
158 codegenArg = "-fPIC"
159 } else {
160 switch cfg.Goos {
161 case "darwin", "ios":
162 switch cfg.Goarch {
163 case "arm64":
164 codegenArg = "-shared"
165 }
166
167 case "dragonfly", "freebsd", "illumos", "linux", "netbsd", "openbsd", "solaris":
168
169
170
171 codegenArg = "-shared"
172 }
173 }
174 cfg.ExeSuffix = ".a"
175 ldBuildmode = "c-archive"
176 case "c-shared":
177 pkgsFilter = oneMainPkg
178 if gccgo {
179 codegenArg = "-fPIC"
180 } else {
181 switch cfg.Goos {
182 case "linux", "android", "freebsd":
183 codegenArg = "-shared"
184 case "windows":
185
186 cfg.ExeSuffix = ""
187 }
188 }
189 ldBuildmode = "c-shared"
190 case "default":
191 switch cfg.Goos {
192 case "android":
193 codegenArg = "-shared"
194 ldBuildmode = "pie"
195 case "windows":
196 ldBuildmode = "pie"
197 case "ios":
198 codegenArg = "-shared"
199 ldBuildmode = "pie"
200 case "darwin":
201 switch cfg.Goarch {
202 case "arm64":
203 codegenArg = "-shared"
204 }
205 fallthrough
206 default:
207 ldBuildmode = "exe"
208 }
209 if gccgo {
210 codegenArg = ""
211 }
212 case "exe":
213 pkgsFilter = pkgsMain
214 ldBuildmode = "exe"
215
216
217
218 if cfg.BuildO != "" {
219 pkgsFilter = oneMainPkg
220 }
221 case "pie":
222 if cfg.BuildRace {
223 base.Fatalf("-buildmode=pie not supported when -race is enabled")
224 }
225 if gccgo {
226 codegenArg = "-fPIE"
227 } else {
228 switch cfg.Goos {
229 case "aix", "windows":
230 default:
231 codegenArg = "-shared"
232 }
233 }
234 ldBuildmode = "pie"
235 case "shared":
236 pkgsFilter = pkgsNotMain
237 if gccgo {
238 codegenArg = "-fPIC"
239 } else {
240 codegenArg = "-dynlink"
241 }
242 if cfg.BuildO != "" {
243 base.Fatalf("-buildmode=shared and -o not supported together")
244 }
245 ldBuildmode = "shared"
246 case "plugin":
247 pkgsFilter = oneMainPkg
248 if gccgo {
249 codegenArg = "-fPIC"
250 } else {
251 codegenArg = "-dynlink"
252 }
253 cfg.ExeSuffix = ".so"
254 ldBuildmode = "plugin"
255 default:
256 base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
257 }
258
259 if !sys.BuildModeSupported(cfg.BuildToolchainName, cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) {
260 base.Fatalf("-buildmode=%s not supported on %s/%s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch)
261 }
262
263 if cfg.BuildLinkshared {
264 if !sys.BuildModeSupported(cfg.BuildToolchainName, "shared", cfg.Goos, cfg.Goarch) {
265 base.Fatalf("-linkshared not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
266 }
267 if gccgo {
268 codegenArg = "-fPIC"
269 } else {
270 forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1",
271 "-linkshared")
272 codegenArg = "-dynlink"
273 forcedGcflags = append(forcedGcflags, "-linkshared")
274
275 forcedLdflags = append(forcedLdflags, "-linkshared", "-w")
276 }
277 }
278 if codegenArg != "" {
279 if gccgo {
280 forcedGccgoflags = append([]string{codegenArg}, forcedGccgoflags...)
281 } else {
282 forcedAsmflags = append([]string{codegenArg}, forcedAsmflags...)
283 forcedGcflags = append([]string{codegenArg}, forcedGcflags...)
284 }
285
286 if cfg.BuildBuildmode != "default" || cfg.BuildLinkshared {
287 if cfg.BuildContext.InstallSuffix != "" {
288 cfg.BuildContext.InstallSuffix += "_"
289 }
290 cfg.BuildContext.InstallSuffix += codegenArg[1:]
291 }
292 }
293
294 switch cfg.BuildMod {
295 case "":
296
297 case "readonly", "vendor", "mod":
298 if !cfg.ModulesEnabled && !base.InGOFLAGS("-mod") {
299 base.Fatalf("build flag -mod=%s only valid when using modules", cfg.BuildMod)
300 }
301 default:
302 base.Fatalf("-mod=%s not supported (can be '', 'mod', 'readonly', or 'vendor')", cfg.BuildMod)
303 }
304 if !cfg.ModulesEnabled {
305 if cfg.ModCacheRW && !base.InGOFLAGS("-modcacherw") {
306 base.Fatalf("build flag -modcacherw only valid when using modules")
307 }
308 if cfg.ModFile != "" && !base.InGOFLAGS("-mod") {
309 base.Fatalf("build flag -modfile only valid when using modules")
310 }
311 }
312 }
313
View as plain text