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