github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/cmd/dist/cmdbootstrap.go (about) 1 package main 2 3 import ( 4 "flag" 5 "os" 6 "os/exec" 7 "path/filepath" 8 "strings" 9 10 "github.com/zxy12/go_duplicate_112_new/src/zdebug" 11 ) 12 13 // The bootstrap command runs a build from scratch, 14 // stopping at having installed the go_bootstrap command. 15 // 16 // WARNING: This command runs after cmd/dist is built with Go 1.4. 17 // It rebuilds and installs cmd/dist with the new toolchain, so other 18 // commands (like "go tool dist test" in run.bash) can rely on bug fixes 19 // made since Go 1.4, but this function cannot. In particular, the uses 20 // of os/exec in this function cannot assume that 21 // cmd.Env = append(os.Environ(), "X=Y") 22 // sets $X to Y in the command's environment. That guarantee was 23 // added after Go 1.4, and in fact in Go 1.4 it was typically the opposite: 24 // if $X was already present in os.Environ(), most systems preferred 25 // that setting, not the new one. 26 func _cmdbootstrap() { 27 timelog("start", "dist bootstrap") 28 defer timelog("end", "dist bootstrap") 29 30 var noBanner bool 31 var debug bool 32 flag.BoolVar(&rebuildall, "a", rebuildall, "rebuild all") 33 flag.BoolVar(&debug, "d", debug, "enable debugging of bootstrap process") 34 flag.BoolVar(&noBanner, "no-banner", noBanner, "do not print banner") 35 36 xflagparse(0) 37 38 if debug { 39 // cmd/buildid is used in debug mode. 40 toolchain = append(toolchain, "cmd/buildid") 41 } 42 43 if isdir(pathf("%s/src/pkg", goroot)) { 44 fatalf("\n\n"+ 45 "The Go package sources have moved to $GOROOT/src.\n"+ 46 "*** %s still exists. ***\n"+ 47 "It probably contains stale files that may confuse the build.\n"+ 48 "Please (check what's there and) remove it and try again.\n"+ 49 "See https://golang.org/s/go14nopkg\n", 50 pathf("%s/src/pkg", goroot)) 51 } 52 53 if rebuildall { 54 clean() 55 } 56 57 // 创建部分目录2020.7.1 58 setup() 59 60 timelog("build", "toolchain1") 61 // 判断`clang --help` 62 checkCC() 63 64 bootstrapBuildTools() 65 66 // Remember old content of $GOROOT/bin for comparison below. 67 oldBinFiles, _ := filepath.Glob(pathf("%s/bin/*", goroot)) 68 69 // For the main bootstrap, building for host os/arch. 70 oldgoos = goos 71 oldgoarch = goarch 72 goos = gohostos 73 goarch = gohostarch 74 os.Setenv("GOHOSTARCH", gohostarch) 75 os.Setenv("GOHOSTOS", gohostos) 76 os.Setenv("GOARCH", goarch) 77 os.Setenv("GOOS", goos) 78 79 timelog("build", "go_bootstrap") 80 xprintf("Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.\n") 81 // 编译 bin/asm bin/link bin/compile bin/cgo放到 pkg/bootstrap里面完毕 82 83 //install("zdebug") // test zdebug install 84 85 install("runtime") // dependency not visible in sources; also sets up textflag.h 86 87 install("cmd/go") 88 89 if vflag > 0 { 90 xprintf("\n") 91 } 92 93 gogcflags = os.Getenv("GO_GCFLAGS") // we were using $BOOT_GO_GCFLAGS until now 94 goldflags = os.Getenv("GO_LDFLAGS") 95 goBootstrap := pathf("%s/go_bootstrap", tooldir) 96 cmdGo := pathf("%s/go", gobin) 97 if debug { 98 run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full") 99 copyfile(pathf("%s/compile1", tooldir), pathf("%s/compile", tooldir), writeExec) 100 } 101 102 // To recap, so far we have built the new toolchain 103 // (cmd/asm, cmd/cgo, cmd/compile, cmd/link) 104 // using Go 1.4's toolchain and go command. 105 // Then we built the new go command (as go_bootstrap) 106 // using the new toolchain and our own build logic (above). 107 // 108 // toolchain1 = mk(new toolchain, go1.4 toolchain, go1.4 cmd/go) 109 // go_bootstrap = mk(new cmd/go, toolchain1, cmd/dist) 110 // 111 // The toolchain1 we built earlier is built from the new sources, 112 // but because it was built using cmd/go it has no build IDs. 113 // The eventually installed toolchain needs build IDs, so we need 114 // to do another round: 115 // 116 // toolchain2 = mk(new toolchain, toolchain1, go_bootstrap) 117 // 118 timelog("build", "toolchain2") 119 if vflag > 0 { 120 xprintf("\n") 121 } 122 xprintf("Building Go toolchain2 using go_bootstrap and Go toolchain1.\n") 123 os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch)) 124 125 zdebug.T("[%v],[%v]", goBootstrap, toolchain) 126 //goInstall(goBootstrap, append([]string{"-i"}, toolchain...)...) 127 128 if debug { 129 run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full") 130 run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch)) 131 copyfile(pathf("%s/compile2", tooldir), pathf("%s/compile", tooldir), writeExec) 132 } 133 134 // Toolchain2 should be semantically equivalent to toolchain1, 135 // but it was built using the new compilers instead of the Go 1.4 compilers, 136 // so it should at the least run faster. Also, toolchain1 had no build IDs 137 // in the binaries, while toolchain2 does. In non-release builds, the 138 // toolchain's build IDs feed into constructing the build IDs of built targets, 139 // so in non-release builds, everything now looks out-of-date due to 140 // toolchain2 having build IDs - that is, due to the go command seeing 141 // that there are new compilers. In release builds, the toolchain's reported 142 // version is used in place of the build ID, and the go command does not 143 // see that change from toolchain1 to toolchain2, so in release builds, 144 // nothing looks out of date. 145 // To keep the behavior the same in both non-release and release builds, 146 // we force-install everything here. 147 // 148 // toolchain3 = mk(new toolchain, toolchain2, go_bootstrap) 149 // 150 timelog("build", "toolchain3") 151 if vflag > 0 { 152 xprintf("\n") 153 } 154 xprintf("Building Go toolchain3 using go_bootstrap and Go toolchain2.\n") 155 goInstall(goBootstrap, append([]string{"-a", "-i"}, toolchain...)...) 156 if debug { 157 run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full") 158 run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch)) 159 copyfile(pathf("%s/compile3", tooldir), pathf("%s/compile", tooldir), writeExec) 160 } 161 checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...) 162 163 if goos == oldgoos && goarch == oldgoarch { 164 // Common case - not setting up for cross-compilation. 165 timelog("build", "toolchain") 166 if vflag > 0 { 167 xprintf("\n") 168 } 169 xprintf("Building packages and commands for %s/%s.\n", goos, goarch) 170 } else { 171 // GOOS/GOARCH does not match GOHOSTOS/GOHOSTARCH. 172 // Finish GOHOSTOS/GOHOSTARCH installation and then 173 // run GOOS/GOARCH installation. 174 timelog("build", "host toolchain") 175 if vflag > 0 { 176 xprintf("\n") 177 } 178 xprintf("Building packages and commands for host, %s/%s.\n", goos, goarch) 179 goInstall(goBootstrap, "std", "cmd") 180 checkNotStale(goBootstrap, "std", "cmd") 181 checkNotStale(cmdGo, "std", "cmd") 182 183 timelog("build", "target toolchain") 184 if vflag > 0 { 185 xprintf("\n") 186 } 187 goos = oldgoos 188 goarch = oldgoarch 189 os.Setenv("GOOS", goos) 190 os.Setenv("GOARCH", goarch) 191 os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch)) 192 xprintf("Building packages and commands for target, %s/%s.\n", goos, goarch) 193 } 194 targets := []string{"std", "cmd"} 195 if goos == "js" && goarch == "wasm" { 196 // Skip the cmd tools for js/wasm. They're not usable. 197 targets = targets[:1] 198 } 199 goInstall(goBootstrap, targets...) 200 checkNotStale(goBootstrap, targets...) 201 checkNotStale(cmdGo, targets...) 202 if debug { 203 run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full") 204 run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch)) 205 checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...) 206 copyfile(pathf("%s/compile4", tooldir), pathf("%s/compile", tooldir), writeExec) 207 } 208 209 // Check that there are no new files in $GOROOT/bin other than 210 // go and gofmt and $GOOS_$GOARCH (target bin when cross-compiling). 211 binFiles, _ := filepath.Glob(pathf("%s/bin/*", goroot)) 212 ok := map[string]bool{} 213 for _, f := range oldBinFiles { 214 ok[f] = true 215 } 216 for _, f := range binFiles { 217 elem := strings.TrimSuffix(filepath.Base(f), ".exe") 218 if !ok[f] && elem != "go" && elem != "gofmt" && elem != goos+"_"+goarch { 219 fatalf("unexpected new file in $GOROOT/bin: %s", elem) 220 } 221 } 222 223 // Remove go_bootstrap now that we're done. 224 xremove(pathf("%s/go_bootstrap", tooldir)) 225 226 // Print trailing banner unless instructed otherwise. 227 if !noBanner { 228 banner() 229 } 230 } 231 232 // setup sets up the tree for the initial build. 233 func setup() { 234 // Create bin directory. 235 if p := pathf("%s/bin", goroot); !isdir(p) { 236 xmkdir(p) 237 } 238 239 // Create package directory. 240 if p := pathf("%s/pkg", goroot); !isdir(p) { 241 xmkdir(p) 242 } 243 244 p := pathf("%s/pkg/%s_%s", goroot, gohostos, gohostarch) 245 if rebuildall { 246 xremoveall(p) 247 } 248 xmkdirall(p) 249 250 if goos != gohostos || goarch != gohostarch { 251 p := pathf("%s/pkg/%s_%s", goroot, goos, goarch) 252 if rebuildall { 253 xremoveall(p) 254 } 255 xmkdirall(p) 256 } 257 258 // Create object directory. 259 // We used to use it for C objects. 260 // Now we use it for the build cache, to separate dist's cache 261 // from any other cache the user might have. 262 p = pathf("%s/pkg/obj/go-build", goroot) 263 if rebuildall { 264 xremoveall(p) 265 } 266 xmkdirall(p) 267 268 // Create tool directory. 269 // We keep it in pkg/, just like the object directory above. 270 if rebuildall { 271 xremoveall(tooldir) 272 } 273 xmkdirall(tooldir) 274 275 // Remove tool binaries from before the tool/gohostos_gohostarch 276 xremoveall(pathf("%s/bin/tool", goroot)) 277 278 // Remove old pre-tool binaries. 279 for _, old := range oldtool { 280 xremove(pathf("%s/bin/%s", goroot, old)) 281 } 282 283 // If $GOBIN is set and has a Go compiler, it must be cleaned. 284 for _, char := range "56789" { 285 if isfile(pathf("%s/%c%s", gobin, char, "g")) { 286 for _, old := range oldtool { 287 xremove(pathf("%s/%s", gobin, old)) 288 } 289 break 290 } 291 } 292 293 // For release, make sure excluded things are excluded. 294 goversion := findgoversion() 295 if strings.HasPrefix(goversion, "release.") || (strings.HasPrefix(goversion, "go") && !strings.Contains(goversion, "beta")) { 296 for _, dir := range unreleased { 297 if p := pathf("%s/%s", goroot, dir); isdir(p) { 298 fatalf("%s should not exist in release build", p) 299 } 300 } 301 } 302 } 303 304 func checkCC() { 305 if !needCC() { 306 return 307 } 308 //zdebug.T("defaultcc=%+v", defaultcc) 309 if output, err := exec.Command(defaultcc[""], "--help").CombinedOutput(); err != nil { 310 outputHdr := "" 311 if len(output) > 0 { 312 outputHdr = "\nCommand output:\n\n" 313 } 314 fatalf("cannot invoke C compiler %q: %v\n\n"+ 315 "Go needs a system C compiler for use with cgo.\n"+ 316 "To set a C compiler, set CC=the-compiler.\n"+ 317 "To disable cgo, set CGO_ENABLED=0.\n%s%s", defaultcc[""], err, outputHdr, output) 318 } 319 } 320 321 func needCC() bool { 322 switch os.Getenv("CGO_ENABLED") { 323 case "1": 324 return true 325 case "0": 326 return false 327 } 328 return cgoEnabled[gohostos+"/"+gohostarch] 329 }