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.
20 // Initialization for any invocation.
22 // The usual variables.
33 goextlinkenabled string
34 gogcflags string // For running built compiler
44 defaultcxxtarget string
45 defaultcctarget string
49 vflag int // verbosity
52 // The known architectures.
53 var okgoarch = []string{
66 // The known operating systems.
67 var okgoos = []string{
81 // find reports the first index of p in l[0:n], or else -1.
82 func find(p string, l []string) int {
91 // xinit handles initialization of the various global state, like goroot and goarch.
93 goroot = os.Getenv("GOROOT")
94 if slash == "/" && len(goroot) > 1 || slash == `\` && len(goroot) > 3 {
95 // if not "/" or "c:\", then strip trailing path separator
96 goroot = strings.TrimSuffix(goroot, slash)
99 fatal("$GOROOT must be set")
102 goroot_final = os.Getenv("GOROOT_FINAL")
103 if goroot_final == "" {
104 goroot_final = goroot
107 b := os.Getenv("GOBIN")
109 b = goroot + slash + "bin"
113 b = os.Getenv("GOOS")
118 if find(goos, okgoos) < 0 {
119 fatal("unknown $GOOS %s", goos)
122 b = os.Getenv("GOARM")
128 b = os.Getenv("GO386")
138 p := pathf("%s/src/all.bash", goroot)
140 fatal("$GOROOT is not set correctly or not exported\n"+
142 "\t%s does not exist", goroot, p)
145 b = os.Getenv("GOHOSTARCH")
150 if find(gohostarch, okgoarch) < 0 {
151 fatal("unknown $GOHOSTARCH %s", gohostarch)
154 b = os.Getenv("GOARCH")
159 if find(goarch, okgoarch) < 0 {
160 fatal("unknown $GOARCH %s", goarch)
163 b = os.Getenv("GO_EXTLINK_ENABLED")
165 if b != "0" && b != "1" {
166 fatal("unknown $GO_EXTLINK_ENABLED %s", b)
171 gogcflags = os.Getenv("BOOT_GO_GCFLAGS")
175 // Use clang on OS X, because gcc is deprecated there.
176 // Xcode for OS X 10.9 Mavericks will ship a fake "gcc" binary that
177 // actually runs clang. We prepare different command
178 // lines for the two binaries, so it matters what we call it.
179 // See golang.org/issue/5822.
188 defaultcflags = os.Getenv("CFLAGS")
190 defaultldflags = os.Getenv("LDFLAGS")
192 b = os.Getenv("CC_FOR_TARGET")
198 b = os.Getenv("CXX_FOR_TARGET")
211 // For tools being invoked but also for os.ExpandEnv.
212 os.Setenv("GO386", go386)
213 os.Setenv("GOARCH", goarch)
214 os.Setenv("GOARM", goarm)
215 os.Setenv("GOHOSTARCH", gohostarch)
216 os.Setenv("GOHOSTOS", gohostos)
217 os.Setenv("GOOS", goos)
218 os.Setenv("GOROOT", goroot)
219 os.Setenv("GOROOT_FINAL", goroot_final)
221 // Make the environment more predictable.
222 os.Setenv("LANG", "C")
223 os.Setenv("LANGUAGE", "en_US.UTF8")
228 tooldir = pathf("%s/pkg/tool/%s_%s", goroot, gohostos, gohostarch)
231 // rmworkdir deletes the work directory.
234 errprintf("rm -rf %s\n", workdir)
239 // Remove trailing spaces.
240 func chomp(s string) string {
241 return strings.TrimRight(s, " \t\r\n")
244 func branchtag(branch string) (tag string, precise bool) {
245 b := run(goroot, CheckExit, "git", "log", "--decorate=full", "--format=format:%d", "master.."+branch)
247 for _, line := range splitlines(b) {
248 // Each line is either blank, or looks like
249 // (tag: refs/tags/go1.4rc2, refs/remotes/origin/release-branch.go1.4, refs/heads/release-branch.go1.4)
250 // We need to find an element starting with refs/tags/.
251 i := strings.Index(line, " refs/tags/")
255 i += len(" refs/tags/")
256 // The tag name ends at a comma or paren (prefer the first).
257 j := strings.Index(line[i:], ",")
259 j = strings.Index(line[i:], ")")
262 continue // malformed line; ignore it
266 precise = true // tag denotes HEAD
273 // findgoversion determines the Go version to use in the version string.
274 func findgoversion() string {
275 // The $GOROOT/VERSION file takes priority, for distributions
276 // without the source repo.
277 path := pathf("%s/VERSION", goroot)
279 b := chomp(readfile(path))
280 // Commands such as "dist version > VERSION" will cause
281 // the shell to create an empty VERSION file and set dist's
282 // stdout to its fd. dist in turn looks at VERSION and uses
283 // its content if available, which is empty at this point.
284 // Only use the VERSION file if it is non-empty.
290 // The $GOROOT/VERSION.cache file is a cache to avoid invoking
291 // git every time we run this command. Unlike VERSION, it gets
292 // deleted by the clean command.
293 path = pathf("%s/VERSION.cache", goroot)
295 return chomp(readfile(path))
298 // Show a nicer error message if this isn't a Git repo.
300 fatal("FAILED: not a Git repo; must put a VERSION file in $GOROOT")
303 // Otherwise, use Git.
304 // What is the current branch?
305 branch := chomp(run(goroot, CheckExit, "git", "rev-parse", "--abbrev-ref", "HEAD"))
307 // What are the tags along the current branch?
311 // If we're on a release branch, use the closest matching tag
312 // that is on the release branch (and not on the master branch).
313 if strings.HasPrefix(branch, "release-branch.") {
314 tag, precise = branchtag(branch)
318 // Tag does not point at HEAD; add hash and date to version.
319 tag += chomp(run(goroot, CheckExit, "git", "log", "-n", "1", "--format=format: +%h %cd", "HEAD"))
323 writefile(tag, path, 0)
328 // isGitRepo reports whether the working directory is inside a Git repository.
329 func isGitRepo() bool {
330 // NB: simply checking the exit code of `git rev-parse --git-dir` would
331 // suffice here, but that requires deviating from the infrastructure
332 // provided by `run`.
333 gitDir := chomp(run(goroot, 0, "git", "rev-parse", "--git-dir"))
334 if !filepath.IsAbs(gitDir) {
335 gitDir = filepath.Join(goroot, gitDir)
337 fi, err := os.Stat(gitDir)
338 return err == nil && fi.IsDir()
342 * Initial tree setup.
345 // The old tools that no longer live in $GOBIN or $GOROOT/bin.
346 var oldtool = []string{
347 "5a", "5c", "5g", "5l",
348 "6a", "6c", "6g", "6l",
349 "8a", "8c", "8g", "8l",
350 "9a", "9c", "9g", "9l",
369 // Unreleased directories (relative to $GOROOT) that should
370 // not be in release branches.
371 var unreleased = []string{
378 // setup sets up the tree for the initial build.
380 // Create bin directory.
381 if p := pathf("%s/bin", goroot); !isdir(p) {
385 // Create package directory.
386 if p := pathf("%s/pkg", goroot); !isdir(p) {
390 p := pathf("%s/pkg/%s_%s", goroot, gohostos, gohostarch)
396 if goos != gohostos || goarch != gohostarch {
397 p := pathf("%s/pkg/%s_%s", goroot, goos, goarch)
404 // Create object directory.
405 // We keep it in pkg/ so that all the generated binaries
406 // are in one tree. If pkg/obj/libgc.a exists, it is a dreg from
407 // before we used subdirectories of obj. Delete all of obj
409 if p := pathf("%s/pkg/obj/libgc.a", goroot); isfile(p) {
410 xremoveall(pathf("%s/pkg/obj", goroot))
412 p = pathf("%s/pkg/obj/%s_%s", goroot, gohostos, gohostarch)
418 // Create tool directory.
419 // We keep it in pkg/, just like the object directory above.
425 // Remove tool binaries from before the tool/gohostos_gohostarch
426 xremoveall(pathf("%s/bin/tool", goroot))
428 // Remove old pre-tool binaries.
429 for _, old := range oldtool {
430 xremove(pathf("%s/bin/%s", goroot, old))
433 // If $GOBIN is set and has a Go compiler, it must be cleaned.
434 for _, char := range "56789" {
435 if isfile(pathf("%s%s%c%s", gobin, slash, char, "g")) {
436 for _, old := range oldtool {
437 xremove(pathf("%s/%s", gobin, old))
443 // For release, make sure excluded things are excluded.
444 goversion := findgoversion()
445 if strings.HasPrefix(goversion, "release.") || (strings.HasPrefix(goversion, "go") && !strings.Contains(goversion, "beta")) {
446 for _, dir := range unreleased {
447 if p := pathf("%s/%s", goroot, dir); isdir(p) {
448 fatal("%s should not exist in release build", p)
458 // deptab lists changes to the default dependencies for a given prefix.
459 // deps ending in /* read the whole directory; deps beginning with -
460 // exclude files with that prefix.
461 var deptab = []struct {
462 prefix string // prefix of target
463 dep []string // dependency tweaks for targets with that prefix
469 {"runtime/internal/sys", []string{
472 {"go/build", []string{
477 // depsuffix records the allowed suffixes for source files.
478 var depsuffix = []string{
483 // gentab records how to generate some trivial files.
484 var gentab = []struct {
486 gen func(string, string)
488 {"zdefaultcc.go", mkzdefaultcc},
489 {"zosarch.go", mkzosarch},
490 {"zversion.go", mkzversion},
493 // not generated anymore, but delete the file if we see it
501 // installed maps from a dir name (as given to install) to a chan
502 // closed when the dir's package is installed.
503 var installed = make(map[string]chan struct{})
505 // install installs the library, package, or binary associated with dir,
506 // which is relative to $GOROOT/src.
507 func install(dir string) {
508 if ch, ok := installed[dir]; ok {
511 for _, dep := range builddeps[dir] {
516 if goos != gohostos || goarch != gohostarch {
517 errprintf("%s (%s/%s)\n", dir, goos, goarch)
519 errprintf("%s\n", dir)
523 workdir := pathf("%s/%s", workdir, dir)
528 for _, name := range clean {
533 // path = full path to dir.
534 path := pathf("%s/src/%s", goroot, dir)
535 name := filepath.Base(dir)
537 ispkg := !strings.HasPrefix(dir, "cmd/") || strings.HasPrefix(dir, "cmd/internal/") || strings.HasPrefix(dir, "cmd/asm/internal/")
539 // Start final link command line.
540 // Note: code below knows that link.p[targ] is the target.
547 // Go library (package).
549 link = []string{"pack", pathf("%s/pkg/%s_%s/%s.a", goroot, goos, goarch, dir)}
551 xmkdirall(filepath.Dir(link[targ]))
556 elem = "go_bootstrap"
558 link = []string{pathf("%s/link", tooldir), "-o", pathf("%s/%s%s", tooldir, elem, exe)}
561 ttarg := mtime(link[targ])
563 // Gather files that are sources for this target.
564 // Everything in that directory, and any target-specific
566 files := xreaddir(path)
568 // Remove files beginning with . or _,
569 // which are likely to be editor temporary files.
570 // This is the same heuristic build.ScanDir uses.
571 // There do exist real C files beginning with _,
572 // so limit that check to just Go files.
573 files = filter(files, func(p string) bool {
574 return !strings.HasPrefix(p, ".") && (!strings.HasPrefix(p, "_") || !strings.HasSuffix(p, ".go"))
577 for _, dt := range deptab {
578 if dir == dt.prefix || strings.HasSuffix(dt.prefix, "/") && strings.HasPrefix(dir, dt.prefix) {
579 for _, p := range dt.dep {
581 files = append(files, p)
587 // Convert to absolute paths.
588 for i, p := range files {
590 files[i] = pathf("%s/%s", path, p)
594 // Is the target up-to-date?
595 var gofiles, missing []string
597 files = filter(files, func(p string) bool {
598 for _, suf := range depsuffix {
599 if strings.HasSuffix(p, suf) {
606 if !t.IsZero() && !strings.HasSuffix(p, ".a") && !shouldbuild(p, dir) {
609 if strings.HasSuffix(p, ".go") {
610 gofiles = append(gofiles, p)
616 missing = append(missing, p)
621 // If there are no files to compile, we're done.
630 // For package runtime, copy some files into the work space.
631 if dir == "runtime" || strings.HasPrefix(dir, "runtime/internal/") {
632 xmkdirall(pathf("%s/pkg/include", goroot))
633 // For use by assembly and C files.
634 copyfile(pathf("%s/pkg/include/textflag.h", goroot),
635 pathf("%s/src/runtime/textflag.h", goroot), 0)
636 copyfile(pathf("%s/pkg/include/funcdata.h", goroot),
637 pathf("%s/src/runtime/funcdata.h", goroot), 0)
638 copyfile(pathf("%s/pkg/include/asm_ppc64x.h", goroot),
639 pathf("%s/src/runtime/asm_ppc64x.h", goroot), 0)
642 // Generate any missing files; regenerate existing ones.
643 for _, p := range files {
644 elem := filepath.Base(p)
645 for _, gt := range gentab {
649 if strings.HasPrefix(elem, gt.nameprefix) {
651 errprintf("generate %s\n", p)
654 // Do not add generated file to clean list.
655 // In runtime, we want to be able to
656 // build the package with the go tool,
657 // and it assumes these generated files already
658 // exist (it does not know how to build them).
659 // The 'clean' command can remove
660 // the generated files.
664 // Did not rebuild p.
665 if find(p, missing) >= 0 {
666 fatal("missing file %s", p)
671 if goos != gohostos || goarch != gohostarch {
672 // We've generated the right files; the go command can do the build.
674 errprintf("skip build for cross-compile %s\n", dir)
680 // The next loop will compile individual non-Go files.
681 // Hand the Go files to the compiler en masse.
682 // For package runtime, this writes go_asm.h, which
683 // the assembly files will need.
685 if strings.HasPrefix(dir, "cmd/") {
688 b := pathf("%s/_go_.a", workdir)
689 clean = append(clean, b)
691 link = append(link, b)
695 compile := []string{pathf("%s/compile", tooldir), "-pack", "-o", b, "-p", pkg}
697 compile = append(compile, strings.Fields(gogcflags)...)
699 if dir == "runtime" {
700 compile = append(compile, "-+", "-asmhdr", pathf("%s/go_asm.h", workdir))
702 compile = append(compile, gofiles...)
703 run(path, CheckExit|ShowOutput, compile...)
705 // Compile the files.
706 var wg sync.WaitGroup
707 for _, p := range files {
708 if !strings.HasSuffix(p, ".s") {
713 // Assembly file for a Go package.
715 pathf("%s/asm", tooldir),
717 "-I", pathf("%s/pkg/include", goroot),
718 "-D", "GOOS_" + goos,
719 "-D", "GOARCH_" + goarch,
720 "-D", "GOOS_GOARCH_" + goos + "_" + goarch,
724 b := pathf("%s/%s", workdir, filepath.Base(p))
726 // Change the last character of the output file (which was c or s).
727 b = b[:len(b)-1] + "o"
728 compile = append(compile, "-o", b, p)
729 bgrun(&wg, path, compile...)
731 link = append(link, b)
733 clean = append(clean, b)
740 dopack(link[targ], archive, link[targ+1:])
744 // Remove target before writing it.
746 run("", CheckExit|ShowOutput, link...)
749 // matchfield reports whether the field (x,y,z) matches this build.
750 // all the elements in the field must be satisfied.
751 func matchfield(f string) bool {
752 for _, tag := range strings.Split(f, ",") {
760 // matchtag reports whether the tag (x or !x) matches this build.
761 func matchtag(tag string) bool {
766 if len(tag) == 1 || tag[1] == '!' {
769 return !matchtag(tag[1:])
771 return tag == "gc" || tag == goos || tag == goarch || tag == "cmd_go_bootstrap" || tag == "go1.1" || (goos == "android" && tag == "linux")
774 // shouldbuild reports whether we should build this file.
775 // It applies the same rules that are used with context tags
776 // in package go/build, except that the GOOS and GOARCH
777 // can appear anywhere in the file name, not just after _.
778 // In particular, they can be the entire file name (like windows.c).
779 // We also allow the special tag cmd_go_bootstrap.
780 // See ../go/bootstrap.go and package go/build.
781 func shouldbuild(file, dir string) bool {
782 // Check file name for GOOS or GOARCH.
783 name := filepath.Base(file)
784 excluded := func(list []string, ok string) bool {
785 for _, x := range list {
789 i := strings.Index(name, x)
794 if i == len(name) || name[i] == '.' || name[i] == '_' {
800 if excluded(okgoos, goos) || excluded(okgoarch, goarch) {
805 if strings.Contains(name, "_test") {
809 // Check file contents for // +build lines.
810 for _, p := range splitlines(readfile(file)) {
811 p = strings.TrimSpace(p)
816 i := strings.Index(code, "//")
818 code = strings.TrimSpace(code[:i])
820 if code == "package documentation" {
823 if code == "package main" && dir != "cmd/go" && dir != "cmd/cgo" {
826 if !strings.HasPrefix(p, "//") {
829 if !strings.Contains(p, "+build") {
832 fields := splitfields(p[2:])
833 if len(fields) < 1 || fields[0] != "+build" {
836 for _, p := range fields[1:] {
848 // copy copies the file src to dst, via memory (so only good for small files).
849 func copyfile(dst, src string, flag int) {
851 errprintf("cp %s %s\n", src, dst)
853 writefile(readfile(src), dst, flag)
856 // dopack copies the package src to dst,
857 // appending the files listed in extra.
858 // The archive format is the traditional Unix ar format.
859 func dopack(dst, src string, extra []string) {
860 bdst := bytes.NewBufferString(readfile(src))
861 for _, file := range extra {
863 // find last path element for archive member name
864 i := strings.LastIndex(file, "/") + 1
865 j := strings.LastIndex(file, `\`) + 1
869 fmt.Fprintf(bdst, "%-16.16s%-12d%-6d%-6d%-8o%-10d`\n", file[i:], 0, 0, 0, 0644, len(b))
875 writefile(bdst.String(), dst, 0)
878 // builddeps records the build dependencies for the 'go bootstrap' command.
879 // It is a map[string][]string and generated by mkdeps.bash into deps.go.
881 // buildlist is the list of directories being built, sorted by name.
882 var buildlist = makeBuildlist()
884 func makeBuildlist() []string {
886 for dir := range builddeps {
887 all = append(all, dir)
893 var runtimegen = []string{
899 for _, name := range buildlist {
900 path := pathf("%s/src/%s", goroot, name)
901 // Remove generated files.
902 for _, elem := range xreaddir(path) {
903 for _, gt := range gentab {
904 if strings.HasPrefix(elem, gt.nameprefix) {
905 xremove(pathf("%s/%s", path, elem))
909 // Remove generated binary named for directory.
910 if strings.HasPrefix(name, "cmd/") {
911 xremove(pathf("%s/%s", path, name[4:]))
915 // remove runtimegen files.
916 path := pathf("%s/src/runtime", goroot)
917 for _, elem := range runtimegen {
918 xremove(pathf("%s/%s", path, elem))
922 // Remove object tree.
923 xremoveall(pathf("%s/pkg/obj/%s_%s", goroot, gohostos, gohostarch))
925 // Remove installed packages and tools.
926 xremoveall(pathf("%s/pkg/%s_%s", goroot, gohostos, gohostarch))
927 xremoveall(pathf("%s/pkg/%s_%s", goroot, goos, goarch))
928 xremoveall(pathf("%s/pkg/%s_%s_race", goroot, gohostos, gohostarch))
929 xremoveall(pathf("%s/pkg/%s_%s_race", goroot, goos, goarch))
932 // Remove cached version info.
933 xremove(pathf("%s/VERSION.cache", goroot))
938 * command implementations
942 xprintf("usage: go tool dist [command]\n" +
945 "banner print installation banner\n" +
946 "bootstrap rebuild everything\n" +
947 "clean deletes all built files\n" +
948 "env [-p] print environment (-p: include $PATH)\n" +
949 "install [dir] install individual directory\n" +
950 "list [-json] list all supported platforms\n" +
951 "test [-h] run Go test(s)\n" +
952 "version print Go version\n" +
954 "All commands take -v flags to emit extra information.\n",
959 // The env command prints the default environment.
961 path := flag.Bool("p", false, "emit updated PATH")
962 plan9 := flag.Bool("9", false, "emit plan 9 syntax")
963 windows := flag.Bool("w", false, "emit windows syntax")
966 format := "%s=\"%s\"\n"
971 format = "set %s=%s\r\n"
974 xprintf(format, "CC", defaultcc)
975 xprintf(format, "CC_FOR_TARGET", defaultcctarget)
976 xprintf(format, "GOROOT", goroot)
977 xprintf(format, "GOBIN", gobin)
978 xprintf(format, "GOARCH", goarch)
979 xprintf(format, "GOOS", goos)
980 xprintf(format, "GOHOSTARCH", gohostarch)
981 xprintf(format, "GOHOSTOS", gohostos)
982 xprintf(format, "GOTOOLDIR", tooldir)
984 xprintf(format, "GOARM", goarm)
987 xprintf(format, "GO386", go386)
992 if gohostos == "windows" {
995 xprintf(format, "PATH", fmt.Sprintf("%s%s%s", gobin, sep, os.Getenv("PATH")))
999 // The bootstrap command runs a build from scratch,
1000 // stopping at having installed the go_bootstrap command.
1001 func cmdbootstrap() {
1002 flag.BoolVar(&rebuildall, "a", rebuildall, "rebuild all")
1005 if isdir(pathf("%s/src/pkg", goroot)) {
1007 "The Go package sources have moved to $GOROOT/src.\n"+
1008 "*** %s still exists. ***\n"+
1009 "It probably contains stale files that may confuse the build.\n"+
1010 "Please (check what's there and) remove it and try again.\n"+
1011 "See https://golang.org/s/go14nopkg\n",
1012 pathf("%s/src/pkg", goroot))
1022 bootstrapBuildTools()
1024 // For the main bootstrap, building for host os/arch.
1029 os.Setenv("GOHOSTARCH", gohostarch)
1030 os.Setenv("GOHOSTOS", gohostos)
1031 os.Setenv("GOARCH", goarch)
1032 os.Setenv("GOOS", goos)
1034 // TODO(rsc): Enable when appropriate.
1035 // This step is only needed if we believe that the Go compiler built from Go 1.4
1036 // will produce different object files than the Go compiler built from itself.
1037 // In the absence of bugs, that should not happen.
1038 // And if there are bugs, they're more likely in the current development tree
1039 // than in a standard release like Go 1.4, so don't do this rebuild by default.
1041 xprintf("##### Building Go toolchain using itself.\n")
1042 for _, dir := range buildlist {
1043 installed[dir] = make(chan struct{})
1045 var wg sync.WaitGroup
1046 for _, dir := range builddeps["cmd/go"] {
1058 xprintf("##### Building go_bootstrap for host, %s/%s.\n", gohostos, gohostarch)
1059 for _, dir := range buildlist {
1060 installed[dir] = make(chan struct{})
1062 for _, dir := range buildlist {
1065 <-installed["cmd/go"]
1069 os.Setenv("GOARCH", goarch)
1070 os.Setenv("GOOS", goos)
1072 // Build runtime for actual goos/goarch too.
1073 if goos != gohostos || goarch != gohostarch {
1074 installed["runtime"] = make(chan struct{})
1079 // Cannot use go/build directly because cmd/dist for a new release
1080 // builds against an old release's go/build, which may be out of sync.
1081 // To reduce duplication, we generate the list for go/build from this.
1083 // We list all supported platforms in this list, so that this is the
1084 // single point of truth for supported platforms. This list is used
1085 // by 'go tool dist list'.
1086 var cgoEnabled = map[string]bool{
1088 "darwin/amd64": true,
1090 "darwin/arm64": true,
1091 "dragonfly/amd64": true,
1092 "freebsd/386": true,
1093 "freebsd/amd64": true,
1094 "freebsd/arm": false,
1096 "linux/amd64": true,
1098 "linux/arm64": true,
1099 "linux/ppc64": false,
1100 "linux/ppc64le": true,
1101 "linux/mips64": true,
1102 "linux/mips64le": true,
1103 "linux/s390x": true,
1104 "android/386": true,
1105 "android/amd64": true,
1106 "android/arm": true,
1107 "android/arm64": true,
1109 "nacl/amd64p32": false,
1112 "netbsd/amd64": true,
1114 "openbsd/386": true,
1115 "openbsd/amd64": true,
1116 "openbsd/arm": false,
1118 "plan9/amd64": false,
1120 "solaris/amd64": true,
1121 "windows/386": true,
1122 "windows/amd64": true,
1125 func needCC() bool {
1126 switch os.Getenv("CGO_ENABLED") {
1132 return cgoEnabled[gohostos+"/"+gohostarch]
1139 if output, err := exec.Command(defaultcc, "--help").CombinedOutput(); err != nil {
1141 if len(output) > 0 {
1142 outputHdr = "\nCommand output:\n\n"
1144 fatal("cannot invoke C compiler %q: %v\n\n"+
1145 "Go needs a system C compiler for use with cgo.\n"+
1146 "To set a C compiler, export CC=the-compiler.\n"+
1147 "To disable cgo, export CGO_ENABLED=0.\n%s%s", defaultcc, err, outputHdr, output)
1151 func defaulttarg() string {
1152 // xgetwd might return a path with symlinks fully resolved, and if
1153 // there happens to be symlinks in goroot, then the hasprefix test
1154 // will never succeed. Instead, we use xrealwd to get a canonical
1155 // goroot/src before the comparison to avoid this problem.
1157 src := pathf("%s/src/", goroot)
1158 real_src := xrealwd(src)
1159 if !strings.HasPrefix(pwd, real_src) {
1160 fatal("current directory %s is not under %s", pwd, real_src)
1162 pwd = pwd[len(real_src):]
1163 // guard against xrealwd returning the directory without the trailing /
1164 pwd = strings.TrimPrefix(pwd, "/")
1169 // Install installs the list of packages named on the command line.
1173 if flag.NArg() == 0 {
1174 install(defaulttarg())
1177 for _, arg := range flag.Args() {
1182 // Clean deletes temporary objects.
1188 // Banner prints the 'now you've installed Go' banner.
1194 xprintf("Installed Go for %s/%s in %s\n", goos, goarch, goroot)
1195 xprintf("Installed commands in %s\n", gobin)
1197 if !xsamefile(goroot_final, goroot) {
1198 // If the files are to be moved, don't check that gobin
1199 // is on PATH; assume they know what they are doing.
1200 } else if gohostos == "plan9" {
1201 // Check that gobin is bound before /bin.
1202 pid := strings.Replace(readfile("#c/pid"), " ", "", -1)
1203 ns := fmt.Sprintf("/proc/%s/ns", pid)
1204 if !strings.Contains(readfile(ns), fmt.Sprintf("bind -b %s /bin", gobin)) {
1205 xprintf("*** You need to bind %s before /bin.\n", gobin)
1208 // Check that gobin appears in $PATH.
1210 if gohostos == "windows" {
1213 if !strings.Contains(pathsep+os.Getenv("PATH")+pathsep, pathsep+gobin+pathsep) {
1214 xprintf("*** You need to add %s to your PATH.\n", gobin)
1218 if !xsamefile(goroot_final, goroot) {
1220 "The binaries expect %s to be copied or moved to %s\n",
1221 goroot, goroot_final)
1225 // Version prints the Go version.
1228 xprintf("%s\n", findgoversion())
1231 // cmdlist lists all supported platforms.
1233 jsonFlag := flag.Bool("json", false, "produce JSON output")
1237 for p := range cgoEnabled {
1238 plats = append(plats, p)
1243 for _, p := range plats {
1249 type jsonResult struct {
1254 var results []jsonResult
1255 for _, p := range plats {
1256 fields := strings.Split(p, "/")
1257 results = append(results, jsonResult{
1260 CgoSupported: cgoEnabled[p]})
1262 out, err := json.MarshalIndent(results, "", "\t")
1264 fatal("json marshal error: %v", err)
1266 if _, err := os.Stdout.Write(out); err != nil {
1267 fatal("write failed: %v", err)