blob: 7aee0bac433e567b131a6be839bff1c51b9c2504 [file] [log] [blame]
Andrew Geissler82c905d2020-04-13 13:39:40 -05001From 10735bb84df17ba657f76835f483cd8543a879c1 Mon Sep 17 00:00:00 2001
2From: Alex Kube <alexander.j.kube@gmail.com>
3Date: Wed, 23 Oct 2019 21:18:12 +0430
4Subject: [PATCH 6/9] cmd/dist: separate host and target builds
5
6Upstream-Status: Inappropriate [OE specific]
7
8Change the dist tool to allow for OE-style cross-
9and cross-canadian builds:
10
11 - command flags --host-only and --target only are added;
12 if one is present, the other changes mentioned below
13 take effect, and arguments may also be specified on
14 the command line to enumerate the package(s) to be
15 built.
16
17 - for OE cross builds, go_bootstrap is always built for
18 the current build host, and is moved, along with the supporting
19 toolchain (asm, compile, etc.) to a separate 'native_native'
20 directory under GOROOT/pkg/tool.
21
22 - go_bootstrap is not automatically removed after the build,
23 so it can be reused later (e.g., building both static and
24 shared runtime).
25
26Note that for --host-only builds, it would be nice to specify
27just the "cmd" package to build only the go commands/tools,
28the staleness checks in the dist tool will fail if the "std"
29library has not also been built. So host-only builds have to
30build everything anyway.
31
32Adapted to Go 1.13 from patches originally submitted to
33the meta/recipes-devtools/go tree by
34Matt Madison <matt@madison.systems>.
35
36Signed-off-by: Alexander J Kube <alexander.j.kube@gmail.com>
37---
38 src/cmd/dist/build.go | 155 ++++++++++++++++++++++++++++++------------
39 1 file changed, 112 insertions(+), 43 deletions(-)
40
41--- a/src/cmd/dist/build.go
42+++ b/src/cmd/dist/build.go
43@@ -41,6 +41,7 @@ var (
44 goldflags string
45 workdir string
46 tooldir string
47+ build_tooldir string
48 oldgoos string
49 oldgoarch string
50 exe string
51@@ -53,6 +54,7 @@ var (
52
53 rebuildall bool
54 defaultclang bool
55+ crossBuild bool
56
57 vflag int // verbosity
58 )
59@@ -249,6 +251,8 @@ func xinit() {
60 if tooldir = os.Getenv("GOTOOLDIR"); tooldir == "" {
61 tooldir = pathf("%s/pkg/tool/%s_%s", goroot, gohostos, gohostarch)
62 }
63+
64+ build_tooldir = pathf("%s/pkg/tool/native_native", goroot)
65 }
66
67 // compilerEnv returns a map from "goos/goarch" to the
68@@ -480,8 +484,10 @@ func setup() {
69 p := pathf("%s/pkg/%s_%s", goroot, gohostos, gohostarch)
70 if rebuildall {
71 xremoveall(p)
72+ xremoveall(build_tooldir)
73 }
74 xmkdirall(p)
75+ xmkdirall(build_tooldir)
76
77 if goos != gohostos || goarch != gohostarch {
78 p := pathf("%s/pkg/%s_%s", goroot, goos, goarch)
79@@ -1244,12 +1250,29 @@ func cmdbootstrap() {
80
81 var noBanner bool
82 var debug bool
83+ var hostOnly bool
84+ var targetOnly bool
85+ var toBuild = []string{"std", "cmd"}
86+
87 flag.BoolVar(&rebuildall, "a", rebuildall, "rebuild all")
88 flag.BoolVar(&debug, "d", debug, "enable debugging of bootstrap process")
89 flag.BoolVar(&noBanner, "no-banner", noBanner, "do not print banner")
90+ flag.BoolVar(&hostOnly, "host-only", hostOnly, "build only host binaries, not target")
91+ flag.BoolVar(&targetOnly, "target-only", targetOnly, "build only target binaries, not host")
92
93- xflagparse(0)
94+ xflagparse(-1)
95
96+ if hostOnly && targetOnly {
97+ fatalf("specify only one of --host-only or --target-only\n")
98+ }
99+ crossBuild = hostOnly || targetOnly
100+ if flag.NArg() > 0 {
101+ if crossBuild {
102+ toBuild = flag.Args()
103+ } else {
104+ fatalf("package names not permitted without --host-only or --target-only\n")
105+ }
106+ }
107 // Set GOPATH to an internal directory. We shouldn't actually
108 // need to store files here, since the toolchain won't
109 // depend on modules outside of vendor directories, but if
110@@ -1303,8 +1326,13 @@ func cmdbootstrap() {
111 xprintf("\n")
112 }
113
114- gogcflags = os.Getenv("GO_GCFLAGS") // we were using $BOOT_GO_GCFLAGS until now
115- goldflags = os.Getenv("GO_LDFLAGS") // we were using $BOOT_GO_LDFLAGS until now
116+ // For split host/target cross/cross-canadian builds, we don't
117+ // want to be setting these flags until after we have compiled
118+ // the toolchain that runs on the build host.
119+ if !crossBuild {
120+ gogcflags = os.Getenv("GO_GCFLAGS") // we were using $BOOT_GO_GCFLAGS until now
121+ goldflags = os.Getenv("GO_LDFLAGS") // we were using $BOOT_GO_LDFLAGS until now
122+ }
123 goBootstrap := pathf("%s/go_bootstrap", tooldir)
124 cmdGo := pathf("%s/go", gobin)
125 if debug {
126@@ -1333,7 +1361,11 @@ func cmdbootstrap() {
127 xprintf("\n")
128 }
129 xprintf("Building Go toolchain2 using go_bootstrap and Go toolchain1.\n")
130- os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
131+ if crossBuild {
132+ os.Setenv("CC", defaultcc[""])
133+ } else {
134+ os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
135+ }
136 goInstall(goBootstrap, append([]string{"-i"}, toolchain...)...)
137 if debug {
138 run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
139@@ -1370,50 +1402,84 @@ func cmdbootstrap() {
140 }
141 checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...)
142
143- if goos == oldgoos && goarch == oldgoarch {
144- // Common case - not setting up for cross-compilation.
145- timelog("build", "toolchain")
146- if vflag > 0 {
147- xprintf("\n")
148+ if crossBuild {
149+ gogcflags = os.Getenv("GO_GCFLAGS")
150+ goldflags = os.Getenv("GO_LDFLAGS")
151+ tool_files, _ := filepath.Glob(pathf("%s/*", tooldir))
152+ for _, f := range tool_files {
153+ copyfile(pathf("%s/%s", build_tooldir, filepath.Base(f)), f, writeExec)
154+ xremove(f)
155+ }
156+ os.Setenv("GOTOOLDIR", build_tooldir)
157+ goBootstrap = pathf("%s/go_bootstrap", build_tooldir)
158+ if hostOnly {
159+ timelog("build", "host toolchain")
160+ if vflag > 0 {
161+ xprintf("\n")
162+ }
163+ xprintf("Building %s for host, %s/%s.\n", strings.Join(toBuild, ","), goos, goarch)
164+ goInstall(goBootstrap, toBuild...)
165+ checkNotStale(goBootstrap, toBuild...)
166+ // Skip cmdGo staleness checks here, since we can't necessarily run the cmdGo binary
167+
168+ timelog("build", "target toolchain")
169+ if vflag > 0 {
170+ xprintf("\n")
171+ }
172+ } else if targetOnly {
173+ goos = oldgoos
174+ goarch = oldgoarch
175+ os.Setenv("GOOS", goos)
176+ os.Setenv("GOARCH", goarch)
177+ os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
178+ xprintf("Building %s for target, %s/%s.\n", strings.Join(toBuild, ","), goos, goarch)
179+ goInstall(goBootstrap, toBuild...)
180+ checkNotStale(goBootstrap, toBuild...)
181+ // Skip cmdGo staleness checks here, since we can't run the target's cmdGo binary
182 }
183- xprintf("Building packages and commands for %s/%s.\n", goos, goarch)
184 } else {
185- // GOOS/GOARCH does not match GOHOSTOS/GOHOSTARCH.
186- // Finish GOHOSTOS/GOHOSTARCH installation and then
187- // run GOOS/GOARCH installation.
188- timelog("build", "host toolchain")
189- if vflag > 0 {
190- xprintf("\n")
191+
192+ if goos == oldgoos && goarch == oldgoarch {
193+ // Common case - not setting up for cross-compilation.
194+ timelog("build", "toolchain")
195+ if vflag > 0 {
196+ xprintf("\n")
197+ }
198+ xprintf("Building packages and commands for %s/%s.\n", goos, goarch)
199+ } else {
200+ // GOOS/GOARCH does not match GOHOSTOS/GOHOSTARCH.
201+ // Finish GOHOSTOS/GOHOSTARCH installation and then
202+ // run GOOS/GOARCH installation.
203+ timelog("build", "host toolchain")
204+ if vflag > 0 {
205+ xprintf("\n")
206+ }
207+ xprintf("Building packages and commands for host, %s/%s.\n", goos, goarch)
208+ goInstall(goBootstrap, "std", "cmd")
209+ checkNotStale(goBootstrap, "std", "cmd")
210+ checkNotStale(cmdGo, "std", "cmd")
211+
212+ timelog("build", "target toolchain")
213+ if vflag > 0 {
214+ xprintf("\n")
215+ }
216+ goos = oldgoos
217+ goarch = oldgoarch
218+ os.Setenv("GOOS", goos)
219+ os.Setenv("GOARCH", goarch)
220+ os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
221+ xprintf("Building packages and commands for target, %s/%s.\n", goos, goarch)
222 }
223- xprintf("Building packages and commands for host, %s/%s.\n", goos, goarch)
224 goInstall(goBootstrap, "std", "cmd")
225 checkNotStale(goBootstrap, "std", "cmd")
226 checkNotStale(cmdGo, "std", "cmd")
227
228- timelog("build", "target toolchain")
229- if vflag > 0 {
230- xprintf("\n")
231- }
232- goos = oldgoos
233- goarch = oldgoarch
234- os.Setenv("GOOS", goos)
235- os.Setenv("GOARCH", goarch)
236- os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
237- xprintf("Building packages and commands for target, %s/%s.\n", goos, goarch)
238- }
239- targets := []string{"std", "cmd"}
240- if goos == "js" && goarch == "wasm" {
241- // Skip the cmd tools for js/wasm. They're not usable.
242- targets = targets[:1]
243- }
244- goInstall(goBootstrap, targets...)
245- checkNotStale(goBootstrap, targets...)
246- checkNotStale(cmdGo, targets...)
247- if debug {
248- run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
249- run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch))
250- checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...)
251- copyfile(pathf("%s/compile4", tooldir), pathf("%s/compile", tooldir), writeExec)
252+ if debug {
253+ run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
254+ run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch))
255+ checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...)
256+ copyfile(pathf("%s/compile4", tooldir), pathf("%s/compile", tooldir), writeExec)
257+ }
258 }
259
260 // Check that there are no new files in $GOROOT/bin other than
261@@ -1430,8 +1496,11 @@ func cmdbootstrap() {
262 }
263 }
264
265- // Remove go_bootstrap now that we're done.
266- xremove(pathf("%s/go_bootstrap", tooldir))
267+ // Except that for split host/target cross-builds, we need to
268+ // keep it.
269+ if !crossBuild {
270+ xremove(pathf("%s/go_bootstrap", tooldir))
271+ }
272
273 if goos == "android" {
274 // Make sure the exec wrapper will sync a fresh $GOROOT to the device.