github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/cmd/dist/build.c (about)

     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.
     4  
     5  #include "a.h"
     6  #include "arg.h"
     7  
     8  /*
     9   * Initialization for any invocation.
    10   */
    11  
    12  // The usual variables.
    13  char *goarch;
    14  char *gobin;
    15  char *gohostarch;
    16  char *gohostchar;
    17  char *gohostos;
    18  char *goos;
    19  char *goarm;
    20  char *go386;
    21  char *goroot = GOROOT_FINAL;
    22  char *goroot_final = GOROOT_FINAL;
    23  char *goextlinkenabled = "";
    24  char *workdir;
    25  char *tooldir;
    26  char *gochar;
    27  char *goversion;
    28  char *slash;	// / for unix, \ for windows
    29  char *defaultcc;
    30  char *defaultcflags;
    31  char *defaultldflags;
    32  char *defaultcxxtarget;
    33  char *defaultcctarget;
    34  bool	rebuildall;
    35  bool defaultclang;
    36  
    37  static bool shouldbuild(char*, char*);
    38  static void copy(char*, char*, int);
    39  static void dopack(char*, char*, char**, int);
    40  static char *findgoversion(void);
    41  
    42  // The known architecture letters.
    43  static char *gochars = "5668";
    44  
    45  // The known architectures.
    46  static char *okgoarch[] = {
    47  	// same order as gochars
    48  	"arm",
    49  	"amd64",
    50  	"amd64p32",
    51  	"386",
    52  };
    53  
    54  // The known operating systems.
    55  static char *okgoos[] = {
    56  	"darwin",
    57  	"dragonfly",
    58  	"linux",
    59  	"solaris",
    60  	"freebsd",
    61  	"nacl",
    62  	"netbsd",
    63  	"openbsd",
    64  	"plan9",
    65  	"windows",
    66  };
    67  
    68  static void rmworkdir(void);
    69  
    70  // find reports the first index of p in l[0:n], or else -1.
    71  int
    72  find(char *p, char **l, int n)
    73  {
    74  	int i;
    75  
    76  	for(i=0; i<n; i++)
    77  		if(streq(p, l[i]))
    78  			return i;
    79  	return -1;
    80  }
    81  
    82  // init handles initialization of the various global state, like goroot and goarch.
    83  void
    84  init(void)
    85  {
    86  	char *p;
    87  	int i;
    88  	Buf b;
    89  
    90  	binit(&b);
    91  
    92  	xgetenv(&b, "GOROOT");
    93  	if(b.len > 0) {
    94  		// if not "/", then strip trailing path separator
    95  		if(b.len >= 2 && b.p[b.len - 1] == slash[0])
    96  			b.len--;
    97  		goroot = btake(&b);
    98  	}
    99  
   100  	xgetenv(&b, "GOBIN");
   101  	if(b.len == 0)
   102  		bprintf(&b, "%s%sbin", goroot, slash);
   103  	gobin = btake(&b);
   104  
   105  	xgetenv(&b, "GOOS");
   106  	if(b.len == 0)
   107  		bwritestr(&b, gohostos);
   108  	goos = btake(&b);
   109  	if(find(goos, okgoos, nelem(okgoos)) < 0)
   110  		fatal("unknown $GOOS %s", goos);
   111  
   112  	xgetenv(&b, "GOARM");
   113  	if(b.len == 0)
   114  		bwritestr(&b, xgetgoarm());
   115  	goarm = btake(&b);
   116  
   117  	xgetenv(&b, "GO386");
   118  	if(b.len == 0) {
   119  		if(cansse2())
   120  			bwritestr(&b, "sse2");
   121  		else
   122  			bwritestr(&b, "387");
   123  	}
   124  	go386 = btake(&b);
   125  
   126  	p = bpathf(&b, "%s/include/u.h", goroot);
   127  	if(!isfile(p)) {
   128  		fatal("$GOROOT is not set correctly or not exported\n"
   129  			"\tGOROOT=%s\n"
   130  			"\t%s does not exist", goroot, p);
   131  	}
   132  
   133  	xgetenv(&b, "GOHOSTARCH");
   134  	if(b.len > 0)
   135  		gohostarch = btake(&b);
   136  
   137  	i = find(gohostarch, okgoarch, nelem(okgoarch));
   138  	if(i < 0)
   139  		fatal("unknown $GOHOSTARCH %s", gohostarch);
   140  	bprintf(&b, "%c", gochars[i]);
   141  	gohostchar = btake(&b);
   142  
   143  	xgetenv(&b, "GOARCH");
   144  	if(b.len == 0)
   145  		bwritestr(&b, gohostarch);
   146  	goarch = btake(&b);
   147  	i = find(goarch, okgoarch, nelem(okgoarch));
   148  	if(i < 0)
   149  		fatal("unknown $GOARCH %s", goarch);
   150  	bprintf(&b, "%c", gochars[i]);
   151  	gochar = btake(&b);
   152  
   153  	xgetenv(&b, "GO_EXTLINK_ENABLED");
   154  	if(b.len > 0) {
   155  		goextlinkenabled = btake(&b);
   156  		if(!streq(goextlinkenabled, "0") && !streq(goextlinkenabled, "1"))
   157  			fatal("unknown $GO_EXTLINK_ENABLED %s", goextlinkenabled);
   158  	}
   159  	
   160  	xgetenv(&b, "CC");
   161  	if(b.len == 0) {
   162  		// Use clang on OS X, because gcc is deprecated there.
   163  		// Xcode for OS X 10.9 Mavericks will ship a fake "gcc" binary that
   164  		// actually runs clang. We prepare different command
   165  		// lines for the two binaries, so it matters what we call it.
   166  		// See golang.org/issue/5822.
   167  		if(defaultclang)
   168  			bprintf(&b, "clang");
   169  		else
   170  			bprintf(&b, "gcc");
   171  	}
   172  	defaultcc = btake(&b);
   173  
   174  	xgetenv(&b, "CFLAGS");
   175  	defaultcflags = btake(&b);
   176  
   177  	xgetenv(&b, "LDFLAGS");
   178  	defaultldflags = btake(&b);
   179  
   180  	xgetenv(&b, "CC_FOR_TARGET");
   181  	if(b.len == 0) {
   182  		bprintf(&b, defaultcc);
   183  	}
   184  	defaultcctarget = btake(&b);
   185  
   186  	xgetenv(&b, "CXX_FOR_TARGET");
   187  	if(b.len == 0) {
   188  		xgetenv(&b, "CXX");
   189  		if(b.len == 0) {
   190  			if(defaultclang)
   191  				bprintf(&b, "clang++");
   192  			else
   193  				bprintf(&b, "g++");
   194  		}
   195  	}
   196  	defaultcxxtarget = btake(&b);
   197  
   198  	xsetenv("GOROOT", goroot);
   199  	xsetenv("GOARCH", goarch);
   200  	xsetenv("GOOS", goos);
   201  	xsetenv("GOARM", goarm);
   202  	xsetenv("GO386", go386);
   203  
   204  	// Make the environment more predictable.
   205  	xsetenv("LANG", "C");
   206  	xsetenv("LANGUAGE", "en_US.UTF8");
   207  
   208  	goversion = findgoversion();
   209  
   210  	workdir = xworkdir();
   211  	xatexit(rmworkdir);
   212  
   213  	bpathf(&b, "%s/pkg/tool/%s_%s", goroot, gohostos, gohostarch);
   214  	tooldir = btake(&b);
   215  
   216  	bfree(&b);
   217  }
   218  
   219  // rmworkdir deletes the work directory.
   220  static void
   221  rmworkdir(void)
   222  {
   223  	if(vflag > 1)
   224  		errprintf("rm -rf %s\n", workdir);
   225  	xremoveall(workdir);
   226  }
   227  
   228  // Remove trailing spaces.
   229  static void
   230  chomp(Buf *b)
   231  {
   232  	int c;
   233  
   234  	while(b->len > 0 && ((c=b->p[b->len-1]) == ' ' || c == '\t' || c == '\r' || c == '\n'))
   235  		b->len--;
   236  }
   237  
   238  
   239  // findgoversion determines the Go version to use in the version string.
   240  static char*
   241  findgoversion(void)
   242  {
   243  	char *tag, *rev, *p;
   244  	int i, nrev;
   245  	Buf b, path, bmore, branch;
   246  	Vec tags;
   247  
   248  	binit(&b);
   249  	binit(&path);
   250  	binit(&bmore);
   251  	binit(&branch);
   252  	vinit(&tags);
   253  
   254  	// The $GOROOT/VERSION file takes priority, for distributions
   255  	// without the Mercurial repo.
   256  	bpathf(&path, "%s/VERSION", goroot);
   257  	if(isfile(bstr(&path))) {
   258  		readfile(&b, bstr(&path));
   259  		chomp(&b);
   260  		// Commands such as "dist version > VERSION" will cause
   261  		// the shell to create an empty VERSION file and set dist's
   262  		// stdout to its fd. dist in turn looks at VERSION and uses
   263  		// its content if available, which is empty at this point.
   264  		if(b.len > 0)
   265  			goto done;
   266  	}
   267  
   268  	// The $GOROOT/VERSION.cache file is a cache to avoid invoking
   269  	// hg every time we run this command.  Unlike VERSION, it gets
   270  	// deleted by the clean command.
   271  	bpathf(&path, "%s/VERSION.cache", goroot);
   272  	if(isfile(bstr(&path))) {
   273  		readfile(&b, bstr(&path));
   274  		chomp(&b);
   275  		goto done;
   276  	}
   277  
   278  	// Otherwise, use Mercurial.
   279  	// What is the current branch?
   280  	run(&branch, goroot, CheckExit, "hg", "identify", "-b", nil);
   281  	chomp(&branch);
   282  
   283  	// What are the tags along the current branch?
   284  	tag = "devel";
   285  	rev = ".";
   286  	run(&b, goroot, CheckExit, "hg", "log", "-b", bstr(&branch), "-r", ".:0", "--template", "{tags} + ", nil);
   287  	splitfields(&tags, bstr(&b));
   288  	nrev = 0;
   289  	for(i=0; i<tags.len; i++) {
   290  		p = tags.p[i];
   291  		if(streq(p, "+"))
   292  			nrev++;
   293  		// Only show the beta tag for the exact revision.
   294  		if(hasprefix(p, "go") && (!contains(p, "beta") || nrev == 0)) {
   295  			tag = xstrdup(p);
   296  			// If this tag matches the current checkout
   297  			// exactly (no "+" yet), don't show extra
   298  			// revision information.
   299  			if(nrev == 0)
   300  				rev = "";
   301  			break;
   302  		}
   303  	}
   304  
   305  	if(tag[0] == '\0') {
   306  		// Did not find a tag; use branch name.
   307  		bprintf(&b, "branch.%s", bstr(&branch));
   308  		tag = btake(&b);
   309  	}
   310  
   311  	if(rev[0]) {
   312  		// Tag is before the revision we're building.
   313  		// Add extra information.
   314  		run(&bmore, goroot, CheckExit, "hg", "log", "--template", " +{node|short} {date|date}", "-r", rev, nil);
   315  		chomp(&bmore);
   316  	}
   317  
   318  	bprintf(&b, "%s", tag);
   319  	if(bmore.len > 0)
   320  		bwriteb(&b, &bmore);
   321  
   322  	// Cache version.
   323  	writefile(&b, bstr(&path), 0);
   324  
   325  done:
   326  	p = btake(&b);
   327  
   328  
   329  	bfree(&b);
   330  	bfree(&path);
   331  	bfree(&bmore);
   332  	bfree(&branch);
   333  	vfree(&tags);
   334  
   335  	return p;
   336  }
   337  
   338  /*
   339   * Initial tree setup.
   340   */
   341  
   342  // The old tools that no longer live in $GOBIN or $GOROOT/bin.
   343  static char *oldtool[] = {
   344  	"5a", "5c", "5g", "5l",
   345  	"6a", "6c", "6g", "6l",
   346  	"8a", "8c", "8g", "8l",
   347  	"6cov",
   348  	"6nm",
   349  	"6prof",
   350  	"cgo",
   351  	"ebnflint",
   352  	"goapi",
   353  	"gofix",
   354  	"goinstall",
   355  	"gomake",
   356  	"gopack",
   357  	"gopprof",
   358  	"gotest",
   359  	"gotype",
   360  	"govet",
   361  	"goyacc",
   362  	"quietgcc",
   363  };
   364  
   365  // Unreleased directories (relative to $GOROOT) that should
   366  // not be in release branches.
   367  static char *unreleased[] = {
   368  	"src/cmd/link",
   369  	"src/pkg/debug/goobj",
   370  	"src/pkg/old",
   371  };
   372  
   373  // setup sets up the tree for the initial build.
   374  static void
   375  setup(void)
   376  {
   377  	int i;
   378  	Buf b;
   379  	char *p;
   380  
   381  	binit(&b);
   382  
   383  	// Create bin directory.
   384  	p = bpathf(&b, "%s/bin", goroot);
   385  	if(!isdir(p))
   386  		xmkdir(p);
   387  
   388  	// Create package directory.
   389  	p = bpathf(&b, "%s/pkg", goroot);
   390  	if(!isdir(p))
   391  		xmkdir(p);
   392  	p = bpathf(&b, "%s/pkg/%s_%s", goroot, gohostos, gohostarch);
   393  	if(rebuildall)
   394  		xremoveall(p);
   395  	xmkdirall(p);
   396  	if(!streq(goos, gohostos) || !streq(goarch, gohostarch)) {
   397  		p = bpathf(&b, "%s/pkg/%s_%s", goroot, goos, goarch);
   398  		if(rebuildall)
   399  			xremoveall(p);
   400  		xmkdirall(p);
   401  	}
   402  
   403  	// Create object directory.
   404  	// We keep it in pkg/ so that all the generated binaries
   405  	// are in one tree.  If pkg/obj/libgc.a exists, it is a dreg from
   406  	// before we used subdirectories of obj.  Delete all of obj
   407  	// to clean up.
   408  	bpathf(&b, "%s/pkg/obj/libgc.a", goroot);
   409  	if(isfile(bstr(&b)))
   410  		xremoveall(bpathf(&b, "%s/pkg/obj", goroot));
   411  	p = bpathf(&b, "%s/pkg/obj/%s_%s", goroot, gohostos, gohostarch);
   412  	if(rebuildall)
   413  		xremoveall(p);
   414  	xmkdirall(p);
   415  
   416  	// Create tool directory.
   417  	// We keep it in pkg/, just like the object directory above.
   418  	if(rebuildall)
   419  		xremoveall(tooldir);
   420  	xmkdirall(tooldir);
   421  
   422  	// Remove tool binaries from before the tool/gohostos_gohostarch
   423  	xremoveall(bpathf(&b, "%s/bin/tool", goroot));
   424  
   425  	// Remove old pre-tool binaries.
   426  	for(i=0; i<nelem(oldtool); i++)
   427  		xremove(bpathf(&b, "%s/bin/%s", goroot, oldtool[i]));
   428  
   429  	// If $GOBIN is set and has a Go compiler, it must be cleaned.
   430  	for(i=0; gochars[i]; i++) {
   431  		if(isfile(bprintf(&b, "%s%s%c%s", gobin, slash, gochars[i], "g"))) {
   432  			for(i=0; i<nelem(oldtool); i++)
   433  				xremove(bprintf(&b, "%s%s%s", gobin, slash, oldtool[i]));
   434  			break;
   435  		}
   436  	}
   437  
   438  	// For release, make sure excluded things are excluded.
   439  	if(hasprefix(goversion, "release.") || (hasprefix(goversion, "go") && !contains(goversion, "beta"))) {
   440  		for(i=0; i<nelem(unreleased); i++)
   441  			if(isdir(bpathf(&b, "%s/%s", goroot, unreleased[i])))
   442  				fatal("%s should not exist in release build", bstr(&b));
   443  	}
   444  
   445  	bfree(&b);
   446  }
   447  
   448  /*
   449   * C library and tool building
   450   */
   451  
   452  // gccargs is the gcc command line to use for compiling a single C file.
   453  static char *proto_gccargs[] = {
   454  	"-Wall",
   455  	// native Plan 9 compilers don't like non-standard prototypes
   456  	// so let gcc catch them.
   457  	"-Wstrict-prototypes",
   458  	"-Wextra",
   459  	"-Wunused",
   460  	"-Wno-sign-compare",
   461  	"-Wno-missing-braces",
   462  	"-Wno-parentheses",
   463  	"-Wno-unknown-pragmas",
   464  	"-Wno-switch",
   465  	"-Wno-comment",
   466  	"-Wno-missing-field-initializers",
   467  	"-Werror",
   468  	"-fno-common",
   469  	"-ggdb",
   470  	"-pipe",
   471  };
   472  
   473  // gccargs2 is the second part of gccargs.
   474  // it is used if the environment isn't defining CFLAGS.
   475  static char *proto_gccargs2[] = {
   476  	// on older versions of GCC, -Wuninitialized is not supported
   477  	// without -O, so put it here together with -O settings in case
   478  	// the user's $CFLAGS doesn't include -O.
   479  	"-Wuninitialized",
   480  #if defined(__NetBSD__) && defined(__arm__)
   481  	// GCC 4.5.4 (NetBSD nb1 20120916) on ARM is known to mis-optimize gc/mparith3.c
   482  	// Fix available at http://patchwork.ozlabs.org/patch/64562/.
   483  	"-O1",
   484  #else
   485  	"-O2",
   486  #endif
   487  };
   488  
   489  static Vec gccargs, ldargs;
   490  
   491  // deptab lists changes to the default dependencies for a given prefix.
   492  // deps ending in /* read the whole directory; deps beginning with -
   493  // exclude files with that prefix.
   494  static struct {
   495  	char *prefix;  // prefix of target
   496  	char *dep[20];  // dependency tweaks for targets with that prefix
   497  } deptab[] = {
   498  	{"lib9", {
   499  		"$GOROOT/include/u.h",
   500  		"$GOROOT/include/utf.h",
   501  		"$GOROOT/include/fmt.h",
   502  		"$GOROOT/include/libc.h",
   503  		"fmt/*",
   504  		"utf/*",
   505  	}},
   506  	{"libbio", {
   507  		"$GOROOT/include/u.h",
   508  		"$GOROOT/include/utf.h",
   509  		"$GOROOT/include/fmt.h",
   510  		"$GOROOT/include/libc.h",
   511  		"$GOROOT/include/bio.h",
   512  	}},
   513  	{"liblink", {
   514  		"$GOROOT/include/u.h",
   515  		"$GOROOT/include/utf.h",
   516  		"$GOROOT/include/fmt.h",
   517  		"$GOROOT/include/libc.h",
   518  		"$GOROOT/include/bio.h",
   519  		"$GOROOT/include/ar.h",
   520  		"$GOROOT/include/link.h",
   521  		"anames5.c",
   522  		"anames6.c",
   523  		"anames8.c",
   524  	}},
   525  	{"cmd/cc", {
   526  		"-pgen.c",
   527  		"-pswt.c",
   528  	}},
   529  	{"cmd/gc", {
   530  		"-cplx.c",
   531  		"-pgen.c",
   532  		"-plive.c",
   533  		"-popt.c",
   534  		"-y1.tab.c",  // makefile dreg
   535  		"opnames.h",
   536  	}},
   537  	{"cmd/5c", {
   538  		"../cc/pgen.c",
   539  		"../cc/pswt.c",
   540  		"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a",
   541  	}},
   542  	{"cmd/6c", {
   543  		"../cc/pgen.c",
   544  		"../cc/pswt.c",
   545  		"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a",
   546  	}},
   547  	{"cmd/8c", {
   548  		"../cc/pgen.c",
   549  		"../cc/pswt.c",
   550  		"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a",
   551  	}},
   552  	{"cmd/5g", {
   553  		"../gc/cplx.c",
   554  		"../gc/pgen.c",
   555  		"../gc/plive.c",
   556  		"../gc/popt.c",
   557  		"../gc/popt.h",
   558  		"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libgc.a",
   559  	}},
   560  	{"cmd/6g", {
   561  		"../gc/cplx.c",
   562  		"../gc/pgen.c",
   563  		"../gc/plive.c",
   564  		"../gc/popt.c",
   565  		"../gc/popt.h",
   566  		"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libgc.a",
   567  	}},
   568  	{"cmd/8g", {
   569  		"../gc/cplx.c",
   570  		"../gc/pgen.c",
   571  		"../gc/plive.c",
   572  		"../gc/popt.c",
   573  		"../gc/popt.h",
   574  		"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libgc.a",
   575  	}},
   576  	{"cmd/5l", {
   577  		"../ld/*",
   578  	}},
   579  	{"cmd/6l", {
   580  		"../ld/*",
   581  	}},
   582  	{"cmd/8l", {
   583  		"../ld/*",
   584  	}},
   585  	{"cmd/go", {
   586  		"zdefaultcc.go",
   587  	}},
   588  	{"cmd/", {
   589  		"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/liblink.a",
   590  		"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libbio.a",
   591  		"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/lib9.a",
   592  	}},
   593  	{"pkg/runtime", {
   594  		"zaexperiment.h", // must sort above zasm
   595  		"zasm_$GOOS_$GOARCH.h",
   596  		"zsys_$GOOS_$GOARCH.s",
   597  		"zgoarch_$GOARCH.go",
   598  		"zgoos_$GOOS.go",
   599  		"zruntime_defs_$GOOS_$GOARCH.go",
   600  		"zversion.go",
   601  	}},
   602  };
   603  
   604  // depsuffix records the allowed suffixes for source files.
   605  char *depsuffix[] = {
   606  	".c",
   607  	".h",
   608  	".s",
   609  	".go",
   610  	".goc",
   611  };
   612  
   613  // gentab records how to generate some trivial files.
   614  static struct {
   615  	char *nameprefix;
   616  	void (*gen)(char*, char*);
   617  } gentab[] = {
   618  	{"opnames.h", gcopnames},
   619  	{"anames5.c", mkanames},
   620  	{"anames6.c", mkanames},
   621  	{"anames8.c", mkanames},
   622  	{"zasm_", mkzasm},
   623  	{"zdefaultcc.go", mkzdefaultcc},
   624  	{"zsys_", mkzsys},
   625  	{"zgoarch_", mkzgoarch},
   626  	{"zgoos_", mkzgoos},
   627  	{"zruntime_defs_", mkzruntimedefs},
   628  	{"zversion.go", mkzversion},
   629  	{"zaexperiment.h", mkzexperiment},
   630  
   631  	// not generated anymore, but delete the file if we see it
   632  	{"enam.c", nil},
   633  };
   634  
   635  // install installs the library, package, or binary associated with dir,
   636  // which is relative to $GOROOT/src.
   637  static void
   638  install(char *dir)
   639  {
   640  	char *name, *p, *elem, *prefix, *exe;
   641  	bool islib, ispkg, isgo, stale, ispackcmd;
   642  	Buf b, b1, path;
   643  	Vec compile, files, link, go, missing, clean, lib, extra;
   644  	Time ttarg, t;
   645  	int i, j, k, n, doclean, targ;
   646  
   647  	if(vflag) {
   648  		if(!streq(goos, gohostos) || !streq(goarch, gohostarch))
   649  			errprintf("%s (%s/%s)\n", dir, goos, goarch);
   650  		else
   651  			errprintf("%s\n", dir);
   652  	}
   653  
   654  	binit(&b);
   655  	binit(&b1);
   656  	binit(&path);
   657  	vinit(&compile);
   658  	vinit(&files);
   659  	vinit(&link);
   660  	vinit(&go);
   661  	vinit(&missing);
   662  	vinit(&clean);
   663  	vinit(&lib);
   664  	vinit(&extra);
   665  
   666  
   667  	// path = full path to dir.
   668  	bpathf(&path, "%s/src/%s", goroot, dir);
   669  	name = lastelem(dir);
   670  
   671  	// For misc/prof, copy into the tool directory and we're done.
   672  	if(hasprefix(dir, "misc/")) {
   673  		copy(bpathf(&b, "%s/%s", tooldir, name),
   674  			bpathf(&b1, "%s/misc/%s", goroot, name), 1);
   675  		goto out;
   676  	}
   677  
   678  	// set up gcc command line on first run.
   679  	if(gccargs.len == 0) {
   680  		bprintf(&b, "%s %s", defaultcc, defaultcflags);
   681  		splitfields(&gccargs, bstr(&b));
   682  		for(i=0; i<nelem(proto_gccargs); i++)
   683  			vadd(&gccargs, proto_gccargs[i]);
   684  		if(defaultcflags[0] == '\0') {
   685  			for(i=0; i<nelem(proto_gccargs2); i++)
   686  				vadd(&gccargs, proto_gccargs2[i]);
   687  		}
   688  		if(contains(gccargs.p[0], "clang")) {
   689  			// disable ASCII art in clang errors, if possible
   690  			vadd(&gccargs, "-fno-caret-diagnostics");
   691  			// clang is too smart about unused command-line arguments
   692  			vadd(&gccargs, "-Qunused-arguments");
   693  		}
   694  		// disable word wrapping in error messages
   695  		vadd(&gccargs, "-fmessage-length=0");
   696  		if(streq(gohostos, "darwin")) {
   697  			// golang.org/issue/5261
   698  			vadd(&gccargs, "-mmacosx-version-min=10.6");
   699  		}
   700  	}
   701  	if(ldargs.len == 0 && defaultldflags[0] != '\0') {
   702  		bprintf(&b, "%s", defaultldflags);
   703  		splitfields(&ldargs, bstr(&b));
   704  	}
   705  
   706  	islib = hasprefix(dir, "lib") || streq(dir, "cmd/cc") || streq(dir, "cmd/gc");
   707  	ispkg = hasprefix(dir, "pkg");
   708  	isgo = ispkg || streq(dir, "cmd/go") || streq(dir, "cmd/cgo");
   709  
   710  	exe = "";
   711  	if(streq(gohostos, "windows"))
   712  		exe = ".exe";
   713  
   714  	// Start final link command line.
   715  	// Note: code below knows that link.p[targ] is the target.
   716  	ispackcmd = 0;
   717  	if(islib) {
   718  		// C library.
   719  		vadd(&link, "ar");
   720  		if(streq(gohostos, "plan9"))
   721  			vadd(&link, "rc");
   722  		else
   723  			vadd(&link, "rsc");
   724  		prefix = "";
   725  		if(!hasprefix(name, "lib"))
   726  			prefix = "lib";
   727  		targ = link.len;
   728  		vadd(&link, bpathf(&b, "%s/pkg/obj/%s_%s/%s%s.a", goroot, gohostos, gohostarch, prefix, name));
   729  	} else if(ispkg) {
   730  		// Go library (package).
   731  		ispackcmd = 1;
   732  		vadd(&link, "pack"); // program name - unused here, but all the other cases record one
   733  		p = bprintf(&b, "%s/pkg/%s_%s/%s", goroot, goos, goarch, dir+4);
   734  		*xstrrchr(p, '/') = '\0';
   735  		xmkdirall(p);
   736  		targ = link.len;
   737  		vadd(&link, bpathf(&b, "%s/pkg/%s_%s/%s.a", goroot, goos, goarch, dir+4));
   738  	} else if(streq(dir, "cmd/go") || streq(dir, "cmd/cgo")) {
   739  		// Go command.
   740  		vadd(&link, bpathf(&b, "%s/%sl", tooldir, gochar));
   741  		vadd(&link, "-o");
   742  		elem = name;
   743  		if(streq(elem, "go"))
   744  			elem = "go_bootstrap";
   745  		targ = link.len;
   746  		vadd(&link, bpathf(&b, "%s/%s%s", tooldir, elem, exe));
   747  	} else {
   748  		// C command. Use gccargs and ldargs.
   749  		if(streq(gohostos, "plan9")) {
   750  			vadd(&link, bprintf(&b, "%sl", gohostchar));
   751  			vadd(&link, "-o");
   752  			targ = link.len;
   753  			vadd(&link, bpathf(&b, "%s/%s", tooldir, name));
   754  		} else {
   755  			vcopy(&link, gccargs.p, gccargs.len);
   756  			vcopy(&link, ldargs.p, ldargs.len);
   757  			if(sflag)
   758  				vadd(&link, "-static");
   759  			vadd(&link, "-o");
   760  			targ = link.len;
   761  			vadd(&link, bpathf(&b, "%s/%s%s", tooldir, name, exe));
   762  			if(streq(gohostarch, "amd64"))
   763  				vadd(&link, "-m64");
   764  			else if(streq(gohostarch, "386"))
   765  				vadd(&link, "-m32");
   766  		}
   767  	}
   768  	ttarg = mtime(link.p[targ]);
   769  
   770  	// Gather files that are sources for this target.
   771  	// Everything in that directory, and any target-specific
   772  	// additions.
   773  	xreaddir(&files, bstr(&path));
   774  
   775  	// Remove files beginning with . or _,
   776  	// which are likely to be editor temporary files.
   777  	// This is the same heuristic build.ScanDir uses.
   778  	// There do exist real C files beginning with _,
   779  	// so limit that check to just Go files.
   780  	n = 0;
   781  	for(i=0; i<files.len; i++) {
   782  		p = files.p[i];
   783  		if(hasprefix(p, ".") || (hasprefix(p, "_") && hassuffix(p, ".go")))
   784  			xfree(p);
   785  		else
   786  			files.p[n++] = p;
   787  	}
   788  	files.len = n;
   789  
   790  	for(i=0; i<nelem(deptab); i++) {
   791  		if(streq(dir, deptab[i].prefix) ||
   792  		   (hassuffix(deptab[i].prefix, "/") && hasprefix(dir, deptab[i].prefix))) {
   793  			for(j=0; (p=deptab[i].dep[j])!=nil; j++) {
   794  				breset(&b1);
   795  				bwritestr(&b1, p);
   796  				bsubst(&b1, "$GOROOT", goroot);
   797  				bsubst(&b1, "$GOOS", goos);
   798  				bsubst(&b1, "$GOARCH", goarch);
   799  				bsubst(&b1, "$GOHOSTOS", gohostos);
   800  				bsubst(&b1, "$GOHOSTARCH", gohostarch);
   801  				p = bstr(&b1);
   802  				if(hassuffix(p, ".a")) {
   803  					vadd(&lib, bpathf(&b, "%s", p));
   804  					continue;
   805  				}
   806  				if(hassuffix(p, "/*")) {
   807  					bpathf(&b, "%s/%s", bstr(&path), p);
   808  					b.len -= 2;
   809  					xreaddir(&extra, bstr(&b));
   810  					bprintf(&b, "%s", p);
   811  					b.len -= 2;
   812  					for(k=0; k<extra.len; k++)
   813  						vadd(&files, bpathf(&b1, "%s/%s", bstr(&b), extra.p[k]));
   814  					continue;
   815  				}
   816  				if(hasprefix(p, "-")) {
   817  					p++;
   818  					n = 0;
   819  					for(k=0; k<files.len; k++) {
   820  						if(hasprefix(files.p[k], p))
   821  							xfree(files.p[k]);
   822  						else
   823  							files.p[n++] = files.p[k];
   824  					}
   825  					files.len = n;
   826  					continue;
   827  				}
   828  				vadd(&files, p);
   829  			}
   830  		}
   831  	}
   832  	vuniq(&files);
   833  
   834  	// Convert to absolute paths.
   835  	for(i=0; i<files.len; i++) {
   836  		if(!isabs(files.p[i])) {
   837  			bpathf(&b, "%s/%s", bstr(&path), files.p[i]);
   838  			xfree(files.p[i]);
   839  			files.p[i] = btake(&b);
   840  		}
   841  	}
   842  
   843  	// Is the target up-to-date?
   844  	stale = rebuildall;
   845  	n = 0;
   846  	for(i=0; i<files.len; i++) {
   847  		p = files.p[i];
   848  		for(j=0; j<nelem(depsuffix); j++)
   849  			if(hassuffix(p, depsuffix[j]))
   850  				goto ok;
   851  		xfree(files.p[i]);
   852  		continue;
   853  	ok:
   854  		t = mtime(p);
   855  		if(t != 0 && !hassuffix(p, ".a") && !shouldbuild(p, dir)) {
   856  			xfree(files.p[i]);
   857  			continue;
   858  		}
   859  		if(hassuffix(p, ".go"))
   860  			vadd(&go, p);
   861  		if(t > ttarg)
   862  			stale = 1;
   863  		if(t == 0) {
   864  			vadd(&missing, p);
   865  			files.p[n++] = files.p[i];
   866  			continue;
   867  		}
   868  		files.p[n++] = files.p[i];
   869  	}
   870  	files.len = n;
   871  
   872  	// If there are no files to compile, we're done.
   873  	if(files.len == 0)
   874  		goto out;
   875  	
   876  	for(i=0; i<lib.len && !stale; i++)
   877  		if(mtime(lib.p[i]) > ttarg)
   878  			stale = 1;
   879  
   880  	if(!stale)
   881  		goto out;
   882  
   883  	// For package runtime, copy some files into the work space.
   884  	if(streq(dir, "pkg/runtime")) {
   885  		copy(bpathf(&b, "%s/arch_GOARCH.h", workdir),
   886  			bpathf(&b1, "%s/arch_%s.h", bstr(&path), goarch), 0);
   887  		copy(bpathf(&b, "%s/defs_GOOS_GOARCH.h", workdir),
   888  			bpathf(&b1, "%s/defs_%s_%s.h", bstr(&path), goos, goarch), 0);
   889  		p = bpathf(&b1, "%s/signal_%s_%s.h", bstr(&path), goos, goarch);
   890  		if(isfile(p))
   891  			copy(bpathf(&b, "%s/signal_GOOS_GOARCH.h", workdir), p, 0);
   892  		copy(bpathf(&b, "%s/os_GOOS.h", workdir),
   893  			bpathf(&b1, "%s/os_%s.h", bstr(&path), goos), 0);
   894  		copy(bpathf(&b, "%s/signals_GOOS.h", workdir),
   895  			bpathf(&b1, "%s/signals_%s.h", bstr(&path), goos), 0);
   896  	}
   897  
   898  	// Generate any missing files; regenerate existing ones.
   899  	for(i=0; i<files.len; i++) {
   900  		p = files.p[i];
   901  		elem = lastelem(p);
   902  		for(j=0; j<nelem(gentab); j++) {
   903  			if(gentab[j].gen == nil)
   904  				continue;
   905  			if(hasprefix(elem, gentab[j].nameprefix)) {
   906  				if(vflag > 1)
   907  					errprintf("generate %s\n", p);
   908  				gentab[j].gen(bstr(&path), p);
   909  				// Do not add generated file to clean list.
   910  				// In pkg/runtime, we want to be able to
   911  				// build the package with the go tool,
   912  				// and it assumes these generated files already
   913  				// exist (it does not know how to build them).
   914  				// The 'clean' command can remove
   915  				// the generated files.
   916  				goto built;
   917  			}
   918  		}
   919  		// Did not rebuild p.
   920  		if(find(p, missing.p, missing.len) >= 0)
   921  			fatal("missing file %s", p);
   922  	built:;
   923  	}
   924  
   925  	// One more copy for package runtime.
   926  	// The last batch was required for the generators.
   927  	// This one is generated.
   928  	if(streq(dir, "pkg/runtime")) {
   929  		copy(bpathf(&b, "%s/zasm_GOOS_GOARCH.h", workdir),
   930  			bpathf(&b1, "%s/zasm_%s_%s.h", bstr(&path), goos, goarch), 0);
   931  	}
   932  
   933  	// Generate .c files from .goc files.
   934  	if(streq(dir, "pkg/runtime")) {
   935  		for(i=0; i<files.len; i++) {
   936  			p = files.p[i];
   937  			if(!hassuffix(p, ".goc"))
   938  				continue;
   939  			// b = path/zp but with _goos_goarch.c instead of .goc
   940  			bprintf(&b, "%s%sz%s", bstr(&path), slash, lastelem(p));
   941  			b.len -= 4;
   942  			bwritef(&b, "_%s_%s.c", goos, goarch);
   943  			goc2c(p, bstr(&b));
   944  			vadd(&files, bstr(&b));
   945  		}
   946  		vuniq(&files);
   947  	}
   948  
   949  	if((!streq(goos, gohostos) || !streq(goarch, gohostarch)) && isgo) {
   950  		// We've generated the right files; the go command can do the build.
   951  		if(vflag > 1)
   952  			errprintf("skip build for cross-compile %s\n", dir);
   953  		goto nobuild;
   954  	}
   955  
   956  	// Compile the files.
   957  	for(i=0; i<files.len; i++) {
   958  		if(!hassuffix(files.p[i], ".c") && !hassuffix(files.p[i], ".s"))
   959  			continue;
   960  		name = lastelem(files.p[i]);
   961  
   962  		vreset(&compile);
   963  		if(!isgo) {
   964  			// C library or tool.
   965  			if(streq(gohostos, "plan9")) {
   966  				vadd(&compile, bprintf(&b, "%sc", gohostchar));
   967  				vadd(&compile, "-FTVwp");
   968  				vadd(&compile, "-DPLAN9");
   969  				vadd(&compile, "-D__STDC__=1");
   970  				vadd(&compile, "-D__SIZE_TYPE__=ulong"); // for GNU Bison
   971  				vadd(&compile, bpathf(&b, "-I%s/include/plan9", goroot));
   972  				vadd(&compile, bpathf(&b, "-I%s/include/plan9/%s", goroot, gohostarch));
   973  			} else {
   974  				vcopy(&compile, gccargs.p, gccargs.len);
   975  				vadd(&compile, "-c");
   976  				if(streq(gohostarch, "amd64"))
   977  					vadd(&compile, "-m64");
   978  				else if(streq(gohostarch, "386"))
   979  					vadd(&compile, "-m32");
   980  	
   981  				vadd(&compile, "-I");
   982  				vadd(&compile, bpathf(&b, "%s/include", goroot));
   983  			}
   984  
   985  			if(streq(dir, "lib9"))
   986  				vadd(&compile, "-DPLAN9PORT");
   987  
   988  
   989  			vadd(&compile, "-I");
   990  			vadd(&compile, bstr(&path));
   991  
   992  			// lib9/goos.c gets the default constants hard-coded.
   993  			if(streq(name, "goos.c")) {
   994  				vadd(&compile, "-D");
   995  				vadd(&compile, bprintf(&b, "GOOS=\"%s\"", goos));
   996  				vadd(&compile, "-D");
   997  				vadd(&compile, bprintf(&b, "GOARCH=\"%s\"", goarch));
   998  				bprintf(&b1, "%s", goroot_final);
   999  				bsubst(&b1, "\\", "\\\\");  // turn into C string
  1000  				vadd(&compile, "-D");
  1001  				vadd(&compile, bprintf(&b, "GOROOT=\"%s\"", bstr(&b1)));
  1002  				vadd(&compile, "-D");
  1003  				vadd(&compile, bprintf(&b, "GOVERSION=\"%s\"", goversion));
  1004  				vadd(&compile, "-D");
  1005  				vadd(&compile, bprintf(&b, "GOARM=\"%s\"", goarm));
  1006  				vadd(&compile, "-D");
  1007  				vadd(&compile, bprintf(&b, "GO386=\"%s\"", go386));
  1008  				vadd(&compile, "-D");
  1009  				vadd(&compile, bprintf(&b, "GO_EXTLINK_ENABLED=\"%s\"", goextlinkenabled));
  1010  			}
  1011  
  1012  			// gc/lex.c records the GOEXPERIMENT setting used during the build.
  1013  			if(streq(name, "lex.c")) {
  1014  				xgetenv(&b, "GOEXPERIMENT");
  1015  				vadd(&compile, "-D");
  1016  				vadd(&compile, bprintf(&b1, "GOEXPERIMENT=\"%s\"", bstr(&b)));
  1017  			}
  1018  		} else {
  1019  			// Supporting files for a Go package.
  1020  			if(hassuffix(files.p[i], ".s"))
  1021  				vadd(&compile, bpathf(&b, "%s/%sa", tooldir, gochar));
  1022  			else {
  1023  				vadd(&compile, bpathf(&b, "%s/%sc", tooldir, gochar));
  1024  				vadd(&compile, "-F");
  1025  				vadd(&compile, "-V");
  1026  				vadd(&compile, "-w");
  1027  			}
  1028  			vadd(&compile, "-I");
  1029  			vadd(&compile, workdir);
  1030  			vadd(&compile, "-I");
  1031  			vadd(&compile, bprintf(&b, "%s/pkg/%s_%s", goroot, goos, goarch));
  1032  			vadd(&compile, "-D");
  1033  			vadd(&compile, bprintf(&b, "GOOS_%s", goos));
  1034  			vadd(&compile, "-D");
  1035  			vadd(&compile, bprintf(&b, "GOARCH_%s", goarch));
  1036  			vadd(&compile, "-D");
  1037  			vadd(&compile, bprintf(&b, "GOOS_GOARCH_%s_%s", goos, goarch));
  1038  		}
  1039  
  1040  		bpathf(&b, "%s/%s", workdir, lastelem(files.p[i]));
  1041  		doclean = 1;
  1042  		if(!isgo && streq(gohostos, "darwin")) {
  1043  			// To debug C programs on OS X, it is not enough to say -ggdb
  1044  			// on the command line.  You have to leave the object files
  1045  			// lying around too.  Leave them in pkg/obj/, which does not
  1046  			// get removed when this tool exits.
  1047  			bpathf(&b1, "%s/pkg/obj/%s", goroot, dir);
  1048  			xmkdirall(bstr(&b1));
  1049  			bpathf(&b, "%s/%s", bstr(&b1), lastelem(files.p[i]));
  1050  			doclean = 0;
  1051  		}
  1052  
  1053  		// Change the last character of the output file (which was c or s).
  1054  		if(streq(gohostos, "plan9"))
  1055  			b.p[b.len-1] = gohostchar[0];
  1056  		else
  1057  			b.p[b.len-1] = 'o';
  1058  		vadd(&compile, "-o");
  1059  		vadd(&compile, bstr(&b));
  1060  		vadd(&compile, files.p[i]);
  1061  		bgrunv(bstr(&path), CheckExit, &compile);
  1062  
  1063  		vadd(&link, bstr(&b));
  1064  		if(doclean)
  1065  			vadd(&clean, bstr(&b));
  1066  	}
  1067  	bgwait();
  1068  
  1069  	if(isgo) {
  1070  		// The last loop was compiling individual files.
  1071  		// Hand the Go files to the compiler en masse.
  1072  		vreset(&compile);
  1073  		vadd(&compile, bpathf(&b, "%s/%sg", tooldir, gochar));
  1074  
  1075  		bpathf(&b, "%s/_go_.a", workdir);
  1076  		vadd(&compile, "-pack");
  1077  		vadd(&compile, "-o");
  1078  		vadd(&compile, bstr(&b));
  1079  		vadd(&clean, bstr(&b));
  1080  		if(!ispackcmd)
  1081  			vadd(&link, bstr(&b));
  1082  
  1083  		vadd(&compile, "-p");
  1084  		if(hasprefix(dir, "pkg/"))
  1085  			vadd(&compile, dir+4);
  1086  		else
  1087  			vadd(&compile, "main");
  1088  
  1089  		if(streq(dir, "pkg/runtime"))
  1090  			vadd(&compile, "-+");
  1091  
  1092  		vcopy(&compile, go.p, go.len);
  1093  
  1094  		runv(nil, bstr(&path), CheckExit, &compile);
  1095  
  1096  		if(ispackcmd) {
  1097  			xremove(link.p[targ]);
  1098  			dopack(link.p[targ], bstr(&b), &link.p[targ+1], link.len - (targ+1));
  1099  			goto nobuild;
  1100  		}
  1101  	}
  1102  
  1103  	if(!islib && !isgo) {
  1104  		// C binaries need the libraries explicitly, and -lm.
  1105  		vcopy(&link, lib.p, lib.len);
  1106  		if(!streq(gohostos, "plan9"))
  1107  			vadd(&link, "-lm");
  1108  	}
  1109  
  1110  	// Remove target before writing it.
  1111  	xremove(link.p[targ]);
  1112  
  1113  	runv(nil, nil, CheckExit, &link);
  1114  
  1115  nobuild:
  1116  	// In package runtime, we install runtime.h and cgocall.h too,
  1117  	// for use by cgo compilation.
  1118  	if(streq(dir, "pkg/runtime")) {
  1119  		copy(bpathf(&b, "%s/pkg/%s_%s/cgocall.h", goroot, goos, goarch),
  1120  			bpathf(&b1, "%s/src/pkg/runtime/cgocall.h", goroot), 0);
  1121  		copy(bpathf(&b, "%s/pkg/%s_%s/runtime.h", goroot, goos, goarch),
  1122  			bpathf(&b1, "%s/src/pkg/runtime/runtime.h", goroot), 0);
  1123  	}
  1124  
  1125  
  1126  out:
  1127  	for(i=0; i<clean.len; i++)
  1128  		xremove(clean.p[i]);
  1129  
  1130  	bfree(&b);
  1131  	bfree(&b1);
  1132  	bfree(&path);
  1133  	vfree(&compile);
  1134  	vfree(&files);
  1135  	vfree(&link);
  1136  	vfree(&go);
  1137  	vfree(&missing);
  1138  	vfree(&clean);
  1139  	vfree(&lib);
  1140  	vfree(&extra);
  1141  }
  1142  
  1143  // matchfield reports whether the field matches this build.
  1144  static bool
  1145  matchfield(char *f)
  1146  {
  1147  	char *p;
  1148  	bool res;
  1149  
  1150  	p = xstrrchr(f, ',');
  1151  	if(p == nil)
  1152  		return streq(f, goos) || streq(f, goarch) || streq(f, "cmd_go_bootstrap") || streq(f, "go1.1");
  1153  	*p = 0;
  1154  	res = matchfield(f) && matchfield(p+1);
  1155  	*p = ',';
  1156  	return res;
  1157  }
  1158  
  1159  // shouldbuild reports whether we should build this file.
  1160  // It applies the same rules that are used with context tags
  1161  // in package go/build, except that the GOOS and GOARCH
  1162  // can appear anywhere in the file name, not just after _.
  1163  // In particular, they can be the entire file name (like windows.c).
  1164  // We also allow the special tag cmd_go_bootstrap.
  1165  // See ../go/bootstrap.go and package go/build.
  1166  static bool
  1167  shouldbuild(char *file, char *dir)
  1168  {
  1169  	char *name, *p;
  1170  	int i, j, ret;
  1171  	Buf b;
  1172  	Vec lines, fields;
  1173  	
  1174  	// Check file name for GOOS or GOARCH.
  1175  	name = lastelem(file);
  1176  	for(i=0; i<nelem(okgoos); i++)
  1177  		if(contains(name, okgoos[i]) && !streq(okgoos[i], goos))
  1178  			return 0;
  1179  	for(i=0; i<nelem(okgoarch); i++)
  1180  		if(contains(name, okgoarch[i]) && !streq(okgoarch[i], goarch))
  1181  			return 0;
  1182  
  1183  	// Omit test files.
  1184  	if(contains(name, "_test"))
  1185  		return 0;
  1186  
  1187  	// cmd/go/doc.go has a giant /* */ comment before
  1188  	// it gets to the important detail that it is not part of
  1189  	// package main.  We don't parse those comments,
  1190  	// so special case that file.
  1191  	if(hassuffix(file, "cmd/go/doc.go") || hassuffix(file, "cmd\\go\\doc.go"))
  1192  		return 0;
  1193  	if(hassuffix(file, "cmd/cgo/doc.go") || hassuffix(file, "cmd\\cgo\\doc.go"))
  1194  		return 0;
  1195  
  1196  	// Check file contents for // +build lines.
  1197  	binit(&b);
  1198  	vinit(&lines);
  1199  	vinit(&fields);
  1200  
  1201  	ret = 1;
  1202  	readfile(&b, file);
  1203  	splitlines(&lines, bstr(&b));
  1204  	for(i=0; i<lines.len; i++) {
  1205  		p = lines.p[i];
  1206  		while(*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
  1207  			p++;
  1208  		if(*p == '\0')
  1209  			continue;
  1210  		if(contains(p, "package documentation")) {
  1211  			ret = 0;
  1212  			goto out;
  1213  		}
  1214  		if(contains(p, "package main") && !streq(dir, "cmd/go") && !streq(dir, "cmd/cgo")) {
  1215  			ret = 0;
  1216  			goto out;
  1217  		}
  1218  		if(!hasprefix(p, "//"))
  1219  			break;
  1220  		if(!contains(p, "+build"))
  1221  			continue;
  1222  		splitfields(&fields, lines.p[i]);
  1223  		if(fields.len < 2 || !streq(fields.p[1], "+build"))
  1224  			continue;
  1225  		for(j=2; j<fields.len; j++) {
  1226  			p = fields.p[j];
  1227  			if((*p == '!' && !matchfield(p+1)) || matchfield(p))
  1228  				goto fieldmatch;
  1229  		}
  1230  		ret = 0;
  1231  		goto out;
  1232  	fieldmatch:;
  1233  	}
  1234  
  1235  out:
  1236  	bfree(&b);
  1237  	vfree(&lines);
  1238  	vfree(&fields);
  1239  
  1240  	return ret;
  1241  }
  1242  
  1243  // copy copies the file src to dst, via memory (so only good for small files).
  1244  static void
  1245  copy(char *dst, char *src, int exec)
  1246  {
  1247  	Buf b;
  1248  
  1249  	if(vflag > 1)
  1250  		errprintf("cp %s %s\n", src, dst);
  1251  
  1252  	binit(&b);
  1253  	readfile(&b, src);
  1254  	writefile(&b, dst, exec);
  1255  	bfree(&b);
  1256  }
  1257  
  1258  // dopack copies the package src to dst,
  1259  // appending the files listed in extra.
  1260  // The archive format is the traditional Unix ar format.
  1261  static void
  1262  dopack(char *dst, char *src, char **extra, int nextra)
  1263  {
  1264  	int i;
  1265  	char c, *p, *q;
  1266  	Buf b, bdst;
  1267  	
  1268  	binit(&b);
  1269  	binit(&bdst);
  1270  
  1271  	readfile(&bdst, src);
  1272  	for(i=0; i<nextra; i++) {
  1273  		readfile(&b, extra[i]);
  1274  		// find last path element for archive member name
  1275  		p = xstrrchr(extra[i], '/');
  1276  		if(p)
  1277  			p++;
  1278  		q = xstrrchr(extra[i], '\\');
  1279  		if(q) {
  1280  			q++;
  1281  			if(p == nil || q > p)
  1282  				p = q;
  1283  		}
  1284  		if(p == nil)
  1285  			p = extra[i];
  1286  		bwritef(&bdst, "%-16.16s%-12d%-6d%-6d%-8o%-10d`\n", p, 0, 0, 0, 0644, b.len);
  1287  		bwriteb(&bdst, &b);
  1288  		if(b.len&1) {
  1289  			c = 0;
  1290  			bwrite(&bdst, &c, 1);
  1291  		}
  1292  	}
  1293  
  1294  	writefile(&bdst, dst, 0);
  1295  
  1296  	bfree(&b);
  1297  	bfree(&bdst);
  1298  }
  1299  
  1300  // buildorder records the order of builds for the 'go bootstrap' command.
  1301  static char *buildorder[] = {
  1302  	"lib9",
  1303  	"libbio",
  1304  	"liblink",
  1305  
  1306  	"misc/pprof",
  1307  
  1308  	"cmd/cc",  // must be before c
  1309  	"cmd/gc",  // must be before g
  1310  	"cmd/%sl",  // must be before a, c, g
  1311  	"cmd/%sa",
  1312  	"cmd/%sc",
  1313  	"cmd/%sg",
  1314  
  1315  	// The dependency order here was copied from a buildscript
  1316  	// back when there were build scripts.  Will have to
  1317  	// be maintained by hand, but shouldn't change very
  1318  	// often.
  1319  	"pkg/runtime",
  1320  	"pkg/errors",
  1321  	"pkg/sync/atomic",
  1322  	"pkg/sync",
  1323  	"pkg/io",
  1324  	"pkg/unicode",
  1325  	"pkg/unicode/utf8",
  1326  	"pkg/unicode/utf16",
  1327  	"pkg/bytes",
  1328  	"pkg/math",
  1329  	"pkg/strings",
  1330  	"pkg/strconv",
  1331  	"pkg/bufio",
  1332  	"pkg/sort",
  1333  	"pkg/container/heap",
  1334  	"pkg/encoding/base64",
  1335  	"pkg/syscall",
  1336  	"pkg/time",
  1337  	"pkg/os",
  1338  	"pkg/reflect",
  1339  	"pkg/fmt",
  1340  	"pkg/encoding",
  1341  	"pkg/encoding/json",
  1342  	"pkg/flag",
  1343  	"pkg/path/filepath",
  1344  	"pkg/path",
  1345  	"pkg/io/ioutil",
  1346  	"pkg/log",
  1347  	"pkg/regexp/syntax",
  1348  	"pkg/regexp",
  1349  	"pkg/go/token",
  1350  	"pkg/go/scanner",
  1351  	"pkg/go/ast",
  1352  	"pkg/go/parser",
  1353  	"pkg/os/exec",
  1354  	"pkg/os/signal",
  1355  	"pkg/net/url",
  1356  	"pkg/text/template/parse",
  1357  	"pkg/text/template",
  1358  	"pkg/go/doc",
  1359  	"pkg/go/build",
  1360  	"cmd/go",
  1361  };
  1362  
  1363  // cleantab records the directories to clean in 'go clean'.
  1364  // It is bigger than the buildorder because we clean all the
  1365  // compilers but build only the $GOARCH ones.
  1366  static char *cleantab[] = {
  1367  	"cmd/5a",
  1368  	"cmd/5c",
  1369  	"cmd/5g",
  1370  	"cmd/5l",
  1371  	"cmd/6a",
  1372  	"cmd/6c",
  1373  	"cmd/6g",
  1374  	"cmd/6l",
  1375  	"cmd/8a",
  1376  	"cmd/8c",
  1377  	"cmd/8g",
  1378  	"cmd/8l",
  1379  	"cmd/cc",
  1380  	"cmd/gc",
  1381  	"cmd/go",	
  1382  	"lib9",
  1383  	"libbio",
  1384  	"liblink",
  1385  	"pkg/bufio",
  1386  	"pkg/bytes",
  1387  	"pkg/container/heap",
  1388  	"pkg/encoding",
  1389  	"pkg/encoding/base64",
  1390  	"pkg/encoding/json",
  1391  	"pkg/errors",
  1392  	"pkg/flag",
  1393  	"pkg/fmt",
  1394  	"pkg/go/ast",
  1395  	"pkg/go/build",
  1396  	"pkg/go/doc",
  1397  	"pkg/go/parser",
  1398  	"pkg/go/scanner",
  1399  	"pkg/go/token",
  1400  	"pkg/io",
  1401  	"pkg/io/ioutil",
  1402  	"pkg/log",
  1403  	"pkg/math",
  1404  	"pkg/net/url",
  1405  	"pkg/os",
  1406  	"pkg/os/exec",
  1407  	"pkg/path",
  1408  	"pkg/path/filepath",
  1409  	"pkg/reflect",
  1410  	"pkg/regexp",
  1411  	"pkg/regexp/syntax",
  1412  	"pkg/runtime",
  1413  	"pkg/sort",
  1414  	"pkg/strconv",
  1415  	"pkg/strings",
  1416  	"pkg/sync",
  1417  	"pkg/sync/atomic",
  1418  	"pkg/syscall",
  1419  	"pkg/text/template",
  1420  	"pkg/text/template/parse",
  1421  	"pkg/time",
  1422  	"pkg/unicode",
  1423  	"pkg/unicode/utf16",
  1424  	"pkg/unicode/utf8",
  1425  };
  1426  
  1427  static void
  1428  clean(void)
  1429  {
  1430  	int i, j, k;
  1431  	Buf b, path;
  1432  	Vec dir;
  1433  
  1434  	binit(&b);
  1435  	binit(&path);
  1436  	vinit(&dir);
  1437  
  1438  	for(i=0; i<nelem(cleantab); i++) {
  1439  		bpathf(&path, "%s/src/%s", goroot, cleantab[i]);
  1440  		xreaddir(&dir, bstr(&path));
  1441  		// Remove generated files.
  1442  		for(j=0; j<dir.len; j++) {
  1443  			for(k=0; k<nelem(gentab); k++) {
  1444  				if(hasprefix(dir.p[j], gentab[k].nameprefix))
  1445  					xremove(bpathf(&b, "%s/%s", bstr(&path), dir.p[j]));
  1446  			}
  1447  		}
  1448  		// Remove generated binary named for directory.
  1449  		if(hasprefix(cleantab[i], "cmd/"))
  1450  			xremove(bpathf(&b, "%s/%s", bstr(&path), cleantab[i]+4));
  1451  	}
  1452  
  1453  	// remove src/pkg/runtime/z* unconditionally
  1454  	vreset(&dir);
  1455  	bpathf(&path, "%s/src/pkg/runtime", goroot);
  1456  	xreaddir(&dir, bstr(&path));
  1457  	for(j=0; j<dir.len; j++) {
  1458  		if(hasprefix(dir.p[j], "z"))
  1459  			xremove(bpathf(&b, "%s/%s", bstr(&path), dir.p[j]));
  1460  	}
  1461  
  1462  	if(rebuildall) {
  1463  		// Remove object tree.
  1464  		xremoveall(bpathf(&b, "%s/pkg/obj/%s_%s", goroot, gohostos, gohostarch));
  1465  
  1466  		// Remove installed packages and tools.
  1467  		xremoveall(bpathf(&b, "%s/pkg/%s_%s", goroot, gohostos, gohostarch));
  1468  		xremoveall(bpathf(&b, "%s/pkg/%s_%s", goroot, goos, goarch));
  1469  		xremoveall(tooldir);
  1470  
  1471  		// Remove cached version info.
  1472  		xremove(bpathf(&b, "%s/VERSION.cache", goroot));
  1473  	}
  1474  
  1475  	bfree(&b);
  1476  	bfree(&path);
  1477  	vfree(&dir);
  1478  }
  1479  
  1480  /*
  1481   * command implementations
  1482   */
  1483  
  1484  void
  1485  usage(void)
  1486  {
  1487  	xprintf("usage: go tool dist [command]\n"
  1488  		"Commands are:\n"
  1489  		"\n"
  1490  		"banner         print installation banner\n"
  1491  		"bootstrap      rebuild everything\n"
  1492  		"clean          deletes all built files\n"
  1493  		"env [-p]       print environment (-p: include $PATH)\n"
  1494  		"install [dir]  install individual directory\n"
  1495  		"version        print Go version\n"
  1496  		"\n"
  1497  		"All commands take -v flags to emit extra information.\n"
  1498  	);
  1499  	xexit(2);
  1500  }
  1501  
  1502  // The env command prints the default environment.
  1503  void
  1504  cmdenv(int argc, char **argv)
  1505  {
  1506  	bool pflag;
  1507  	char *sep;
  1508  	Buf b, b1;
  1509  	char *format;
  1510  
  1511  	binit(&b);
  1512  	binit(&b1);
  1513  
  1514  	format = "%s=\"%s\"\n";
  1515  	pflag = 0;
  1516  	ARGBEGIN{
  1517  	case '9':
  1518  		format = "%s='%s'\n";
  1519  		break;
  1520  	case 'p':
  1521  		pflag = 1;
  1522  		break;
  1523  	case 'v':
  1524  		vflag++;
  1525  		break;
  1526  	case 'w':
  1527  		format = "set %s=%s\r\n";
  1528  		break;
  1529  	default:
  1530  		usage();
  1531  	}ARGEND
  1532  
  1533  	if(argc > 0)
  1534  		usage();
  1535  
  1536  	xprintf(format, "CC", defaultcc);
  1537  	xprintf(format, "CC_FOR_TARGET", defaultcctarget);
  1538  	xprintf(format, "GOROOT", goroot);
  1539  	xprintf(format, "GOBIN", gobin);
  1540  	xprintf(format, "GOARCH", goarch);
  1541  	xprintf(format, "GOOS", goos);
  1542  	xprintf(format, "GOHOSTARCH", gohostarch);
  1543  	xprintf(format, "GOHOSTOS", gohostos);
  1544  	xprintf(format, "GOTOOLDIR", tooldir);
  1545  	xprintf(format, "GOCHAR", gochar);
  1546  	if(streq(goarch, "arm"))
  1547  		xprintf(format, "GOARM", goarm);
  1548  	if(streq(goarch, "386"))
  1549  		xprintf(format, "GO386", go386);
  1550  
  1551  	if(pflag) {
  1552  		sep = ":";
  1553  		if(streq(gohostos, "windows"))
  1554  			sep = ";";
  1555  		xgetenv(&b, "PATH");
  1556  		bprintf(&b1, "%s%s%s", gobin, sep, bstr(&b));
  1557  		xprintf(format, "PATH", bstr(&b1));
  1558  	}
  1559  
  1560  	bfree(&b);
  1561  	bfree(&b1);
  1562  }
  1563  
  1564  // The bootstrap command runs a build from scratch,
  1565  // stopping at having installed the go_bootstrap command.
  1566  void
  1567  cmdbootstrap(int argc, char **argv)
  1568  {
  1569  	int i;
  1570  	Buf b;
  1571  	char *oldgoos, *oldgoarch, *oldgochar;
  1572  
  1573  	binit(&b);
  1574  
  1575  	ARGBEGIN{
  1576  	case 'a':
  1577  		rebuildall = 1;
  1578  		break;
  1579  	case 's':
  1580  		sflag++;
  1581  		break;
  1582  	case 'v':
  1583  		vflag++;
  1584  		break;
  1585  	default:
  1586  		usage();
  1587  	}ARGEND
  1588  
  1589  	if(argc > 0)
  1590  		usage();
  1591  
  1592  	if(rebuildall)
  1593  		clean();
  1594  	goversion = findgoversion();
  1595  	setup();
  1596  
  1597  	xsetenv("GOROOT", goroot);
  1598  	xsetenv("GOROOT_FINAL", goroot_final);
  1599  
  1600  	// For the main bootstrap, building for host os/arch.
  1601  	oldgoos = goos;
  1602  	oldgoarch = goarch;
  1603  	oldgochar = gochar;
  1604  	goos = gohostos;
  1605  	goarch = gohostarch;
  1606  	gochar = gohostchar;
  1607  	xsetenv("GOARCH", goarch);
  1608  	xsetenv("GOOS", goos);
  1609  
  1610  	for(i=0; i<nelem(buildorder); i++) {
  1611  		install(bprintf(&b, buildorder[i], gohostchar));
  1612  		if(!streq(oldgochar, gohostchar) && xstrstr(buildorder[i], "%s"))
  1613  			install(bprintf(&b, buildorder[i], oldgochar));
  1614  	}
  1615  
  1616  	goos = oldgoos;
  1617  	goarch = oldgoarch;
  1618  	gochar = oldgochar;
  1619  	xsetenv("GOARCH", goarch);
  1620  	xsetenv("GOOS", goos);
  1621  
  1622  	// Build pkg/runtime for actual goos/goarch too.
  1623  	if(!streq(goos, gohostos) || !streq(goarch, gohostarch))
  1624  		install("pkg/runtime");
  1625  
  1626  	bfree(&b);
  1627  }
  1628  
  1629  static char*
  1630  defaulttarg(void)
  1631  {
  1632  	char *p;
  1633  	Buf pwd, src, real_src;
  1634  
  1635  	binit(&pwd);
  1636  	binit(&src);
  1637  	binit(&real_src);
  1638  
  1639  	// xgetwd might return a path with symlinks fully resolved, and if
  1640  	// there happens to be symlinks in goroot, then the hasprefix test
  1641  	// will never succeed. Instead, we use xrealwd to get a canonical
  1642  	// goroot/src before the comparison to avoid this problem.
  1643  	xgetwd(&pwd);
  1644  	p = btake(&pwd);
  1645  	bpathf(&src, "%s/src/", goroot);
  1646  	xrealwd(&real_src, bstr(&src));
  1647  	if(!hasprefix(p, bstr(&real_src)))
  1648  		fatal("current directory %s is not under %s", p, bstr(&real_src));
  1649  	p += real_src.len;
  1650  	// guard againt xrealwd return the directory without the trailing /
  1651  	if(*p == slash[0])
  1652  		p++;
  1653  
  1654  	bfree(&pwd);
  1655  	bfree(&src);
  1656  	bfree(&real_src);
  1657  
  1658  	return p;
  1659  }
  1660  
  1661  // Install installs the list of packages named on the command line.
  1662  void
  1663  cmdinstall(int argc, char **argv)
  1664  {
  1665  	int i;
  1666  
  1667  	ARGBEGIN{
  1668  	case 's':
  1669  		sflag++;
  1670  		break;
  1671  	case 'v':
  1672  		vflag++;
  1673  		break;
  1674  	default:
  1675  		usage();
  1676  	}ARGEND
  1677  
  1678  	if(argc == 0)
  1679  		install(defaulttarg());
  1680  
  1681  	for(i=0; i<argc; i++)
  1682  		install(argv[i]);
  1683  }
  1684  
  1685  // Clean deletes temporary objects.
  1686  // Clean -i deletes the installed objects too.
  1687  void
  1688  cmdclean(int argc, char **argv)
  1689  {
  1690  	ARGBEGIN{
  1691  	case 'v':
  1692  		vflag++;
  1693  		break;
  1694  	default:
  1695  		usage();
  1696  	}ARGEND
  1697  
  1698  	if(argc > 0)
  1699  		usage();
  1700  
  1701  	clean();
  1702  }
  1703  
  1704  // Banner prints the 'now you've installed Go' banner.
  1705  void
  1706  cmdbanner(int argc, char **argv)
  1707  {
  1708  	char *pathsep, *pid, *ns;
  1709  	Buf b, b1, search, path;
  1710  
  1711  	ARGBEGIN{
  1712  	case 'v':
  1713  		vflag++;
  1714  		break;
  1715  	default:
  1716  		usage();
  1717  	}ARGEND
  1718  
  1719  	if(argc > 0)
  1720  		usage();
  1721  
  1722  	binit(&b);
  1723  	binit(&b1);
  1724  	binit(&search);
  1725  	binit(&path);
  1726  
  1727  	xprintf("\n");
  1728  	xprintf("---\n");
  1729  	xprintf("Installed Go for %s/%s in %s\n", goos, goarch, goroot);
  1730  	xprintf("Installed commands in %s\n", gobin);
  1731  
  1732  	if(!xsamefile(goroot_final, goroot)) {
  1733  		// If the files are to be moved, don't check that gobin
  1734  		// is on PATH; assume they know what they are doing.
  1735  	} else if(streq(gohostos, "plan9")) {
  1736  		// Check that gobin is bound before /bin.
  1737  		readfile(&b, "#c/pid");
  1738  		bsubst(&b, " ", "");
  1739  		pid = btake(&b);
  1740  		bprintf(&b, "/proc/%s/ns", pid);
  1741  		ns = btake(&b);
  1742  		readfile(&b, ns);
  1743  		bprintf(&search, "bind -b %s /bin\n", gobin);
  1744  		if(xstrstr(bstr(&b), bstr(&search)) == nil)
  1745  			xprintf("*** You need to bind %s before /bin.\n", gobin);
  1746  	} else {
  1747  		// Check that gobin appears in $PATH.
  1748  		xgetenv(&b, "PATH");
  1749  		pathsep = ":";
  1750  		if(streq(gohostos, "windows"))
  1751  			pathsep = ";";
  1752  		bprintf(&b1, "%s%s%s", pathsep, bstr(&b), pathsep);
  1753  		bprintf(&search, "%s%s%s", pathsep, gobin, pathsep);
  1754  		if(xstrstr(bstr(&b1), bstr(&search)) == nil)
  1755  			xprintf("*** You need to add %s to your PATH.\n", gobin);
  1756  	}
  1757  
  1758  	if(streq(gohostos, "darwin")) {
  1759  		if(isfile(bpathf(&path, "%s/cov", tooldir)))
  1760  			xprintf("\n"
  1761  				"On OS X the debuggers must be installed setgid procmod.\n"
  1762  				"Read and run ./sudo.bash to install the debuggers.\n");
  1763  	}
  1764  
  1765  	if(!xsamefile(goroot_final, goroot)) {
  1766  		xprintf("\n"
  1767  			"The binaries expect %s to be copied or moved to %s\n",
  1768  			goroot, goroot_final);
  1769  	}
  1770  
  1771  	bfree(&b);
  1772  	bfree(&b1);
  1773  	bfree(&search);
  1774  	bfree(&path);
  1775  }
  1776  
  1777  // Version prints the Go version.
  1778  void
  1779  cmdversion(int argc, char **argv)
  1780  {
  1781  	ARGBEGIN{
  1782  	case 'v':
  1783  		vflag++;
  1784  		break;
  1785  	default:
  1786  		usage();
  1787  	}ARGEND
  1788  
  1789  	if(argc > 0)
  1790  		usage();
  1791  
  1792  	xprintf("%s\n", goversion);
  1793  }