Source file src/pkg/cmd/dist/buildtool.go
1
2
3
4
5
6
7
8
9
10
11
12 package main
13
14 import (
15 "fmt"
16 "os"
17 "path/filepath"
18 "runtime"
19 "strings"
20 )
21
22
23
24
25
26
27
28
29
30
31
32 var bootstrapDirs = []string{
33 "cmd/asm",
34 "cmd/asm/internal/arch",
35 "cmd/asm/internal/asm",
36 "cmd/asm/internal/flags",
37 "cmd/asm/internal/lex",
38 "cmd/cgo",
39 "cmd/compile",
40 "cmd/compile/internal/amd64",
41 "cmd/compile/internal/arm",
42 "cmd/compile/internal/arm64",
43 "cmd/compile/internal/gc",
44 "cmd/compile/internal/mips",
45 "cmd/compile/internal/mips64",
46 "cmd/compile/internal/ppc64",
47 "cmd/compile/internal/types",
48 "cmd/compile/internal/s390x",
49 "cmd/compile/internal/ssa",
50 "cmd/compile/internal/syntax",
51 "cmd/compile/internal/x86",
52 "cmd/compile/internal/wasm",
53 "cmd/internal/bio",
54 "cmd/internal/gcprog",
55 "cmd/internal/dwarf",
56 "cmd/internal/edit",
57 "cmd/internal/objabi",
58 "cmd/internal/obj",
59 "cmd/internal/obj/arm",
60 "cmd/internal/obj/arm64",
61 "cmd/internal/obj/mips",
62 "cmd/internal/obj/ppc64",
63 "cmd/internal/obj/s390x",
64 "cmd/internal/obj/x86",
65 "cmd/internal/obj/wasm",
66 "cmd/internal/src",
67 "cmd/internal/sys",
68 "cmd/link",
69 "cmd/link/internal/amd64",
70 "cmd/link/internal/arm",
71 "cmd/link/internal/arm64",
72 "cmd/link/internal/ld",
73 "cmd/link/internal/loadelf",
74 "cmd/link/internal/loadmacho",
75 "cmd/link/internal/loadpe",
76 "cmd/link/internal/loadxcoff",
77 "cmd/link/internal/mips",
78 "cmd/link/internal/mips64",
79 "cmd/link/internal/objfile",
80 "cmd/link/internal/ppc64",
81 "cmd/link/internal/s390x",
82 "cmd/link/internal/sym",
83 "cmd/link/internal/x86",
84 "compress/flate",
85 "compress/zlib",
86 "cmd/link/internal/wasm",
87 "container/heap",
88 "debug/dwarf",
89 "debug/elf",
90 "debug/macho",
91 "debug/pe",
92 "internal/goversion",
93 "internal/race",
94 "internal/xcoff",
95 "math/big",
96 "math/bits",
97 "sort",
98 }
99
100
101
102 var ignorePrefixes = []string{
103 ".",
104 "_",
105 }
106
107
108
109 var ignoreSuffixes = []string{
110 "_arm64.s",
111 "_arm64.go",
112 "_wasm.s",
113 "_wasm.go",
114 }
115
116 func bootstrapBuildTools() {
117 goroot_bootstrap := os.Getenv("GOROOT_BOOTSTRAP")
118 if goroot_bootstrap == "" {
119 goroot_bootstrap = pathf("%s/go1.4", os.Getenv("HOME"))
120 }
121 xprintf("Building Go toolchain1 using %s.\n", goroot_bootstrap)
122
123 mkzbootstrap(pathf("%s/src/cmd/internal/objabi/zbootstrap.go", goroot))
124
125
126
127
128
129
130 workspace := pathf("%s/pkg/bootstrap", goroot)
131 xremoveall(workspace)
132 xatexit(func() { xremoveall(workspace) })
133 base := pathf("%s/src/bootstrap", workspace)
134 xmkdirall(base)
135
136
137 writefile("module bootstrap\n", pathf("%s/%s", base, "go.mod"), 0)
138 for _, dir := range bootstrapDirs {
139 src := pathf("%s/src/%s", goroot, dir)
140 dst := pathf("%s/%s", base, dir)
141 xmkdirall(dst)
142 if dir == "cmd/cgo" {
143
144
145 mkzdefaultcc("", pathf("%s/zdefaultcc.go", src))
146 }
147 Dir:
148 for _, name := range xreaddirfiles(src) {
149 for _, pre := range ignorePrefixes {
150 if strings.HasPrefix(name, pre) {
151 continue Dir
152 }
153 }
154 for _, suf := range ignoreSuffixes {
155 if strings.HasSuffix(name, suf) {
156 continue Dir
157 }
158 }
159 srcFile := pathf("%s/%s", src, name)
160 dstFile := pathf("%s/%s", dst, name)
161 text := bootstrapRewriteFile(srcFile)
162 writefile(text, dstFile, 0)
163 }
164 }
165
166
167
168
169
170
171
172
173
174
175
176 defer os.Setenv("GOROOT", os.Getenv("GOROOT"))
177 os.Setenv("GOROOT", goroot_bootstrap)
178
179 defer os.Setenv("GOPATH", os.Getenv("GOPATH"))
180 os.Setenv("GOPATH", workspace)
181
182 defer os.Setenv("GOBIN", os.Getenv("GOBIN"))
183 os.Setenv("GOBIN", "")
184
185 os.Setenv("GOOS", "")
186 os.Setenv("GOHOSTOS", "")
187 os.Setenv("GOARCH", "")
188 os.Setenv("GOHOSTARCH", "")
189
190
191
192
193
194
195
196
197
198 cmd := []string{
199 pathf("%s/bin/go", goroot_bootstrap),
200 "install",
201 "-gcflags=-l",
202 "-tags=math_big_pure_go compiler_bootstrap",
203 }
204 if vflag > 0 {
205 cmd = append(cmd, "-v")
206 }
207 if tool := os.Getenv("GOBOOTSTRAP_TOOLEXEC"); tool != "" {
208 cmd = append(cmd, "-toolexec="+tool)
209 }
210 cmd = append(cmd, "bootstrap/cmd/...")
211 run(base, ShowOutput|CheckExit, cmd...)
212
213
214 for _, name := range bootstrapDirs {
215 if !strings.HasPrefix(name, "cmd/") {
216 continue
217 }
218 name = name[len("cmd/"):]
219 if !strings.Contains(name, "/") {
220 copyfile(pathf("%s/%s%s", tooldir, name, exe), pathf("%s/bin/%s%s", workspace, name, exe), writeExec)
221 }
222 }
223
224 if vflag > 0 {
225 xprintf("\n")
226 }
227 }
228
229 var ssaRewriteFileSubstring = filepath.FromSlash("src/cmd/compile/internal/ssa/rewrite")
230
231
232
233
234
235
236
237 func isUnneededSSARewriteFile(srcFile string) (archCaps string, unneeded bool) {
238 if !strings.Contains(srcFile, ssaRewriteFileSubstring) {
239 return "", false
240 }
241 fileArch := strings.TrimSuffix(strings.TrimPrefix(filepath.Base(srcFile), "rewrite"), ".go")
242 if fileArch == "" {
243 return "", false
244 }
245 b := fileArch[0]
246 if b == '_' || ('a' <= b && b <= 'z') {
247 return "", false
248 }
249 archCaps = fileArch
250 fileArch = strings.ToLower(fileArch)
251 fileArch = strings.TrimSuffix(fileArch, "splitload")
252 if fileArch == strings.TrimSuffix(runtime.GOARCH, "le") {
253 return "", false
254 }
255 if fileArch == strings.TrimSuffix(os.Getenv("GOARCH"), "le") {
256 return "", false
257 }
258 return archCaps, true
259 }
260
261 func bootstrapRewriteFile(srcFile string) string {
262
263
264
265
266 if archCaps, ok := isUnneededSSARewriteFile(srcFile); ok {
267 return fmt.Sprintf(`// Code generated by go tool dist; DO NOT EDIT.
268
269 package ssa
270
271 func rewriteValue%s(v *Value) bool { panic("unused during bootstrap") }
272 func rewriteBlock%s(b *Block) bool { panic("unused during bootstrap") }
273 `, archCaps, archCaps)
274 }
275
276 return bootstrapFixImports(srcFile)
277 }
278
279 func bootstrapFixImports(srcFile string) string {
280 lines := strings.SplitAfter(readfile(srcFile), "\n")
281 inBlock := false
282 for i, line := range lines {
283 if strings.HasPrefix(line, "import (") {
284 inBlock = true
285 continue
286 }
287 if inBlock && strings.HasPrefix(line, ")") {
288 inBlock = false
289 continue
290 }
291 if strings.HasPrefix(line, `import "`) || strings.HasPrefix(line, `import . "`) ||
292 inBlock && (strings.HasPrefix(line, "\t\"") || strings.HasPrefix(line, "\t. \"")) {
293 line = strings.Replace(line, `"cmd/`, `"bootstrap/cmd/`, -1)
294 for _, dir := range bootstrapDirs {
295 if strings.HasPrefix(dir, "cmd/") {
296 continue
297 }
298 line = strings.Replace(line, `"`+dir+`"`, `"bootstrap/`+dir+`"`, -1)
299 }
300 lines[i] = line
301 }
302 }
303
304 lines[0] = "// Code generated by go tool dist; DO NOT EDIT.\n// This is a bootstrap copy of " + srcFile + "\n\n//line " + srcFile + ":1\n" + lines[0]
305
306 return strings.Join(lines, "")
307 }
308
View as plain text