]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/go/internal/work/init.go
[dev.fuzz] all: merge master (d137b74) into dev.fuzz
[gostls13.git] / src / cmd / go / internal / work / init.go
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         "cmd/go/internal/base"
11         "cmd/go/internal/cfg"
12         "cmd/go/internal/fsys"
13         "cmd/go/internal/modload"
14         "cmd/internal/sys"
15         "flag"
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         // 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)
34                 if err != nil {
35                         fmt.Fprintf(os.Stderr, "go %s: evaluating -pkgdir: %v\n", flag.Args()[0], err)
36                         base.SetExitStatus(2)
37                         base.Exit()
38                 }
39                 cfg.BuildPkgdir = p
40         }
41
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)
46                 }
47         }
48 }
49
50 func FuzzInstrumentFlags() []string {
51         if cfg.Goarch != "amd64" && cfg.Goarch != "arm64" {
52                 // Instrumentation is only supported on 64-bit architectures.
53                 return nil
54         }
55         return []string{"-d=libfuzzer"}
56 }
57
58 func instrumentInit() {
59         if !cfg.BuildRace && !cfg.BuildMSan {
60                 return
61         }
62         if cfg.BuildRace && cfg.BuildMSan {
63                 fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0])
64                 base.SetExitStatus(2)
65                 base.Exit()
66         }
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)
69                 base.SetExitStatus(2)
70                 base.Exit()
71         }
72         if cfg.BuildRace {
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])
75                         base.SetExitStatus(2)
76                         base.Exit()
77                 }
78         }
79         mode := "race"
80         if cfg.BuildMSan {
81                 mode = "msan"
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"
86                 }
87         }
88         modeFlag := "-" + mode
89
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)
93                 } else {
94                         fmt.Fprintf(os.Stderr, "go %s: %s requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0], modeFlag)
95                 }
96
97                 base.SetExitStatus(2)
98                 base.Exit()
99         }
100         forcedGcflags = append(forcedGcflags, modeFlag)
101         forcedLdflags = append(forcedLdflags, modeFlag)
102
103         if cfg.BuildContext.InstallSuffix != "" {
104                 cfg.BuildContext.InstallSuffix += "_"
105         }
106         cfg.BuildContext.InstallSuffix += mode
107         cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, mode)
108 }
109
110 func buildModeInit() {
111         gccgo := cfg.BuildToolchainName == "gccgo"
112         var codegenArg string
113
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.
117
118         switch cfg.BuildBuildmode {
119         case "archive":
120                 pkgsFilter = pkgsNotMain
121         case "c-archive":
122                 pkgsFilter = oneMainPkg
123                 if gccgo {
124                         codegenArg = "-fPIC"
125                 } else {
126                         switch cfg.Goos {
127                         case "darwin", "ios":
128                                 switch cfg.Goarch {
129                                 case "arm64":
130                                         codegenArg = "-shared"
131                                 }
132
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
136                                 // shared library.
137                                 codegenArg = "-shared"
138                         }
139                 }
140                 cfg.ExeSuffix = ".a"
141                 ldBuildmode = "c-archive"
142         case "c-shared":
143                 pkgsFilter = oneMainPkg
144                 if gccgo {
145                         codegenArg = "-fPIC"
146                 } else {
147                         switch cfg.Goos {
148                         case "linux", "android", "freebsd":
149                                 codegenArg = "-shared"
150                         case "windows":
151                                 // Do not add usual .exe suffix to the .dll file.
152                                 cfg.ExeSuffix = ""
153                         }
154                 }
155                 ldBuildmode = "c-shared"
156         case "default":
157                 switch cfg.Goos {
158                 case "android":
159                         codegenArg = "-shared"
160                         ldBuildmode = "pie"
161                 case "windows":
162                         ldBuildmode = "pie"
163                 case "ios":
164                         codegenArg = "-shared"
165                         ldBuildmode = "pie"
166                 case "darwin":
167                         switch cfg.Goarch {
168                         case "arm64":
169                                 codegenArg = "-shared"
170                         }
171                         fallthrough
172                 default:
173                         ldBuildmode = "exe"
174                 }
175                 if gccgo {
176                         codegenArg = ""
177                 }
178         case "exe":
179                 pkgsFilter = pkgsMain
180                 ldBuildmode = "exe"
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.
183                 // See issue #20017.
184                 if cfg.BuildO != "" {
185                         pkgsFilter = oneMainPkg
186                 }
187         case "pie":
188                 if cfg.BuildRace {
189                         base.Fatalf("-buildmode=pie not supported when -race is enabled")
190                 }
191                 if gccgo {
192                         codegenArg = "-fPIE"
193                 } else {
194                         switch cfg.Goos {
195                         case "aix", "windows":
196                         default:
197                                 codegenArg = "-shared"
198                         }
199                 }
200                 ldBuildmode = "pie"
201         case "shared":
202                 pkgsFilter = pkgsNotMain
203                 if gccgo {
204                         codegenArg = "-fPIC"
205                 } else {
206                         codegenArg = "-dynlink"
207                 }
208                 if cfg.BuildO != "" {
209                         base.Fatalf("-buildmode=shared and -o not supported together")
210                 }
211                 ldBuildmode = "shared"
212         case "plugin":
213                 pkgsFilter = oneMainPkg
214                 if gccgo {
215                         codegenArg = "-fPIC"
216                 } else {
217                         codegenArg = "-dynlink"
218                 }
219                 cfg.ExeSuffix = ".so"
220                 ldBuildmode = "plugin"
221         default:
222                 base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
223         }
224
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)
227         }
228
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)
232                 }
233                 if gccgo {
234                         codegenArg = "-fPIC"
235                 } else {
236                         forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1",
237                                 "-linkshared")
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")
242                 }
243         }
244         if codegenArg != "" {
245                 if gccgo {
246                         forcedGccgoflags = append([]string{codegenArg}, forcedGccgoflags...)
247                 } else {
248                         forcedAsmflags = append([]string{codegenArg}, forcedAsmflags...)
249                         forcedGcflags = append([]string{codegenArg}, forcedGcflags...)
250                 }
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 += "_"
255                         }
256                         cfg.BuildContext.InstallSuffix += codegenArg[1:]
257                 }
258         }
259
260         switch cfg.BuildMod {
261         case "":
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)
266                 }
267         default:
268                 base.Fatalf("-mod=%s not supported (can be '', 'mod', 'readonly', or 'vendor')", cfg.BuildMod)
269         }
270         if !cfg.ModulesEnabled {
271                 if cfg.ModCacheRW && !base.InGOFLAGS("-modcacherw") {
272                         base.Fatalf("build flag -modcacherw only valid when using modules")
273                 }
274                 if cfg.ModFile != "" && !base.InGOFLAGS("-mod") {
275                         base.Fatalf("build flag -modfile only valid when using modules")
276                 }
277         }
278 }