From 2f07af34697c61decdcfa5b11434451fbcf37704 Mon Sep 17 00:00:00 2001 From: Matt Madison Date: Sat, 17 Feb 2018 10:03:48 -0800 Subject: [PATCH 6/9] cmd/dist: separate host and target builds Change the dist tool to allow for OE-style cross- and cross-canadian builds: - command flags --host-only and --target only are added; if one is present, the other changes mentioned below take effect, and arguments may also be specified on the command line to enumerate the package(s) to be built. - for OE cross builds, go_bootstrap is always built for the current build host, and is moved, along with the supporting toolchain (asm, compile, etc.) to a separate 'native_native' directory under GOROOT/pkg/tool. - go_bootstrap is not automatically removed after the build, so it can be reused later (e.g., building both static and shared runtime). Note that for --host-only builds, it would be nice to specify just the "cmd" package to build only the go commands/tools, the staleness checks in the dist tool will fail if the "std" library has not also been built. So host-only builds have to build everything anyway. Upstream-Status: Inappropriate [OE specific] Signed-off-by: Matt Madison more dist cleanup --- src/cmd/dist/build.go | 149 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 111 insertions(+), 38 deletions(-) diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go index afc615b5c2..36262665b2 100644 --- a/src/cmd/dist/build.go +++ b/src/cmd/dist/build.go @@ -38,6 +38,7 @@ var ( goldflags string workdir string tooldir string + build_tooldir string oldgoos string oldgoarch string exe string @@ -49,6 +50,7 @@ var ( rebuildall bool defaultclang bool + crossBuild bool vflag int // verbosity ) @@ -223,6 +225,8 @@ func xinit() { if tooldir = os.Getenv("GOTOOLDIR"); tooldir == "" { tooldir = pathf("%s/pkg/tool/%s_%s", goroot, gohostos, gohostarch) } + build_tooldir = pathf("%s/pkg/tool/native_native", goroot) + } // compilerEnv returns a map from "goos/goarch" to the @@ -252,7 +256,6 @@ func compilerEnv(envName, def string) map[string]string { if gohostos != goos || gohostarch != goarch { m[gohostos+"/"+gohostarch] = m[""] } - m[""] = env } for _, goos := range okgoos { @@ -479,8 +482,10 @@ func setup() { // We keep it in pkg/, just like the object directory above. if rebuildall { xremoveall(tooldir) + xremoveall(build_tooldir) } xmkdirall(tooldir) + xmkdirall(build_tooldir) // Remove tool binaries from before the tool/gohostos_gohostarch xremoveall(pathf("%s/bin/tool", goroot)) @@ -1130,11 +1135,29 @@ func cmdbootstrap() { var noBanner bool var debug bool + var hostOnly bool + var targetOnly bool + var toBuild = []string { "std", "cmd" } + flag.BoolVar(&rebuildall, "a", rebuildall, "rebuild all") flag.BoolVar(&debug, "d", debug, "enable debugging of bootstrap process") flag.BoolVar(&noBanner, "no-banner", noBanner, "do not print banner") + flag.BoolVar(&hostOnly, "host-only", hostOnly, "build only host binaries, not target") + flag.BoolVar(&targetOnly, "target-only", targetOnly, "build only target binaries, not host") - xflagparse(0) + xflagparse(-1) + + if (hostOnly && targetOnly) { + fatalf("specify only one of --host-only or --target-only\n") + } + crossBuild = hostOnly || targetOnly + if flag.NArg() > 0 { + if crossBuild { + toBuild = flag.Args() + } else { + fatalf("package names not permitted without --host-only or --target-only\n") + } + } if debug { // cmd/buildid is used in debug mode. @@ -1182,8 +1205,13 @@ func cmdbootstrap() { xprintf("\n") } - gogcflags = os.Getenv("GO_GCFLAGS") // we were using $BOOT_GO_GCFLAGS until now - goldflags = os.Getenv("GO_LDFLAGS") + // For split host/target cross/cross-canadian builds, we don't + // want to be setting these flags until after we have compiled + // the toolchain that runs on the build host. + if ! crossBuild { + gogcflags = os.Getenv("GO_GCFLAGS") // we were using $BOOT_GO_GCFLAGS until now + goldflags = os.Getenv("GO_LDFLAGS") + } goBootstrap := pathf("%s/go_bootstrap", tooldir) cmdGo := pathf("%s/go", gobin) if debug { @@ -1212,7 +1240,11 @@ func cmdbootstrap() { xprintf("\n") } xprintf("Building Go toolchain2 using go_bootstrap and Go toolchain1.\n") - os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch)) + if crossBuild { + os.Setenv("CC", defaultcc[""]) + } else { + os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch)) + } goInstall(goBootstrap, append([]string{"-i"}, toolchain...)...) if debug { run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full") @@ -1249,45 +1281,82 @@ func cmdbootstrap() { } checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...) - if goos == oldgoos && goarch == oldgoarch { - // Common case - not setting up for cross-compilation. - timelog("build", "toolchain") - if vflag > 0 { - xprintf("\n") + if crossBuild { + gogcflags = os.Getenv("GO_GCFLAGS") + goldflags = os.Getenv("GO_LDFLAGS") + tool_files, _ := filepath.Glob(pathf("%s/*", tooldir)) + for _, f := range tool_files { + copyfile(pathf("%s/%s", build_tooldir, filepath.Base(f)), f, writeExec) + xremove(f) + } + os.Setenv("GOTOOLDIR", build_tooldir) + goBootstrap = pathf("%s/go_bootstrap", build_tooldir) + if hostOnly { + timelog("build", "host toolchain") + if vflag > 0 { + xprintf("\n") + } + xprintf("Building %s for host, %s/%s.\n", strings.Join(toBuild, ","), goos, goarch) + goInstall(goBootstrap, toBuild...) + checkNotStale(goBootstrap, toBuild...) + // Skip cmdGo staleness checks here, since we can't necessarily run the cmdGo binary + + timelog("build", "target toolchain") + if vflag > 0 { + xprintf("\n") + } + } else if targetOnly { + goos = oldgoos + goarch = oldgoarch + os.Setenv("GOOS", goos) + os.Setenv("GOARCH", goarch) + os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch)) + xprintf("Building %s for target, %s/%s.\n", strings.Join(toBuild, ","), goos, goarch) + goInstall(goBootstrap, toBuild...) + checkNotStale(goBootstrap, toBuild...) + // Skip cmdGo staleness checks here, since we can't run the target's cmdGo binary } - xprintf("Building packages and commands for %s/%s.\n", goos, goarch) } else { - // GOOS/GOARCH does not match GOHOSTOS/GOHOSTARCH. - // Finish GOHOSTOS/GOHOSTARCH installation and then - // run GOOS/GOARCH installation. - timelog("build", "host toolchain") - if vflag > 0 { - xprintf("\n") + if goos == oldgoos && goarch == oldgoarch { + // Common case - not setting up for cross-compilation. + timelog("build", "toolchain") + if vflag > 0 { + xprintf("\n") + } + xprintf("Building packages and commands for %s/%s.\n", goos, goarch) + } else { + // GOOS/GOARCH does not match GOHOSTOS/GOHOSTARCH. + // Finish GOHOSTOS/GOHOSTARCH installation and then + // run GOOS/GOARCH installation. + timelog("build", "host toolchain") + if vflag > 0 { + xprintf("\n") + } + xprintf("Building packages and commands for host, %s/%s.\n", goos, goarch) + goInstall(goBootstrap, "std", "cmd") + checkNotStale(goBootstrap, "std", "cmd") + checkNotStale(cmdGo, "std", "cmd") + + timelog("build", "target toolchain") + if vflag > 0 { + xprintf("\n") + } + goos = oldgoos + goarch = oldgoarch + os.Setenv("GOOS", goos) + os.Setenv("GOARCH", goarch) + os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch)) + xprintf("Building packages and commands for target, %s/%s.\n", goos, goarch) } - xprintf("Building packages and commands for host, %s/%s.\n", goos, goarch) goInstall(goBootstrap, "std", "cmd") checkNotStale(goBootstrap, "std", "cmd") checkNotStale(cmdGo, "std", "cmd") - - timelog("build", "target toolchain") - if vflag > 0 { - xprintf("\n") + if debug { + run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full") + run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch)) + checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...) + copyfile(pathf("%s/compile4", tooldir), pathf("%s/compile", tooldir), writeExec) } - goos = oldgoos - goarch = oldgoarch - os.Setenv("GOOS", goos) - os.Setenv("GOARCH", goarch) - os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch)) - xprintf("Building packages and commands for target, %s/%s.\n", goos, goarch) - } - goInstall(goBootstrap, "std", "cmd") - checkNotStale(goBootstrap, "std", "cmd") - checkNotStale(cmdGo, "std", "cmd") - if debug { - run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full") - run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch)) - checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...) - copyfile(pathf("%s/compile4", tooldir), pathf("%s/compile", tooldir), writeExec) } // Check that there are no new files in $GOROOT/bin other than @@ -1305,7 +1374,11 @@ func cmdbootstrap() { } // Remove go_bootstrap now that we're done. - xremove(pathf("%s/go_bootstrap", tooldir)) + // Except that for split host/target cross-builds, we need to + // keep it. + if ! crossBuild { + xremove(pathf("%s/go_bootstrap", tooldir)) + } // Print trailing banner unless instructed otherwise. if !noBanner { -- 2.14.1