1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
17 // Initialization for any invocation.
19 // The usual variables.
31 goextlinkenabled string
42 defaultcxxtarget string
43 defaultcctarget string
47 sflag bool // build static binaries
48 vflag int // verbosity
51 // The known architecture letters.
52 var gochars = "566899"
54 // The known architectures.
55 var okgoarch = []string{
56 // same order as gochars
65 // The known operating systems.
66 var okgoos = []string{
80 // find reports the first index of p in l[0:n], or else -1.
81 func find(p string, l []string) int {
90 // xinit handles initialization of the various global state, like goroot and goarch.
92 goroot = os.Getenv("GOROOT")
93 if slash == "/" && len(goroot) > 1 || slash == `\` && len(goroot) > 3 {
94 // if not "/" or "c:\", then strip trailing path separator
95 goroot = strings.TrimSuffix(goroot, slash)
98 fatal("$GOROOT must be set")
101 goroot_final = os.Getenv("GOROOT_FINAL")
102 if goroot_final == "" {
103 goroot_final = goroot
106 b := os.Getenv("GOBIN")
108 b = goroot + slash + "bin"
112 b = os.Getenv("GOOS")
117 if find(goos, okgoos) < 0 {
118 fatal("unknown $GOOS %s", goos)
121 b = os.Getenv("GOARM")
127 b = os.Getenv("GO386")
137 p := pathf("%s/include/u.h", goroot)
139 fatal("$GOROOT is not set correctly or not exported\n"+
141 "\t%s does not exist", goroot, p)
144 b = os.Getenv("GOHOSTARCH")
149 i := find(gohostarch, okgoarch)
151 fatal("unknown $GOHOSTARCH %s", gohostarch)
153 gohostchar = gochars[i : i+1]
155 b = os.Getenv("GOARCH")
160 i = find(goarch, okgoarch)
162 fatal("unknown $GOARCH %s", goarch)
164 gochar = gochars[i : i+1]
166 b = os.Getenv("GO_EXTLINK_ENABLED")
168 if b != "0" && b != "1" {
169 fatal("unknown $GO_EXTLINK_ENABLED %s", b)
176 // Use clang on OS X, because gcc is deprecated there.
177 // Xcode for OS X 10.9 Mavericks will ship a fake "gcc" binary that
178 // actually runs clang. We prepare different command
179 // lines for the two binaries, so it matters what we call it.
180 // See golang.org/issue/5822.
189 defaultcflags = os.Getenv("CFLAGS")
191 defaultldflags = os.Getenv("LDFLAGS")
193 b = os.Getenv("CC_FOR_TARGET")
199 b = os.Getenv("CXX_FOR_TARGET")
212 // For tools being invoked but also for os.ExpandEnv.
213 os.Setenv("GO386", go386)
214 os.Setenv("GOARCH", goarch)
215 os.Setenv("GOARM", goarm)
216 os.Setenv("GOHOSTARCH", gohostarch)
217 os.Setenv("GOHOSTOS", gohostos)
218 os.Setenv("GOOS", goos)
219 os.Setenv("GOROOT", goroot)
220 os.Setenv("GOROOT_FINAL", goroot_final)
222 // Make the environment more predictable.
223 os.Setenv("LANG", "C")
224 os.Setenv("LANGUAGE", "en_US.UTF8")
229 tooldir = pathf("%s/pkg/tool/%s_%s", goroot, gohostos, gohostarch)
232 // rmworkdir deletes the work directory.
235 errprintf("rm -rf %s\n", workdir)
240 // Remove trailing spaces.
241 func chomp(s string) string {
242 return strings.TrimRight(s, " \t\r\n")
245 func branchtag(branch string) (tag string, precise bool) {
246 b := run(goroot, CheckExit, "git", "log", "--decorate=full", "--format=format:%d", "master.."+branch)
248 for _, line := range splitlines(b) {
249 // Each line is either blank, or looks like
250 // (tag: refs/tags/go1.4rc2, refs/remotes/origin/release-branch.go1.4, refs/heads/release-branch.go1.4)
251 // We need to find an element starting with refs/tags/.
252 i := strings.Index(line, " refs/tags/")
256 i += len(" refs/tags/")
257 // The tag name ends at a comma or paren (prefer the first).
258 j := strings.Index(line[i:], ",")
260 j = strings.Index(line[i:], ")")
263 continue // malformed line; ignore it
267 precise = true // tag denotes HEAD
274 // findgoversion determines the Go version to use in the version string.
275 func findgoversion() string {
276 // The $GOROOT/VERSION file takes priority, for distributions
277 // without the source repo.
278 path := pathf("%s/VERSION", goroot)
280 b := chomp(readfile(path))
281 // Commands such as "dist version > VERSION" will cause
282 // the shell to create an empty VERSION file and set dist's
283 // stdout to its fd. dist in turn looks at VERSION and uses
284 // its content if available, which is empty at this point.
285 // Only use the VERSION file if it is non-empty.
291 // The $GOROOT/VERSION.cache file is a cache to avoid invoking
292 // git every time we run this command. Unlike VERSION, it gets
293 // deleted by the clean command.
294 path = pathf("%s/VERSION.cache", goroot)
296 return chomp(readfile(path))
299 // Otherwise, use Git.
300 // What is the current branch?
301 branch := chomp(run(goroot, CheckExit, "git", "rev-parse", "--abbrev-ref", "HEAD"))
303 // What are the tags along the current branch?
307 // If we're on a release branch, use the closest matching tag
308 // that is on the release branch (and not on the master branch).
309 if strings.HasPrefix(branch, "release-branch.") {
310 tag, precise = branchtag(branch)
314 // Tag does not point at HEAD; add hash and date to version.
315 tag += chomp(run(goroot, CheckExit, "git", "log", "-n", "1", "--format=format: +%h %cd", "HEAD"))
319 writefile(tag, path, 0)
325 * Initial tree setup.
328 // The old tools that no longer live in $GOBIN or $GOROOT/bin.
329 var oldtool = []string{
330 "5a", "5c", "5g", "5l",
331 "6a", "6c", "6g", "6l",
332 "8a", "8c", "8g", "8l",
333 "9a", "9c", "9g", "9l",
352 // Unreleased directories (relative to $GOROOT) that should
353 // not be in release branches.
354 var unreleased = []string{
360 // setup sets up the tree for the initial build.
362 // Create bin directory.
363 if p := pathf("%s/bin", goroot); !isdir(p) {
367 // Create package directory.
368 if p := pathf("%s/pkg", goroot); !isdir(p) {
372 p := pathf("%s/pkg/%s_%s", goroot, gohostos, gohostarch)
378 if goos != gohostos || goarch != gohostarch {
379 p := pathf("%s/pkg/%s_%s", goroot, goos, goarch)
386 // Create object directory.
387 // We keep it in pkg/ so that all the generated binaries
388 // are in one tree. If pkg/obj/libgc.a exists, it is a dreg from
389 // before we used subdirectories of obj. Delete all of obj
391 if p := pathf("%s/pkg/obj/libgc.a", goroot); isfile(p) {
392 xremoveall(pathf("%s/pkg/obj", goroot))
394 p = pathf("%s/pkg/obj/%s_%s", goroot, gohostos, gohostarch)
400 // Create tool directory.
401 // We keep it in pkg/, just like the object directory above.
407 // Remove tool binaries from before the tool/gohostos_gohostarch
408 xremoveall(pathf("%s/bin/tool", goroot))
410 // Remove old pre-tool binaries.
411 for _, old := range oldtool {
412 xremove(pathf("%s/bin/%s", goroot, old))
415 // If $GOBIN is set and has a Go compiler, it must be cleaned.
416 for _, char := range gochars {
417 if isfile(pathf("%s%s%c%s", gobin, slash, char, "g")) {
418 for _, old := range oldtool {
419 xremove(pathf("%s/%s", gobin, old))
425 // For release, make sure excluded things are excluded.
426 goversion := findgoversion()
427 if strings.HasPrefix(goversion, "release.") || (strings.HasPrefix(goversion, "go") && !strings.Contains(goversion, "beta")) {
428 for _, dir := range unreleased {
429 if p := pathf("%s/%s", goroot, dir); isdir(p) {
430 fatal("%s should not exist in release build", p)
437 * C library and tool building
440 // gccargs is the gcc command line to use for compiling a single C file.
441 var proto_gccargs = []string{
443 // native Plan 9 compilers don't like non-standard prototypes
444 // so let gcc catch them.
445 "-Wstrict-prototypes",
449 "-Wno-missing-braces",
451 "-Wno-unknown-pragmas",
454 "-Wno-missing-field-initializers",
461 // gccargs2 is the second part of gccargs.
462 // it is used if the environment isn't defining CFLAGS.
463 var proto_gccargs2 = []string{
464 // on older versions of GCC, -Wuninitialized is not supported
465 // without -O, so put it here together with -O settings in case
466 // the user's $CFLAGS doesn't include -O.
472 if runtime.GOOS == "netbsd" && runtime.GOARCH == "arm" {
473 // GCC 4.5.4 (NetBSD nb1 20120916) on ARM is known to mis-optimize gc/mparith3.c
474 // Fix available at http://patchwork.ozlabs.org/patch/64562/.
475 proto_gccargs2[1] = "-O1"
479 var gccargs, ldargs []string
481 // deptab lists changes to the default dependencies for a given prefix.
482 // deps ending in /* read the whole directory; deps beginning with -
483 // exclude files with that prefix.
484 var deptab = []struct {
485 prefix string // prefix of target
486 dep []string // dependency tweaks for targets with that prefix
489 "$GOROOT/include/u.h",
490 "$GOROOT/include/utf.h",
491 "$GOROOT/include/fmt.h",
492 "$GOROOT/include/libc.h",
497 "$GOROOT/include/u.h",
498 "$GOROOT/include/utf.h",
499 "$GOROOT/include/fmt.h",
500 "$GOROOT/include/libc.h",
501 "$GOROOT/include/bio.h",
503 {"liblink", []string{
504 "$GOROOT/include/u.h",
505 "$GOROOT/include/utf.h",
506 "$GOROOT/include/fmt.h",
507 "$GOROOT/include/libc.h",
508 "$GOROOT/include/bio.h",
509 "$GOROOT/include/ar.h",
510 "$GOROOT/include/link.h",
520 "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libgc.a",
523 "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libgc.a",
526 "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libgc.a",
529 "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libgc.a",
532 "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
535 "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
538 "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
541 "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libld.a",
547 "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/liblink.a",
548 "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/libbio.a",
549 "$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/lib9.a",
551 {"runtime", []string{
556 // depsuffix records the allowed suffixes for source files.
557 var depsuffix = []string{
564 // gentab records how to generate some trivial files.
565 var gentab = []struct {
567 gen func(string, string)
569 {"opnames.h", gcopnames},
570 {"anames5.c", mkanames},
571 {"anames6.c", mkanames},
572 {"anames8.c", mkanames},
573 {"anames9.c", mkanames},
574 {"zdefaultcc.go", mkzdefaultcc},
575 {"zversion.go", mkzversion},
577 // not generated anymore, but delete the file if we see it
581 // install installs the library, package, or binary associated with dir,
582 // which is relative to $GOROOT/src.
583 func install(dir string) {
585 if goos != gohostos || goarch != gohostarch {
586 errprintf("%s (%s/%s)\n", dir, goos, goarch)
588 errprintf("%s\n", dir)
594 for _, name := range clean {
599 // path = full path to dir.
600 path := pathf("%s/src/%s", goroot, dir)
601 name := filepath.Base(dir)
603 // set up gcc command line on first run.
605 gccargs = splitfields(defaultcc + " " + defaultcflags)
606 gccargs = append(gccargs, proto_gccargs...)
607 if defaultcflags == "" {
608 gccargs = append(gccargs, proto_gccargs2...)
610 if strings.Contains(gccargs[0], "clang") {
611 // disable ASCII art in clang errors, if possible
612 gccargs = append(gccargs, "-fno-caret-diagnostics")
613 // clang is too smart about unused command-line arguments
614 gccargs = append(gccargs, "-Qunused-arguments")
616 // disable word wrapping in error messages
617 gccargs = append(gccargs, "-fmessage-length=0")
618 if gohostos == "darwin" && gohostarch != "arm" {
619 // golang.org/issue/5261
620 gccargs = append(gccargs, "-mmacosx-version-min=10.6")
623 if ldargs == nil && defaultldflags != "" {
624 ldargs = splitfields(defaultldflags)
627 islib := strings.HasPrefix(dir, "lib") || dir == "cmd/gc" || dir == "cmd/ld"
628 ispkg := !islib && !strings.HasPrefix(dir, "cmd/")
629 isgo := ispkg || dir == "cmd/go" || dir == "cmd/cgo"
632 if gohostos == "windows" {
636 // Start final link command line.
637 // Note: code below knows that link.p[targ] is the target.
647 if !strings.HasPrefix(name, "lib") {
650 link = []string{"ar", "rsc", pathf("%s/pkg/obj/%s_%s/%s%s.a", goroot, gohostos, gohostarch, prefix, name)}
651 if gohostos == "plan9" {
657 // Go library (package).
659 link = []string{"pack", pathf("%s/pkg/%s_%s/%s.a", goroot, goos, goarch, dir)}
661 xmkdirall(filepath.Dir(link[targ]))
663 case dir == "cmd/go" || dir == "cmd/cgo":
667 elem = "go_bootstrap"
669 link = []string{fmt.Sprintf("%s/%sl", tooldir, gochar), "-o", pathf("%s/%s%s", tooldir, elem, exe)}
673 // C command. Use gccargs and ldargs.
674 if gohostos == "plan9" {
675 link = []string{fmt.Sprintf("%sl", gohostchar), "-o", pathf("%s/%s", tooldir, name)}
678 link = append(link, gccargs...)
679 link = append(link, ldargs...)
681 link = append(link, "-static")
683 link = append(link, "-o", pathf("%s/%s%s", tooldir, name, exe))
687 link = append(link, "-m64")
689 link = append(link, "-m32")
693 ttarg := mtime(link[targ])
695 // Gather files that are sources for this target.
696 // Everything in that directory, and any target-specific
698 files := xreaddir(path)
700 // Remove files beginning with . or _,
701 // which are likely to be editor temporary files.
702 // This is the same heuristic build.ScanDir uses.
703 // There do exist real C files beginning with _,
704 // so limit that check to just Go files.
705 files = filter(files, func(p string) bool {
706 return !strings.HasPrefix(p, ".") && (!strings.HasPrefix(p, "_") || !strings.HasSuffix(p, ".go"))
711 for _, dt := range deptab {
712 if dir == dt.prefix || strings.HasSuffix(dt.prefix, "/") && strings.HasPrefix(dir, dt.prefix) {
713 for _, p := range dt.dep {
716 case strings.HasSuffix(p, ".a"):
717 libs = append(libs, p)
719 case strings.HasSuffix(p, "/*"):
720 dir := strings.TrimSuffix(p, "/*")
721 for _, name := range xreaddir(pathf("%s/%s", path, dir)) {
722 files = append(files, pathf("%s/%s", dir, name))
725 case strings.HasPrefix(p, "-"):
726 files = filter(files, func(s string) bool {
727 return !strings.HasPrefix(s, p[1:])
731 files = append(files, p)
738 // Convert to absolute paths.
739 for i, p := range files {
741 files[i] = pathf("%s/%s", path, p)
745 // Is the target up-to-date?
746 var gofiles, missing []string
748 files = filter(files, func(p string) bool {
749 for _, suf := range depsuffix {
750 if strings.HasSuffix(p, suf) {
757 if !t.IsZero() && !strings.HasSuffix(p, ".a") && !shouldbuild(p, dir) {
760 if strings.HasSuffix(p, ".go") {
761 gofiles = append(gofiles, p)
767 missing = append(missing, p)
772 // If there are no files to compile, we're done.
778 for _, p := range libs {
779 if mtime(p).After(ttarg) {
790 // For package runtime, copy some files into the work space.
791 if dir == "runtime" {
792 // For use by assembly and C files.
793 copyfile(pathf("%s/pkg/%s_%s/textflag.h", goroot, goos, goarch),
794 pathf("%s/src/cmd/ld/textflag.h", goroot), 0)
795 copyfile(pathf("%s/pkg/%s_%s/funcdata.h", goroot, goos, goarch),
796 pathf("%s/src/runtime/funcdata.h", goroot), 0)
799 // Generate any missing files; regenerate existing ones.
800 for _, p := range files {
801 elem := filepath.Base(p)
802 for _, gt := range gentab {
806 if strings.HasPrefix(elem, gt.nameprefix) {
808 errprintf("generate %s\n", p)
811 // Do not add generated file to clean list.
812 // In runtime, we want to be able to
813 // build the package with the go tool,
814 // and it assumes these generated files already
815 // exist (it does not know how to build them).
816 // The 'clean' command can remove
817 // the generated files.
821 // Did not rebuild p.
822 if find(p, missing) >= 0 {
823 fatal("missing file %s", p)
828 if (goos != gohostos || goarch != gohostarch) && isgo {
829 // We've generated the right files; the go command can do the build.
831 errprintf("skip build for cross-compile %s\n", dir)
838 // The next loop will compile individual non-Go files.
839 // Hand the Go files to the compiler en masse.
840 // For package runtime, this writes go_asm.h, which
841 // the assembly files will need.
843 if strings.HasPrefix(dir, "cmd/") {
846 b := pathf("%s/_go_.a", workdir)
847 clean = append(clean, b)
849 link = append(link, b)
853 compile := []string{pathf("%s/%sg", tooldir, gochar), "-pack", "-o", b, "-p", pkg}
854 if dir == "runtime" {
855 compile = append(compile, "-+", "-asmhdr", pathf("%s/go_asm.h", workdir))
857 compile = append(compile, gofiles...)
858 run(path, CheckExit|ShowOutput, compile...)
861 // Compile the files.
862 for _, p := range files {
863 if !strings.HasSuffix(p, ".c") && !strings.HasSuffix(p, ".s") {
866 name := filepath.Base(p)
870 // C library or tool.
871 if gohostos == "plan9" {
873 gohostchar + "c", "-FTVwp",
876 "-D__SIZE_TYPE__=ulong", // for GNU bison
877 pathf("-I%s/include/plan9", goroot),
878 pathf("-I%s/include/plan9/%s", goroot, gohostarch),
881 compile = gccargs[0:len(gccargs):len(gccargs)]
882 compile = append(compile, "-c")
885 compile = append(compile, "-m64")
887 compile = append(compile, "-m32")
889 compile = append(compile, "-I", pathf("%s/include", goroot))
893 compile = append(compile, "-DPLAN9PORT")
896 compile = append(compile, "-I", path)
898 // lib9/goos.c gets the default constants hard-coded.
899 if name == "goos.c" {
900 compile = append(compile,
901 "-D", fmt.Sprintf("GOOS=%q", goos),
902 "-D", fmt.Sprintf("GOARCH=%q", goarch),
903 "-D", fmt.Sprintf("GOROOT=%q", goroot_final),
904 "-D", fmt.Sprintf("GOVERSION=%q", findgoversion()),
905 "-D", fmt.Sprintf("GOARM=%q", goarm),
906 "-D", fmt.Sprintf("GO386=%q", go386),
907 "-D", fmt.Sprintf("GO_EXTLINK_ENABLED=%q", goextlinkenabled),
911 // liblink/go.c records the GOEXPERIMENT setting used during the build.
913 compile = append(compile,
914 "-D", fmt.Sprintf("GOEXPERIMENT=%q", os.Getenv("GOEXPERIMENT")))
917 // Assembly file for a Go package.
919 pathf("%s/%sa", tooldir, gochar),
921 "-I", pathf("%s/pkg/%s_%s", goroot, goos, goarch),
922 "-D", "GOOS_" + goos,
923 "-D", "GOARCH_" + goarch,
924 "-D", "GOOS_GOARCH_" + goos + "_" + goarch,
929 b := pathf("%s/%s", workdir, filepath.Base(p))
930 if !isgo && gohostos == "darwin" {
931 // To debug C programs on OS X, it is not enough to say -ggdb
932 // on the command line. You have to leave the object files
933 // lying around too. Leave them in pkg/obj/, which does not
934 // get removed when this tool exits.
935 obj := pathf("%s/pkg/obj/%s", goroot, dir)
937 b = pathf("%s/%s", obj, filepath.Base(p))
941 // Change the last character of the output file (which was c or s).
942 if gohostos == "plan9" {
943 b = b[:len(b)-1] + gohostchar
945 b = b[:len(b)-1] + "o"
947 compile = append(compile, "-o", b, p)
948 bgrun(path, compile...)
950 link = append(link, b)
952 clean = append(clean, b)
957 if isgo && ispackcmd {
959 dopack(link[targ], archive, link[targ+1:])
964 // C binaries need the libraries explicitly, and -lm.
965 link = append(link, libs...)
966 if gohostos != "plan9" {
967 link = append(link, "-lm")
971 // Remove target before writing it.
973 run("", CheckExit|ShowOutput, link...)
976 // matchfield reports whether the field matches this build.
977 func matchfield(f string) bool {
978 for _, tag := range strings.Split(f, ",") {
979 if tag == goos || tag == goarch || tag == "cmd_go_bootstrap" || tag == "go1.1" || (goos == "android" && tag == "linux") {
987 // shouldbuild reports whether we should build this file.
988 // It applies the same rules that are used with context tags
989 // in package go/build, except that the GOOS and GOARCH
990 // can appear anywhere in the file name, not just after _.
991 // In particular, they can be the entire file name (like windows.c).
992 // We also allow the special tag cmd_go_bootstrap.
993 // See ../go/bootstrap.go and package go/build.
994 func shouldbuild(file, dir string) bool {
995 // Check file name for GOOS or GOARCH.
996 name := filepath.Base(file)
997 excluded := func(list []string, ok string) bool {
998 for _, x := range list {
1002 i := strings.Index(name, x)
1007 if i == len(name) || name[i] == '.' || name[i] == '_' {
1013 if excluded(okgoos, goos) || excluded(okgoarch, goarch) {
1018 if strings.Contains(name, "_test") {
1022 // cmd/go/doc.go has a giant /* */ comment before
1023 // it gets to the important detail that it is not part of
1024 // package main. We don't parse those comments,
1025 // so special case that file.
1026 if strings.HasSuffix(file, "cmd/go/doc.go") || strings.HasSuffix(file, "cmd\\go\\doc.go") {
1029 if strings.HasSuffix(file, "cmd/cgo/doc.go") || strings.HasSuffix(file, "cmd\\cgo\\doc.go") {
1033 // Check file contents for // +build lines.
1034 for _, p := range splitlines(readfile(file)) {
1035 p = strings.TrimSpace(p)
1039 if strings.Contains(p, "package documentation") {
1042 if strings.Contains(p, "package main") && dir != "cmd/go" && dir != "cmd/cgo" {
1045 if !strings.HasPrefix(p, "//") {
1048 if !strings.Contains(p, "+build") {
1051 fields := splitfields(p)
1052 if len(fields) < 2 || fields[1] != "+build" {
1055 for _, p := range fields[2:] {
1056 if (p[0] == '!' && !matchfield(p[1:])) || matchfield(p) {
1067 // copy copies the file src to dst, via memory (so only good for small files).
1068 func copyfile(dst, src string, exec int) {
1070 errprintf("cp %s %s\n", src, dst)
1072 writefile(readfile(src), dst, exec)
1075 // dopack copies the package src to dst,
1076 // appending the files listed in extra.
1077 // The archive format is the traditional Unix ar format.
1078 func dopack(dst, src string, extra []string) {
1079 bdst := bytes.NewBufferString(readfile(src))
1080 for _, file := range extra {
1082 // find last path element for archive member name
1083 i := strings.LastIndex(file, "/") + 1
1084 j := strings.LastIndex(file, `\`) + 1
1088 fmt.Fprintf(bdst, "%-16.16s%-12d%-6d%-6d%-8o%-10d`\n", file[i:], 0, 0, 0, 0644, len(b))
1094 writefile(bdst.String(), dst, 0)
1097 // buildorder records the order of builds for the 'go bootstrap' command.
1098 var buildorder = []string{
1103 "cmd/gc", // must be before g
1104 "cmd/ld", // must be before l
1105 "cmd/%sl", // must be before a, g
1109 // The dependency order here was copied from a buildscript
1110 // back when there were build scripts. Will have to
1111 // be maintained by hand, but shouldn't change very
1150 "text/template/parse",
1157 // cleantab records the directories to clean in 'go clean'.
1158 // It is bigger than the buildorder because we clean all the
1159 // compilers but build only the $GOARCH ones.
1160 var cleantab = []string{
1161 // Commands and C libraries.
1216 "text/template/parse",
1223 var runtimegen = []string{
1229 for _, name := range cleantab {
1230 path := pathf("%s/src/%s", goroot, name)
1231 // Remove generated files.
1232 for _, elem := range xreaddir(path) {
1233 for _, gt := range gentab {
1234 if strings.HasPrefix(elem, gt.nameprefix) {
1235 xremove(pathf("%s/%s", path, elem))
1239 // Remove generated binary named for directory.
1240 if strings.HasPrefix(name, "cmd/") {
1241 xremove(pathf("%s/%s", path, name[4:]))
1245 // remove runtimegen files.
1246 path := pathf("%s/src/runtime", goroot)
1247 for _, elem := range runtimegen {
1248 xremove(pathf("%s/%s", path, elem))
1252 // Remove object tree.
1253 xremoveall(pathf("%s/pkg/obj/%s_%s", goroot, gohostos, gohostarch))
1255 // Remove installed packages and tools.
1256 xremoveall(pathf("%s/pkg/%s_%s", goroot, gohostos, gohostarch))
1257 xremoveall(pathf("%s/pkg/%s_%s", goroot, goos, goarch))
1260 // Remove cached version info.
1261 xremove(pathf("%s/VERSION.cache", goroot))
1266 * command implementations
1270 xprintf("usage: go tool dist [command]\n" +
1273 "banner print installation banner\n" +
1274 "bootstrap rebuild everything\n" +
1275 "clean deletes all built files\n" +
1276 "env [-p] print environment (-p: include $PATH)\n" +
1277 "install [dir] install individual directory\n" +
1278 "version print Go version\n" +
1280 "All commands take -v flags to emit extra information.\n",
1285 // The env command prints the default environment.
1287 path := flag.Bool("p", false, "emit updated PATH")
1288 plan9 := flag.Bool("9", false, "emit plan 9 syntax")
1289 windows := flag.Bool("w", false, "emit windows syntax")
1292 format := "%s=\"%s\"\n"
1295 format = "%s='%s'\n"
1297 format = "set %s=%s\r\n"
1300 xprintf(format, "CC", defaultcc)
1301 xprintf(format, "CC_FOR_TARGET", defaultcctarget)
1302 xprintf(format, "GOROOT", goroot)
1303 xprintf(format, "GOBIN", gobin)
1304 xprintf(format, "GOARCH", goarch)
1305 xprintf(format, "GOOS", goos)
1306 xprintf(format, "GOHOSTARCH", gohostarch)
1307 xprintf(format, "GOHOSTOS", gohostos)
1308 xprintf(format, "GOTOOLDIR", tooldir)
1309 xprintf(format, "GOCHAR", gochar)
1310 if goarch == "arm" {
1311 xprintf(format, "GOARM", goarm)
1313 if goarch == "386" {
1314 xprintf(format, "GO386", go386)
1319 if gohostos == "windows" {
1322 xprintf(format, "PATH", fmt.Sprintf("%s%s%s", gobin, sep, os.Getenv("PATH")))
1326 // The bootstrap command runs a build from scratch,
1327 // stopping at having installed the go_bootstrap command.
1328 func cmdbootstrap() {
1329 flag.BoolVar(&rebuildall, "a", rebuildall, "rebuild all")
1330 flag.BoolVar(&sflag, "s", sflag, "build static binaries")
1333 if isdir(pathf("%s/src/pkg", goroot)) {
1335 "The Go package sources have moved to $GOROOT/src.\n"+
1336 "*** %s still exists. ***\n"+
1337 "It probably contains stale files that may confuse the build.\n"+
1338 "Please (check what's there and) remove it and try again.\n"+
1339 "See http://golang.org/s/go14nopkg\n",
1340 pathf("%s/src/pkg", goroot))
1349 // For the main bootstrap, building for host os/arch.
1356 os.Setenv("GOHOSTARCH", gohostarch)
1357 os.Setenv("GOHOSTOS", gohostos)
1358 os.Setenv("GOARCH", goarch)
1359 os.Setenv("GOOS", goos)
1361 for _, pattern := range buildorder {
1363 if strings.Contains(pattern, "%s") {
1364 dir = fmt.Sprintf(pattern, gohostchar)
1367 if oldgochar != gohostchar && strings.Contains(pattern, "%s") {
1368 install(fmt.Sprintf(pattern, oldgochar))
1375 os.Setenv("GOARCH", goarch)
1376 os.Setenv("GOOS", goos)
1378 // Build runtime for actual goos/goarch too.
1379 if goos != gohostos || goarch != gohostarch {
1384 func defaulttarg() string {
1385 // xgetwd might return a path with symlinks fully resolved, and if
1386 // there happens to be symlinks in goroot, then the hasprefix test
1387 // will never succeed. Instead, we use xrealwd to get a canonical
1388 // goroot/src before the comparison to avoid this problem.
1390 src := pathf("%s/src/", goroot)
1391 real_src := xrealwd(src)
1392 if !strings.HasPrefix(pwd, real_src) {
1393 fatal("current directory %s is not under %s", pwd, real_src)
1395 pwd = pwd[len(real_src):]
1396 // guard againt xrealwd return the directory without the trailing /
1397 pwd = strings.TrimPrefix(pwd, "/")
1402 // Install installs the list of packages named on the command line.
1404 flag.BoolVar(&sflag, "s", sflag, "build static binaries")
1407 if flag.NArg() == 0 {
1408 install(defaulttarg())
1411 for _, arg := range flag.Args() {
1416 // Clean deletes temporary objects.
1422 // Banner prints the 'now you've installed Go' banner.
1428 xprintf("Installed Go for %s/%s in %s\n", goos, goarch, goroot)
1429 xprintf("Installed commands in %s\n", gobin)
1431 if !xsamefile(goroot_final, goroot) {
1432 // If the files are to be moved, don't check that gobin
1433 // is on PATH; assume they know what they are doing.
1434 } else if gohostos == "plan9" {
1435 // Check that gobin is bound before /bin.
1436 pid := strings.Replace(readfile("#c/pid"), " ", "", -1)
1437 ns := fmt.Sprintf("/proc/%s/ns", pid)
1438 if !strings.Contains(readfile(ns), fmt.Sprintf("bind -b %s /bin", gobin)) {
1439 xprintf("*** You need to bind %s before /bin.\n", gobin)
1442 // Check that gobin appears in $PATH.
1444 if gohostos == "windows" {
1447 if !strings.Contains(pathsep+os.Getenv("PATH")+pathsep, pathsep+gobin+pathsep) {
1448 xprintf("*** You need to add %s to your PATH.\n", gobin)
1452 if !xsamefile(goroot_final, goroot) {
1454 "The binaries expect %s to be copied or moved to %s\n",
1455 goroot, goroot_final)
1459 // Version prints the Go version.
1462 xprintf("%s\n", findgoversion())