github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/cmd/go/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 "cmd/go/internal/base" 11 "cmd/go/internal/cfg" 12 "cmd/go/internal/load" 13 "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 os.Exit(2) 33 } 34 cfg.BuildPkgdir = p 35 } 36 } 37 38 func instrumentInit() { 39 if !cfg.BuildRace && !cfg.BuildMSan { 40 return 41 } 42 if cfg.BuildRace && cfg.BuildMSan { 43 fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0]) 44 os.Exit(2) 45 } 46 if cfg.BuildMSan && !sys.MSanSupported(cfg.Goos, cfg.Goarch) { 47 fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch) 48 os.Exit(2) 49 } 50 if cfg.BuildRace { 51 if !sys.RaceDetectorSupported(cfg.Goos, cfg.Goarch) { 52 fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, linux/ppc64le, freebsd/amd64, netbsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0]) 53 os.Exit(2) 54 } 55 } 56 mode := "race" 57 if cfg.BuildMSan { 58 mode = "msan" 59 } 60 modeFlag := "-" + mode 61 62 if !cfg.BuildContext.CgoEnabled { 63 fmt.Fprintf(os.Stderr, "go %s: %s requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0], modeFlag) 64 os.Exit(2) 65 } 66 forcedGcflags = append(forcedGcflags, modeFlag) 67 forcedLdflags = append(forcedLdflags, modeFlag) 68 69 if cfg.BuildContext.InstallSuffix != "" { 70 cfg.BuildContext.InstallSuffix += "_" 71 } 72 cfg.BuildContext.InstallSuffix += mode 73 cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, mode) 74 } 75 76 func buildModeInit() { 77 gccgo := cfg.BuildToolchainName == "gccgo" 78 var codegenArg string 79 platform := cfg.Goos + "/" + cfg.Goarch 80 switch cfg.BuildBuildmode { 81 case "archive": 82 pkgsFilter = pkgsNotMain 83 case "c-archive": 84 pkgsFilter = oneMainPkg 85 switch platform { 86 case "darwin/arm", "darwin/arm64": 87 codegenArg = "-shared" 88 default: 89 switch cfg.Goos { 90 case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris": 91 if platform == "linux/ppc64" { 92 base.Fatalf("-buildmode=c-archive not supported on %s\n", platform) 93 } 94 // Use -shared so that the result is 95 // suitable for inclusion in a PIE or 96 // shared library. 97 codegenArg = "-shared" 98 } 99 } 100 cfg.ExeSuffix = ".a" 101 ldBuildmode = "c-archive" 102 case "c-shared": 103 pkgsFilter = oneMainPkg 104 if gccgo { 105 codegenArg = "-fPIC" 106 } else { 107 switch platform { 108 case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/ppc64le", "linux/s390x", 109 "android/amd64", "android/arm", "android/arm64", "android/386", 110 "freebsd/amd64": 111 codegenArg = "-shared" 112 case "darwin/amd64", "darwin/386": 113 case "windows/amd64", "windows/386": 114 // Do not add usual .exe suffix to the .dll file. 115 cfg.ExeSuffix = "" 116 default: 117 base.Fatalf("-buildmode=c-shared not supported on %s\n", platform) 118 } 119 } 120 ldBuildmode = "c-shared" 121 case "default": 122 switch platform { 123 case "android/arm", "android/arm64", "android/amd64", "android/386": 124 codegenArg = "-shared" 125 ldBuildmode = "pie" 126 case "darwin/arm", "darwin/arm64": 127 codegenArg = "-shared" 128 fallthrough 129 default: 130 ldBuildmode = "exe" 131 } 132 case "exe": 133 pkgsFilter = pkgsMain 134 ldBuildmode = "exe" 135 // Set the pkgsFilter to oneMainPkg if the user passed a specific binary output 136 // and is using buildmode=exe for a better error message. 137 // See issue #20017. 138 if cfg.BuildO != "" { 139 pkgsFilter = oneMainPkg 140 } 141 case "pie": 142 if cfg.BuildRace { 143 base.Fatalf("-buildmode=pie not supported when -race is enabled") 144 } 145 if gccgo { 146 base.Fatalf("-buildmode=pie not supported by gccgo") 147 } else { 148 switch platform { 149 case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x", 150 "android/amd64", "android/arm", "android/arm64", "android/386", 151 "freebsd/amd64": 152 codegenArg = "-shared" 153 case "darwin/amd64": 154 codegenArg = "-shared" 155 default: 156 base.Fatalf("-buildmode=pie not supported on %s\n", platform) 157 } 158 } 159 ldBuildmode = "pie" 160 case "shared": 161 pkgsFilter = pkgsNotMain 162 if gccgo { 163 codegenArg = "-fPIC" 164 } else { 165 switch platform { 166 case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x": 167 default: 168 base.Fatalf("-buildmode=shared not supported on %s\n", platform) 169 } 170 codegenArg = "-dynlink" 171 } 172 if cfg.BuildO != "" { 173 base.Fatalf("-buildmode=shared and -o not supported together") 174 } 175 ldBuildmode = "shared" 176 case "plugin": 177 pkgsFilter = oneMainPkg 178 if gccgo { 179 codegenArg = "-fPIC" 180 } else { 181 switch platform { 182 case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le", 183 "android/amd64", "android/arm", "android/arm64", "android/386": 184 case "darwin/amd64": 185 // Skip DWARF generation due to #21647 186 forcedLdflags = append(forcedLdflags, "-w") 187 default: 188 base.Fatalf("-buildmode=plugin not supported on %s\n", platform) 189 } 190 codegenArg = "-dynlink" 191 } 192 cfg.ExeSuffix = ".so" 193 ldBuildmode = "plugin" 194 default: 195 base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode) 196 } 197 if cfg.BuildLinkshared { 198 if gccgo { 199 codegenArg = "-fPIC" 200 } else { 201 switch platform { 202 case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x": 203 forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1") 204 default: 205 base.Fatalf("-linkshared not supported on %s\n", platform) 206 } 207 codegenArg = "-dynlink" 208 // TODO(mwhudson): remove -w when that gets fixed in linker. 209 forcedLdflags = append(forcedLdflags, "-linkshared", "-w") 210 } 211 } 212 if codegenArg != "" { 213 if gccgo { 214 forcedGccgoflags = append([]string{codegenArg}, forcedGccgoflags...) 215 } else { 216 forcedAsmflags = append([]string{codegenArg}, forcedAsmflags...) 217 forcedGcflags = append([]string{codegenArg}, forcedGcflags...) 218 } 219 // Don't alter InstallSuffix when modifying default codegen args. 220 if cfg.BuildBuildmode != "default" || cfg.BuildLinkshared { 221 if cfg.BuildContext.InstallSuffix != "" { 222 cfg.BuildContext.InstallSuffix += "_" 223 } 224 cfg.BuildContext.InstallSuffix += codegenArg[1:] 225 } 226 } 227 228 switch cfg.BuildMod { 229 case "": 230 // ok 231 case "readonly", "vendor": 232 if load.ModLookup == nil && !inGOFLAGS("-mod") { 233 base.Fatalf("build flag -mod=%s only valid when using modules", cfg.BuildMod) 234 } 235 default: 236 base.Fatalf("-mod=%s not supported (can be '', 'readonly', or 'vendor')", cfg.BuildMod) 237 } 238 } 239 240 func inGOFLAGS(flag string) bool { 241 for _, goflag := range base.GOFLAGS() { 242 name := goflag 243 if strings.HasPrefix(name, "--") { 244 name = name[1:] 245 } 246 if i := strings.Index(name, "="); i >= 0 { 247 name = name[:i] 248 } 249 if name == flag { 250 return true 251 } 252 } 253 return false 254 }