// Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. #include "a.h" /* * Initialization for any invocation. */ // The usual variables. char *goarch; char *gobin; char *gohostarch; char *gohostos; char *goos; char *goroot; char *workdir; char *gochar; char *goroot_final; char *goversion = "go1"; // TODO: Read correct version char *slash; // / for unix, \ for windows char *default_goroot; static void fixslash(Buf*); static bool shouldbuild(char*, char*); static void copy(char*, char*); // The known architecture letters. static char *gochars = "568"; // The known architectures. static char *okgoarch[] = { // same order as gochars "arm", "amd64", "386", }; // The known operating systems. static char *okgoos[] = { "darwin", "linux", "freebsd", "netbsd", "openbsd", "plan9", "windows", }; static void rmworkdir(void); // find reports the first index of p in l[0:n], or else -1. static int find(char *p, char **l, int n) { int i; for(i=0; i 0) gohostarch = btake(&b); if(find(gohostarch, okgoarch, nelem(okgoarch)) < 0) fatal("unknown $GOHOSTARCH %s", gohostarch); xgetenv(&b, "GOARCH"); if(b.len == 0) bwritestr(&b, gohostarch); goarch = btake(&b); if((i=find(goarch, okgoarch, nelem(okgoarch))) < 0) fatal("unknown $GOARCH %s", goarch); bprintf(&b, "%c", gochars[i]); gochar = btake(&b); xgetenv(&b, "GOROOT_FINAL"); if(b.len > 0) goroot_final = btake(&b); else goroot_final = goroot; xsetenv("GOROOT", goroot); xsetenv("GOARCH", goarch); xsetenv("GOOS", goos); // Make the environment more predictable. xsetenv("LANG", "C"); xsetenv("LANGUAGE", "en_US.UTF8"); workdir = xworkdir(); xatexit(rmworkdir); bfree(&b); } // rmworkdir deletes the work directory. static void rmworkdir(void) { xprintf("rm -rf %s\n", workdir); xremoveall(workdir); } /* * Initial tree setup. */ // The old tools that no longer live in $GOBIN or $GOROOT/bin. static char *oldtool[] = { "5a", "5c", "5g", "5l", "6a", "6c", "6g", "6l", "8a", "8c", "8g", "8l", "6cov", "6nm", "cgo", "ebnflint", "goapi", "gofix", "goinstall", "gomake", "gopack", "gopprof", "gotest", "gotype", "govet", "goyacc", "quietgcc", }; // setup sets up the tree for the initial build. static void setup(void) { int i; Buf b; char *p; binit(&b); run(&b, nil, 0, "ld", "--version", nil); if(contains(bstr(&b), "gold") && contains(bstr(&b), " 2.20")) { fatal("Your system has gold 2.20 installed.\n" "This version is shipped by Ubuntu even though\n" "it is known not to work on Ubuntu.\n" "Binaries built with this linker are likely to fail in mysterious ways.\n" "\n" "Run sudo apt-get remove binutils-gold."); } // Create tool directory. p = bprintf(&b, "%s/bin", goroot); fixslash(&b); if(!isdir(p)) xmkdir(p); p = bprintf(&b, "%s/bin/go-tool", goroot); fixslash(&b); if(!isdir(p)) xmkdir(p); // Create package directory. p = bprintf(&b, "%s/pkg", goroot); fixslash(&b); if(!isdir(p)) xmkdir(p); p = bprintf(&b, "%s/pkg/%s_%s", goroot, goos, goarch); fixslash(&b); xremoveall(p); xmkdir(p); // Remove old pre-tool binaries. for(i=0; i ttarg) stale = 1; if(t == 0) { vadd(&missing, p); files.p[n++] = files.p[i]; continue; } if(!hassuffix(p, ".a") && !shouldbuild(p, dir)) { xfree(files.p[i]); continue; } if(hassuffix(p, ".go")) vadd(&go, p); files.p[n++] = files.p[i]; } files.len = n; for(i=0; i ttarg) stale = 1; if(!stale) goto out; // Generate any missing files. for(i=0; ilen; i++) if(b->p[i] == '/') b->p[i] = '\\'; } // copy copies the file src to dst, via memory (so only good for small files). static void copy(char *dst, char *src) { Buf b; binit(&b); readfile(&b, src); writefile(&b, dst); bfree(&b); } /* * command implementations */ // The env command prints the default environment. void cmdenv(int argc, char **argv) { USED(argc); USED(argv); xprintf("GOROOT=%s\n", goroot); xprintf("GOARCH=%s\n", goarch); xprintf("GOOS=%s\n", goos); } // buildorder records the order of builds for the 'go bootstrap' command. static char *buildorder[] = { "lib9", "libbio", "libmach", "cmd/cov", "cmd/nm", "cmd/pack", "cmd/prof", "cmd/cc", // must be before c "cmd/gc", // must be before g "cmd/%sl", // must be before a, c, g "cmd/%sa", "cmd/%sc", "cmd/%sg", // The dependency order here was copied from a buildscript // back when there were build scripts. Will have to // be maintained by hand, but shouldn't change very // often. "pkg/runtime", "pkg/errors", "pkg/sync/atomic", "pkg/sync", "pkg/io", "pkg/unicode", "pkg/unicode/utf8", "pkg/unicode/utf16", "pkg/bytes", "pkg/math", "pkg/strings", "pkg/strconv", "pkg/bufio", "pkg/sort", "pkg/container/heap", "pkg/encoding/base64", "pkg/syscall", "pkg/time", "pkg/os", "pkg/reflect", "pkg/fmt", "pkg/encoding/json", "pkg/encoding/gob", "pkg/flag", "pkg/path/filepath", "pkg/path", "pkg/io/ioutil", "pkg/log", "pkg/regexp/syntax", "pkg/regexp", "pkg/go/token", "pkg/go/scanner", "pkg/go/ast", "pkg/go/parser", "pkg/go/build", "pkg/os/exec", "pkg/net/url", "pkg/text/template/parse", "pkg/text/template", "cmd/go", }; // The bootstrap command runs a build from scratch, // stopping at having installed the go_bootstrap command. void cmdbootstrap(int argc, char **argv) { int i; Buf b; char *p; setup(); // TODO: nuke(); binit(&b); for(i=0; i