blob: ee743ab9900be8d1f8d154906e809ae78146e06e [file] [log] [blame]
Andrew Geissler595f6302022-01-24 19:11:47 +00001From 7bc891e00be4263311d75aa2b2ee6a3b7b75355f 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] 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---
39 src/cmd/dist/build.go | 156 ++++++++++++++++++++++++++++++------------
40 1 file changed, 113 insertions(+), 43 deletions(-)
41
Andrew Geissler595f6302022-01-24 19:11:47 +000042--- a/src/cmd/dist/build.go
43+++ b/src/cmd/dist/build.go
Patrick Williams03907ee2022-05-01 06:28:52 -050044@@ -44,6 +44,7 @@ var (
Andrew Geissler595f6302022-01-24 19:11:47 +000045 goexperiment string
46 workdir string
47 tooldir string
48+ build_tooldir string
49 oldgoos string
50 oldgoarch string
51 exe string
Patrick Williams03907ee2022-05-01 06:28:52 -050052@@ -54,6 +55,7 @@ var (
Andrew Geissler595f6302022-01-24 19:11:47 +000053
54 rebuildall bool
55 defaultclang bool
56+ crossBuild bool
57
58 vflag int // verbosity
59 )
Patrick Williams03907ee2022-05-01 06:28:52 -050060@@ -254,6 +256,8 @@ func xinit() {
Andrew Geissler595f6302022-01-24 19:11:47 +000061 if tooldir = os.Getenv("GOTOOLDIR"); tooldir == "" {
62 tooldir = pathf("%s/pkg/tool/%s_%s", goroot, gohostos, gohostarch)
63 }
64+
65+ build_tooldir = pathf("%s/pkg/tool/native_native", goroot)
66 }
67
68 // compilerEnv returns a map from "goos/goarch" to the
Patrick Williams03907ee2022-05-01 06:28:52 -050069@@ -499,8 +503,10 @@ func setup() {
Andrew Geissler595f6302022-01-24 19:11:47 +000070 p := pathf("%s/pkg/%s_%s", goroot, gohostos, gohostarch)
71 if rebuildall {
72 xremoveall(p)
73+ xremoveall(build_tooldir)
74 }
75 xmkdirall(p)
76+ xmkdirall(build_tooldir)
77
78 if goos != gohostos || goarch != gohostarch {
79 p := pathf("%s/pkg/%s_%s", goroot, goos, goarch)
Patrick Williams03907ee2022-05-01 06:28:52 -050080@@ -1252,17 +1258,35 @@ func cmdbootstrap() {
Andrew Geissler595f6302022-01-24 19:11:47 +000081
82 var noBanner, noClean bool
83 var debug bool
84+ var hostOnly bool
85+ var targetOnly bool
86+ var toBuild = []string{"std", "cmd"}
87+
88 flag.BoolVar(&rebuildall, "a", rebuildall, "rebuild all")
89 flag.BoolVar(&debug, "d", debug, "enable debugging of bootstrap process")
90 flag.BoolVar(&noBanner, "no-banner", noBanner, "do not print banner")
91 flag.BoolVar(&noClean, "no-clean", noClean, "print deprecation warning")
92+ flag.BoolVar(&hostOnly, "host-only", hostOnly, "build only host binaries, not target")
93+ flag.BoolVar(&targetOnly, "target-only", targetOnly, "build only target binaries, not host")
94
95- xflagparse(0)
96+ xflagparse(-1)
97
98 if noClean {
99 xprintf("warning: --no-clean is deprecated and has no effect; use 'go install std cmd' instead\n")
100 }
101
102+ if hostOnly && targetOnly {
103+ fatalf("specify only one of --host-only or --target-only\n")
104+ }
105+ crossBuild = hostOnly || targetOnly
106+ if flag.NArg() > 0 {
107+ if crossBuild {
108+ toBuild = flag.Args()
109+ } else {
110+ fatalf("package names not permitted without --host-only or --target-only\n")
111+ }
112+ }
113+
114 // Set GOPATH to an internal directory. We shouldn't actually
115 // need to store files here, since the toolchain won't
116 // depend on modules outside of vendor directories, but if
Patrick Williams03907ee2022-05-01 06:28:52 -0500117@@ -1330,8 +1354,13 @@ func cmdbootstrap() {
Andrew Geissler595f6302022-01-24 19:11:47 +0000118 xprintf("\n")
119 }
120
121- gogcflags = os.Getenv("GO_GCFLAGS") // we were using $BOOT_GO_GCFLAGS until now
122- goldflags = os.Getenv("GO_LDFLAGS") // we were using $BOOT_GO_LDFLAGS until now
123+ // For split host/target cross/cross-canadian builds, we don't
124+ // want to be setting these flags until after we have compiled
125+ // the toolchain that runs on the build host.
126+ if !crossBuild {
127+ gogcflags = os.Getenv("GO_GCFLAGS") // we were using $BOOT_GO_GCFLAGS until now
128+ goldflags = os.Getenv("GO_LDFLAGS") // we were using $BOOT_GO_LDFLAGS until now
129+ }
130 goBootstrap := pathf("%s/go_bootstrap", tooldir)
131 cmdGo := pathf("%s/go", gobin)
132 if debug {
Patrick Williams03907ee2022-05-01 06:28:52 -0500133@@ -1360,7 +1389,11 @@ func cmdbootstrap() {
Andrew Geissler595f6302022-01-24 19:11:47 +0000134 xprintf("\n")
135 }
136 xprintf("Building Go toolchain2 using go_bootstrap and Go toolchain1.\n")
137- os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
138+ if crossBuild {
139+ os.Setenv("CC", defaultcc[""])
140+ } else {
141+ os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
142+ }
143 // Now that cmd/go is in charge of the build process, enable GOEXPERIMENT.
144 os.Setenv("GOEXPERIMENT", goexperiment)
145 goInstall(goBootstrap, append([]string{"-i"}, toolchain...)...)
Patrick Williams03907ee2022-05-01 06:28:52 -0500146@@ -1399,50 +1432,84 @@ func cmdbootstrap() {
Andrew Geissler595f6302022-01-24 19:11:47 +0000147 }
148 checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...)
149
150- if goos == oldgoos && goarch == oldgoarch {
151- // Common case - not setting up for cross-compilation.
152- timelog("build", "toolchain")
153- if vflag > 0 {
154- xprintf("\n")
155+ if crossBuild {
156+ gogcflags = os.Getenv("GO_GCFLAGS")
157+ goldflags = os.Getenv("GO_LDFLAGS")
158+ tool_files, _ := filepath.Glob(pathf("%s/*", tooldir))
159+ for _, f := range tool_files {
160+ copyfile(pathf("%s/%s", build_tooldir, filepath.Base(f)), f, writeExec)
161+ xremove(f)
162+ }
163+ os.Setenv("GOTOOLDIR", build_tooldir)
164+ goBootstrap = pathf("%s/go_bootstrap", build_tooldir)
165+ if hostOnly {
166+ timelog("build", "host toolchain")
167+ if vflag > 0 {
168+ xprintf("\n")
169+ }
170+ xprintf("Building %s for host, %s/%s.\n", strings.Join(toBuild, ","), goos, goarch)
171+ goInstall(goBootstrap, toBuild...)
172+ checkNotStale(goBootstrap, toBuild...)
173+ // Skip cmdGo staleness checks here, since we can't necessarily run the cmdGo binary
174+
175+ timelog("build", "target toolchain")
176+ if vflag > 0 {
177+ xprintf("\n")
178+ }
179+ } else if targetOnly {
180+ goos = oldgoos
181+ goarch = oldgoarch
182+ os.Setenv("GOOS", goos)
183+ os.Setenv("GOARCH", goarch)
184+ os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
185+ xprintf("Building %s for target, %s/%s.\n", strings.Join(toBuild, ","), goos, goarch)
186+ goInstall(goBootstrap, toBuild...)
187+ checkNotStale(goBootstrap, toBuild...)
188+ // Skip cmdGo staleness checks here, since we can't run the target's cmdGo binary
189 }
190- xprintf("Building packages and commands for %s/%s.\n", goos, goarch)
191 } else {
192- // GOOS/GOARCH does not match GOHOSTOS/GOHOSTARCH.
193- // Finish GOHOSTOS/GOHOSTARCH installation and then
194- // run GOOS/GOARCH installation.
195- timelog("build", "host toolchain")
196- if vflag > 0 {
197- xprintf("\n")
Andrew Geissler595f6302022-01-24 19:11:47 +0000198+
199+ if goos == oldgoos && goarch == oldgoarch {
200+ // Common case - not setting up for cross-compilation.
201+ timelog("build", "toolchain")
202+ if vflag > 0 {
203+ xprintf("\n")
204+ }
205+ xprintf("Building packages and commands for %s/%s.\n", goos, goarch)
206+ } else {
207+ // GOOS/GOARCH does not match GOHOSTOS/GOHOSTARCH.
208+ // Finish GOHOSTOS/GOHOSTARCH installation and then
209+ // run GOOS/GOARCH installation.
210+ timelog("build", "host toolchain")
211+ if vflag > 0 {
212+ xprintf("\n")
213+ }
214+ xprintf("Building packages and commands for host, %s/%s.\n", goos, goarch)
215+ goInstall(goBootstrap, "std", "cmd")
216+ checkNotStale(goBootstrap, "std", "cmd")
217+ checkNotStale(cmdGo, "std", "cmd")
218+
219+ timelog("build", "target toolchain")
220+ if vflag > 0 {
221+ xprintf("\n")
222+ }
223+ goos = oldgoos
224+ goarch = oldgoarch
225+ os.Setenv("GOOS", goos)
226+ os.Setenv("GOARCH", goarch)
227+ os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
228+ xprintf("Building packages and commands for target, %s/%s.\n", goos, goarch)
Patrick Williams03907ee2022-05-01 06:28:52 -0500229 }
230- xprintf("Building packages and commands for host, %s/%s.\n", goos, goarch)
Andrew Geissler595f6302022-01-24 19:11:47 +0000231 goInstall(goBootstrap, "std", "cmd")
232 checkNotStale(goBootstrap, "std", "cmd")
233 checkNotStale(cmdGo, "std", "cmd")
234
235- timelog("build", "target toolchain")
236- if vflag > 0 {
237- xprintf("\n")
Patrick Williams03907ee2022-05-01 06:28:52 -0500238- }
Andrew Geissler595f6302022-01-24 19:11:47 +0000239- goos = oldgoos
240- goarch = oldgoarch
241- os.Setenv("GOOS", goos)
242- os.Setenv("GOARCH", goarch)
243- os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
244- xprintf("Building packages and commands for target, %s/%s.\n", goos, goarch)
245- }
246- targets := []string{"std", "cmd"}
247- if goos == "js" && goarch == "wasm" {
248- // Skip the cmd tools for js/wasm. They're not usable.
249- targets = targets[:1]
250- }
251- goInstall(goBootstrap, targets...)
252- checkNotStale(goBootstrap, targets...)
253- checkNotStale(cmdGo, targets...)
254- if debug {
255- run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
256- run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch))
257- checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...)
258- copyfile(pathf("%s/compile4", tooldir), pathf("%s/compile", tooldir), writeExec)
Patrick Williams03907ee2022-05-01 06:28:52 -0500259+ if debug {
260+ run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
261+ run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch))
262+ checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...)
263+ copyfile(pathf("%s/compile4", tooldir), pathf("%s/compile", tooldir), writeExec)
264+ }
Andrew Geissler595f6302022-01-24 19:11:47 +0000265 }
266
267 // Check that there are no new files in $GOROOT/bin other than
Patrick Williams03907ee2022-05-01 06:28:52 -0500268@@ -1459,8 +1526,11 @@ func cmdbootstrap() {
Andrew Geissler595f6302022-01-24 19:11:47 +0000269 }
270 }
271
272- // Remove go_bootstrap now that we're done.
273- xremove(pathf("%s/go_bootstrap", tooldir))
274+ // Except that for split host/target cross-builds, we need to
275+ // keep it.
276+ if !crossBuild {
277+ xremove(pathf("%s/go_bootstrap", tooldir))
278+ }
279
280 if goos == "android" {
281 // Make sure the exec wrapper will sync a fresh $GOROOT to the device.