Skip to content

Commit e441676

Browse files
committed
DRAFT: multi architecture / multi os
Not quite right, doesn't set up #! for more than one arch, but I'm taking the day off. Signed-off-by: Ronald G. Minnich <[email protected]>
1 parent 1ae03aa commit e441676

File tree

1 file changed

+50
-43
lines changed

1 file changed

+50
-43
lines changed

main.go

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
"os"
1818
"os/exec"
1919
"path/filepath"
20-
"runtime"
20+
"strings"
2121

2222
"github.com/hashicorp/go-multierror"
2323
"github.com/u-root/u-root/pkg/cpio"
@@ -27,8 +27,8 @@ import (
2727
var (
2828
version = "go1.17.7"
2929
V = log.Printf
30-
arch = runtime.GOARCH
31-
kern = runtime.GOOS
30+
archList = flag.String("arches", "amd64", "comma-separated list of GOARCH")
31+
kernList = flag.String("kernels", "linux", "comma-seperate list of GOOS")
3232
bin string
3333
testrun = true
3434
dest = flag.String("d", "", "Destination directory -- default is os.MkdirTemp")
@@ -62,7 +62,7 @@ func clone(tmp, version, repo, dir, base string) error {
6262
return nil
6363
}
6464

65-
func tidy(tmp, dir, base string) error {
65+
func tidy(tmp, dir, base, kern, arch string) error {
6666
c := exec.Command(filepath.Join(tmp, "go/bin/go"), "mod", "tidy")
6767
c.Stdout, c.Stderr = os.Stdout, os.Stderr
6868
c.Env = append(c.Env, "GOPATH="+tmp)
@@ -78,7 +78,7 @@ func tidy(tmp, dir, base string) error {
7878
return nil
7979
}
8080

81-
func modinit(tmp, host, dir, base string) error {
81+
func modinit(tmp, host, dir, base, kern, arch string) error {
8282
path := filepath.Join(tmp, dir, base)
8383
V("modinit: check %q for go.mod", path)
8484
if _, err := os.Stat(filepath.Join(path, "go.mod")); err == nil {
@@ -117,13 +117,13 @@ func getgo(d, v string) error {
117117

118118
// build builds the code found in filepath.Join(tmp, dir)
119119
// into bin.
120-
func build(tmp, sourcePath, dir, bin string, extra ...string) error {
120+
func build(tmp, sourcePath, dir, bin, kern, arch string, extra ...string) error {
121121
c := exec.Command(filepath.Join(tmp, "go/bin/go"), "build", "-o", bin)
122122
c.Args = append(c.Args, extra...)
123123
c.Dir = filepath.Join(sourcePath, dir)
124124
c.Stdout, c.Stderr = os.Stdout, os.Stderr
125125
c.Env = os.Environ()
126-
c.Env = append(c.Env, "GOROOT_FINAL=/go", "CGO_ENABLED=0")
126+
c.Env = append(c.Env, "GOROOT_FINAL=/go", "CGO_ENABLED=0", "GOOS="+kern, "GOARCH="+arch)
127127
if err := c.Run(); err != nil {
128128
return err
129129
}
@@ -133,7 +133,7 @@ func build(tmp, sourcePath, dir, bin string, extra ...string) error {
133133
// buildToolchain builds the needed Go toolchain binaries: go, compile, link,
134134
// asm. We can no longer do this without the script. Damn.
135135
// TODO: figure out what files we can remove.
136-
func buildToolchain(tmp string) error {
136+
func buildToolchain(tmp, kern, arch string) error {
137137
c := exec.Command("bash", "make.bash")
138138
c.Dir = filepath.Join(tmp, "go/src")
139139
c.Stdout, c.Stderr = os.Stdout, os.Stderr
@@ -173,7 +173,7 @@ func goName(p string) (string, string, string, error) {
173173
return host, filepath.Dir(u.Path), filepath.Base(u.Path), nil
174174
}
175175

176-
func get(target string, args ...string) error {
176+
func get(target string, kernels, archs []string, args ...string) error {
177177
var err error
178178
for _, d := range args {
179179
V("Get %q", d)
@@ -189,28 +189,22 @@ func get(target string, args ...string) error {
189189
err = multierror.Append(err, e)
190190
continue
191191
}
192-
193-
if e := modinit(target, host, dir, base); e != nil {
194-
err = multierror.Append(err, e)
195-
continue
196-
}
197-
if e := tidy(target, dir, base); e != nil {
198-
err = multierror.Append(err, e)
199-
continue
192+
for _, kern := range kernels {
193+
for _, arch := range archs {
194+
if e := modinit(target, host, dir, base, kern, arch); e != nil {
195+
err = multierror.Append(err, e)
196+
continue
197+
}
198+
if e := tidy(target, dir, base, kern, arch); e != nil {
199+
err = multierror.Append(err, e)
200+
continue
201+
}
202+
}
200203
}
201204
}
202205
return err
203206
}
204207

205-
func init() {
206-
if a, ok := os.LookupEnv("GOARCH"); ok {
207-
arch = a
208-
}
209-
if a, ok := os.LookupEnv("GOOS"); ok {
210-
kern = a
211-
}
212-
}
213-
214208
func tree(d string) error {
215209
var err error
216210
for _, n := range []string{"tmp", "dev", "etc"} {
@@ -306,7 +300,10 @@ func ramfs(from, out string, filter ...string) error {
306300

307301
func main() {
308302
flag.Parse()
309-
V("Building for %v_%v", arch, kern)
303+
304+
kernels := strings.Split(*kernList, ",")
305+
archs := strings.Split(*archList, ",")
306+
V("Building for %v_%v", kernels, archs)
310307

311308
// Build the target directory
312309
// Start with a temporary directory
@@ -333,21 +330,27 @@ func main() {
333330
if err := tree(d); err != nil {
334331
log.Fatal(err)
335332
}
336-
bin = filepath.Join(fmt.Sprintf("%v_%v", kern, arch), "bin")
337-
if err := os.MkdirAll(filepath.Join(d, bin), 0755); err != nil {
338-
log.Fatal(err)
339-
}
340-
341333
if err := getgo(d, version); err != nil {
342334
log.Printf("getgo errored, %v, keep going", err)
343335
}
344-
if err := buildToolchain(d); err != nil {
345-
log.Fatal(err)
336+
337+
// Some things need GOOS and GOARCH awareness in surprising ways. Modules are once such.
338+
for _, kern := range kernels {
339+
for _, arch := range archs {
340+
bin = filepath.Join(fmt.Sprintf("%v_%v", kern, arch), "bin")
341+
if err := os.MkdirAll(filepath.Join(d, bin), 0755); err != nil {
342+
log.Fatal(err)
343+
}
344+
345+
if err := buildToolchain(d, kern, arch); err != nil {
346+
log.Fatal(err)
347+
}
348+
}
346349
}
347350
if err := os.MkdirAll(filepath.Join(d, "src"), 0755); err != nil {
348351
log.Fatal(err)
349352
}
350-
if err := get(filepath.Join(d, "src"), append(flag.Args(), "[email protected]:u-root/sourcery")...); err != nil {
353+
if err := get(filepath.Join(d, "src"), kernels, archs, append(flag.Args(), "[email protected]:u-root/sourcery")...); err != nil {
351354
log.Fatalf("Getting packages: %v", err)
352355
}
353356

@@ -360,20 +363,24 @@ func main() {
360363
baseToolPath = pwd
361364
}
362365
V("Build tools from %q", baseToolPath)
363-
for _, tool := range []string{"installcommand", "init"} {
364-
goBin := filepath.Join(d, bin, tool)
365-
V("Build %q in %q, install to %q", tool, baseToolPath, goBin)
366-
if err := build(d, baseToolPath, tool, goBin); err != nil {
367-
log.Fatalf("Building %q -> %q: %v", goBin, tool, err)
366+
for _, kern := range kernels {
367+
for _, arch := range archs {
368+
for _, tool := range []string{"installcommand", "init"} {
369+
goBin := filepath.Join(d, bin, tool)
370+
V("Build %q in %q, install to %q", tool, baseToolPath, goBin)
371+
if err := build(d, baseToolPath, tool, goBin, kern, arch); err != nil {
372+
log.Fatalf("Building %q -> %q: %v", goBin, tool, err)
373+
}
374+
}
375+
368376
}
369377
}
370-
371378
if *outCPIO != "" {
372379
if err := ramfs(d, *outCPIO); err != nil {
373380
log.Printf("ramfs: %v", err)
374381
}
375382
}
376-
log.Printf("sudo strace -o syscalltrace -f unshare -m chroot %q /%q_%q/bin/init", d, kern, arch)
377-
log.Printf("unshare -m chroot %q /%q_%q/bin/init", d, kern, arch)
383+
log.Printf("sudo strace -o syscalltrace -f unshare -m chroot %q /%q_%q/bin/init", d, kernels, archs)
384+
log.Printf("unshare -m chroot %q /%q_%q/bin/init", d, kernels, archs)
378385
log.Printf("rsync -avz --no-owner --no-group -I %q somewhere", d)
379386
}

0 commit comments

Comments
 (0)