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 }