github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/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 dopack(char*, char*, char**, int); 39 static char *findgoversion(void); 40 41 // The known architecture letters. 42 static char *gochars = "5668"; 43 44 // The known architectures. 45 static char *okgoarch[] = { 46 // same order as gochars 47 "arm", 48 "amd64", 49 "amd64p32", 50 "386", 51 }; 52 53 // The known operating systems. 54 static char *okgoos[] = { 55 "darwin", 56 "dragonfly", 57 "linux", 58 "android", 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/debug/goobj", 370 "src/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 "-fno-common", 468 "-ggdb", 469 "-pipe", 470 }; 471 472 // gccargs2 is the second part of gccargs. 473 // it is used if the environment isn't defining CFLAGS. 474 static char *proto_gccargs2[] = { 475 // on older versions of GCC, -Wuninitialized is not supported 476 // without -O, so put it here together with -O settings in case 477 // the user's $CFLAGS doesn't include -O. 478 "-Wuninitialized", 479 #if defined(__NetBSD__) && defined(__arm__) 480 // GCC 4.5.4 (NetBSD nb1 20120916) on ARM is known to mis-optimize gc/mparith3.c 481 // Fix available at http://patchwork.ozlabs.org/patch/64562/. 482 "-O1", 483 #else 484 "-O2", 485 #endif 486 }; 487 488 static Vec gccargs, ldargs; 489 490 // deptab lists changes to the default dependencies for a given prefix. 491 // deps ending in /* read the whole directory; deps beginning with - 492 // exclude files with that prefix. 493 static struct { 494 char *prefix; // prefix of target 495 char *dep[20]; // dependency tweaks for targets with that prefix 496 } deptab[] = { 497 {"lib9", { 498 "$GOROOT/include/u.h", 499 "$GOROOT/include/utf.h", 500 "$GOROOT/include/fmt.h", 501 "$GOROOT/include/libc.h", 502 "fmt/*", 503 "utf/*", 504 }}, 505 {"libbio", { 506 "$GOROOT/include/u.h", 507 "$GOROOT/include/utf.h", 508 "$GOROOT/include/fmt.h", 509 "$GOROOT/include/libc.h", 510 "$GOROOT/include/bio.h", 511 }}, 512 {"liblink", { 513 "$GOROOT/include/u.h", 514 "$GOROOT/include/utf.h", 515 "$GOROOT/include/fmt.h", 516 "$GOROOT/include/libc.h", 517 "$GOROOT/include/bio.h", 518 "$GOROOT/include/ar.h", 519 "$GOROOT/include/link.h", 520 "anames5.c", 521 "anames6.c", 522 "anames8.c", 523 }}, 524 {"cmd/cc", { 525 "-pgen.c", 526 "-pswt.c", 527 }}, 528 {"cmd/gc", { 529 "-cplx.c", 530 "-pgen.c", 531 "-plive.c", 532 "-popt.c", 533 "-y1.tab.c", // makefile dreg 534 "opnames.h", 535 }}, 536 {"cmd/5c", { 537 "../cc/pgen.c", 538 "../cc/pswt.c", 539 "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a", 540 }}, 541 {"cmd/6c", { 542 "../cc/pgen.c", 543 "../cc/pswt.c", 544 "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a", 545 }}, 546 {"cmd/8c", { 547 "../cc/pgen.c", 548 "../cc/pswt.c", 549 "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libcc.a", 550 }}, 551 {"cmd/5g", { 552 "../gc/cplx.c", 553 "../gc/pgen.c", 554 "../gc/plive.c", 555 "../gc/popt.c", 556 "../gc/popt.h", 557 "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libgc.a", 558 }}, 559 {"cmd/6g", { 560 "../gc/cplx.c", 561 "../gc/pgen.c", 562 "../gc/plive.c", 563 "../gc/popt.c", 564 "../gc/popt.h", 565 "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libgc.a", 566 }}, 567 {"cmd/8g", { 568 "../gc/cplx.c", 569 "../gc/pgen.c", 570 "../gc/plive.c", 571 "../gc/popt.c", 572 "../gc/popt.h", 573 "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libgc.a", 574 }}, 575 {"cmd/5l", { 576 "../ld/*", 577 }}, 578 {"cmd/6l", { 579 "../ld/*", 580 }}, 581 {"cmd/8l", { 582 "../ld/*", 583 }}, 584 {"cmd/go", { 585 "zdefaultcc.go", 586 }}, 587 {"cmd/", { 588 "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/liblink.a", 589 "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libbio.a", 590 "$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/lib9.a", 591 }}, 592 {"runtime", { 593 "zaexperiment.h", // must sort above zasm 594 "zasm_$GOOS_$GOARCH.h", 595 "zsys_$GOOS_$GOARCH.s", 596 "zgoarch_$GOARCH.go", 597 "zgoos_$GOOS.go", 598 "zruntime_defs_$GOOS_$GOARCH.go", 599 "zversion.go", 600 }}, 601 }; 602 603 // depsuffix records the allowed suffixes for source files. 604 char *depsuffix[] = { 605 ".c", 606 ".h", 607 ".s", 608 ".go", 609 }; 610 611 // gentab records how to generate some trivial files. 612 static struct { 613 char *nameprefix; 614 void (*gen)(char*, char*); 615 } gentab[] = { 616 {"opnames.h", gcopnames}, 617 {"anames5.c", mkanames}, 618 {"anames6.c", mkanames}, 619 {"anames8.c", mkanames}, 620 {"zasm_", mkzasm}, 621 {"zdefaultcc.go", mkzdefaultcc}, 622 {"zsys_", mkzsys}, 623 {"zgoarch_", mkzgoarch}, 624 {"zgoos_", mkzgoos}, 625 {"zruntime_defs_", mkzruntimedefs}, 626 {"zversion.go", mkzversion}, 627 {"zaexperiment.h", mkzexperiment}, 628 629 // not generated anymore, but delete the file if we see it 630 {"enam.c", nil}, 631 }; 632 633 // install installs the library, package, or binary associated with dir, 634 // which is relative to $GOROOT/src. 635 static void 636 install(char *dir) 637 { 638 char *name, *p, *elem, *prefix, *exe; 639 bool islib, ispkg, isgo, stale, ispackcmd; 640 Buf b, b1, path, final_path, final_name; 641 Vec compile, files, link, go, missing, clean, lib, extra; 642 Time ttarg, t; 643 int i, j, k, n, doclean, targ; 644 645 if(vflag) { 646 if(!streq(goos, gohostos) || !streq(goarch, gohostarch)) 647 errprintf("%s (%s/%s)\n", dir, goos, goarch); 648 else 649 errprintf("%s\n", dir); 650 } 651 652 binit(&b); 653 binit(&b1); 654 binit(&path); 655 binit(&final_path); 656 binit(&final_name); 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 bpathf(&final_path, "%s/src/%s", goroot_final, dir); 670 name = lastelem(dir); 671 672 // For misc/prof, copy into the tool directory and we're done. 673 if(hasprefix(dir, "misc/")) { 674 copyfile(bpathf(&b, "%s/%s", tooldir, name), 675 bpathf(&b1, "%s/misc/%s", goroot, name), 1); 676 goto out; 677 } 678 679 // set up gcc command line on first run. 680 if(gccargs.len == 0) { 681 bprintf(&b, "%s %s", defaultcc, defaultcflags); 682 splitfields(&gccargs, bstr(&b)); 683 for(i=0; i<nelem(proto_gccargs); i++) 684 vadd(&gccargs, proto_gccargs[i]); 685 if(defaultcflags[0] == '\0') { 686 for(i=0; i<nelem(proto_gccargs2); i++) 687 vadd(&gccargs, proto_gccargs2[i]); 688 } 689 if(contains(gccargs.p[0], "clang")) { 690 // disable ASCII art in clang errors, if possible 691 vadd(&gccargs, "-fno-caret-diagnostics"); 692 // clang is too smart about unused command-line arguments 693 vadd(&gccargs, "-Qunused-arguments"); 694 } 695 // disable word wrapping in error messages 696 vadd(&gccargs, "-fmessage-length=0"); 697 if(streq(gohostos, "darwin")) { 698 // golang.org/issue/5261 699 vadd(&gccargs, "-mmacosx-version-min=10.6"); 700 } 701 } 702 if(ldargs.len == 0 && defaultldflags[0] != '\0') { 703 bprintf(&b, "%s", defaultldflags); 704 splitfields(&ldargs, bstr(&b)); 705 } 706 707 islib = hasprefix(dir, "lib") || streq(dir, "cmd/cc") || streq(dir, "cmd/gc"); 708 ispkg = !islib && !hasprefix(dir, "cmd/"); 709 isgo = ispkg || streq(dir, "cmd/go") || streq(dir, "cmd/cgo"); 710 711 exe = ""; 712 if(streq(gohostos, "windows")) 713 exe = ".exe"; 714 715 // Start final link command line. 716 // Note: code below knows that link.p[targ] is the target. 717 ispackcmd = 0; 718 if(islib) { 719 // C library. 720 vadd(&link, "ar"); 721 if(streq(gohostos, "plan9")) 722 vadd(&link, "rc"); 723 else 724 vadd(&link, "rsc"); 725 prefix = ""; 726 if(!hasprefix(name, "lib")) 727 prefix = "lib"; 728 targ = link.len; 729 vadd(&link, bpathf(&b, "%s/pkg/obj/%s_%s/%s%s.a", goroot, gohostos, gohostarch, prefix, name)); 730 } else if(ispkg) { 731 // Go library (package). 732 ispackcmd = 1; 733 vadd(&link, "pack"); // program name - unused here, but all the other cases record one 734 p = bprintf(&b, "%s/pkg/%s_%s/%s", goroot, goos, goarch, dir); 735 *xstrrchr(p, '/') = '\0'; 736 xmkdirall(p); 737 targ = link.len; 738 vadd(&link, bpathf(&b, "%s/pkg/%s_%s/%s.a", goroot, goos, goarch, dir)); 739 } else if(streq(dir, "cmd/go") || streq(dir, "cmd/cgo")) { 740 // Go command. 741 vadd(&link, bpathf(&b, "%s/%sl", tooldir, gochar)); 742 vadd(&link, "-o"); 743 elem = name; 744 if(streq(elem, "go")) 745 elem = "go_bootstrap"; 746 targ = link.len; 747 vadd(&link, bpathf(&b, "%s/%s%s", tooldir, elem, exe)); 748 } else { 749 // C command. Use gccargs and ldargs. 750 if(streq(gohostos, "plan9")) { 751 vadd(&link, bprintf(&b, "%sl", gohostchar)); 752 vadd(&link, "-o"); 753 targ = link.len; 754 vadd(&link, bpathf(&b, "%s/%s", tooldir, name)); 755 } else { 756 vcopy(&link, gccargs.p, gccargs.len); 757 vcopy(&link, ldargs.p, ldargs.len); 758 if(sflag) 759 vadd(&link, "-static"); 760 vadd(&link, "-o"); 761 targ = link.len; 762 vadd(&link, bpathf(&b, "%s/%s%s", tooldir, name, exe)); 763 if(streq(gohostarch, "amd64")) 764 vadd(&link, "-m64"); 765 else if(streq(gohostarch, "386")) 766 vadd(&link, "-m32"); 767 } 768 } 769 ttarg = mtime(link.p[targ]); 770 771 // Gather files that are sources for this target. 772 // Everything in that directory, and any target-specific 773 // additions. 774 xreaddir(&files, bstr(&path)); 775 776 // Remove files beginning with . or _, 777 // which are likely to be editor temporary files. 778 // This is the same heuristic build.ScanDir uses. 779 // There do exist real C files beginning with _, 780 // so limit that check to just Go files. 781 n = 0; 782 for(i=0; i<files.len; i++) { 783 p = files.p[i]; 784 if(hasprefix(p, ".") || (hasprefix(p, "_") && hassuffix(p, ".go"))) 785 xfree(p); 786 else 787 files.p[n++] = p; 788 } 789 files.len = n; 790 791 for(i=0; i<nelem(deptab); i++) { 792 if(streq(dir, deptab[i].prefix) || 793 (hassuffix(deptab[i].prefix, "/") && hasprefix(dir, deptab[i].prefix))) { 794 for(j=0; (p=deptab[i].dep[j])!=nil; j++) { 795 breset(&b1); 796 bwritestr(&b1, p); 797 bsubst(&b1, "$GOROOT", goroot); 798 bsubst(&b1, "$GOOS", goos); 799 bsubst(&b1, "$GOARCH", goarch); 800 bsubst(&b1, "$GOHOSTOS", gohostos); 801 bsubst(&b1, "$GOHOSTARCH", gohostarch); 802 p = bstr(&b1); 803 if(hassuffix(p, ".a")) { 804 vadd(&lib, bpathf(&b, "%s", p)); 805 continue; 806 } 807 if(hassuffix(p, "/*")) { 808 bpathf(&b, "%s/%s", bstr(&path), p); 809 b.len -= 2; 810 xreaddir(&extra, bstr(&b)); 811 bprintf(&b, "%s", p); 812 b.len -= 2; 813 for(k=0; k<extra.len; k++) 814 vadd(&files, bpathf(&b1, "%s/%s", bstr(&b), extra.p[k])); 815 continue; 816 } 817 if(hasprefix(p, "-")) { 818 p++; 819 n = 0; 820 for(k=0; k<files.len; k++) { 821 if(hasprefix(files.p[k], p)) 822 xfree(files.p[k]); 823 else 824 files.p[n++] = files.p[k]; 825 } 826 files.len = n; 827 continue; 828 } 829 vadd(&files, p); 830 } 831 } 832 } 833 vuniq(&files); 834 835 // Convert to absolute paths. 836 for(i=0; i<files.len; i++) { 837 if(!isabs(files.p[i])) { 838 bpathf(&b, "%s/%s", bstr(&path), files.p[i]); 839 xfree(files.p[i]); 840 files.p[i] = btake(&b); 841 } 842 } 843 844 // Is the target up-to-date? 845 stale = rebuildall; 846 n = 0; 847 for(i=0; i<files.len; i++) { 848 p = files.p[i]; 849 for(j=0; j<nelem(depsuffix); j++) 850 if(hassuffix(p, depsuffix[j])) 851 goto ok; 852 xfree(files.p[i]); 853 continue; 854 ok: 855 t = mtime(p); 856 if(t != 0 && !hassuffix(p, ".a") && !shouldbuild(p, dir)) { 857 xfree(files.p[i]); 858 continue; 859 } 860 if(hassuffix(p, ".go")) 861 vadd(&go, p); 862 if(t > ttarg) 863 stale = 1; 864 if(t == 0) { 865 vadd(&missing, p); 866 files.p[n++] = files.p[i]; 867 continue; 868 } 869 files.p[n++] = files.p[i]; 870 } 871 files.len = n; 872 873 // If there are no files to compile, we're done. 874 if(files.len == 0) 875 goto out; 876 877 for(i=0; i<lib.len && !stale; i++) 878 if(mtime(lib.p[i]) > ttarg) 879 stale = 1; 880 881 if(!stale) 882 goto out; 883 884 // For package runtime, copy some files into the work space. 885 if(streq(dir, "runtime")) { 886 copyfile(bpathf(&b, "%s/arch_GOARCH.h", workdir), 887 bpathf(&b1, "%s/arch_%s.h", bstr(&path), goarch), 0); 888 copyfile(bpathf(&b, "%s/defs_GOOS_GOARCH.h", workdir), 889 bpathf(&b1, "%s/defs_%s_%s.h", bstr(&path), goos, goarch), 0); 890 p = bpathf(&b1, "%s/signal_%s_%s.h", bstr(&path), goos, goarch); 891 if(isfile(p)) 892 copyfile(bpathf(&b, "%s/signal_GOOS_GOARCH.h", workdir), p, 0); 893 copyfile(bpathf(&b, "%s/os_GOOS.h", workdir), 894 bpathf(&b1, "%s/os_%s.h", bstr(&path), goos), 0); 895 copyfile(bpathf(&b, "%s/signals_GOOS.h", workdir), 896 bpathf(&b1, "%s/signals_%s.h", bstr(&path), goos), 0); 897 copyfile(bpathf(&b, "%s/pkg/%s_%s/textflag.h", goroot, goos, goarch), 898 bpathf(&b1, "%s/src/cmd/ld/textflag.h", goroot), 0); 899 copyfile(bpathf(&b, "%s/pkg/%s_%s/funcdata.h", goroot, goos, goarch), 900 bpathf(&b1, "%s/src/runtime/funcdata.h", goroot), 0); 901 } 902 903 // Generate any missing files; regenerate existing ones. 904 for(i=0; i<files.len; i++) { 905 p = files.p[i]; 906 elem = lastelem(p); 907 for(j=0; j<nelem(gentab); j++) { 908 if(gentab[j].gen == nil) 909 continue; 910 if(hasprefix(elem, gentab[j].nameprefix)) { 911 if(vflag > 1) 912 errprintf("generate %s\n", p); 913 gentab[j].gen(bstr(&path), p); 914 // Do not add generated file to clean list. 915 // In runtime, we want to be able to 916 // build the package with the go tool, 917 // and it assumes these generated files already 918 // exist (it does not know how to build them). 919 // The 'clean' command can remove 920 // the generated files. 921 goto built; 922 } 923 } 924 // Did not rebuild p. 925 if(find(p, missing.p, missing.len) >= 0) 926 fatal("missing file %s", p); 927 built:; 928 } 929 930 // One more copy for package runtime. 931 // The last batch was required for the generators. 932 // This one is generated. 933 if(streq(dir, "runtime")) { 934 copyfile(bpathf(&b, "%s/zasm_GOOS_GOARCH.h", workdir), 935 bpathf(&b1, "%s/zasm_%s_%s.h", bstr(&path), goos, goarch), 0); 936 } 937 938 if((!streq(goos, gohostos) || !streq(goarch, gohostarch)) && isgo) { 939 // We've generated the right files; the go command can do the build. 940 if(vflag > 1) 941 errprintf("skip build for cross-compile %s\n", dir); 942 goto nobuild; 943 } 944 945 // Compile the files. 946 for(i=0; i<files.len; i++) { 947 if(!hassuffix(files.p[i], ".c") && !hassuffix(files.p[i], ".s")) 948 continue; 949 name = lastelem(files.p[i]); 950 951 vreset(&compile); 952 if(!isgo) { 953 // C library or tool. 954 if(streq(gohostos, "plan9")) { 955 vadd(&compile, bprintf(&b, "%sc", gohostchar)); 956 vadd(&compile, "-FTVwp"); 957 vadd(&compile, "-DPLAN9"); 958 vadd(&compile, "-D__STDC__=1"); 959 vadd(&compile, "-D__SIZE_TYPE__=ulong"); // for GNU Bison 960 vadd(&compile, bpathf(&b, "-I%s/include/plan9", goroot)); 961 vadd(&compile, bpathf(&b, "-I%s/include/plan9/%s", goroot, gohostarch)); 962 } else { 963 vcopy(&compile, gccargs.p, gccargs.len); 964 vadd(&compile, "-c"); 965 if(streq(gohostarch, "amd64")) 966 vadd(&compile, "-m64"); 967 else if(streq(gohostarch, "386")) 968 vadd(&compile, "-m32"); 969 970 vadd(&compile, "-I"); 971 vadd(&compile, bpathf(&b, "%s/include", goroot)); 972 } 973 974 if(streq(dir, "lib9")) 975 vadd(&compile, "-DPLAN9PORT"); 976 977 978 vadd(&compile, "-I"); 979 vadd(&compile, bstr(&path)); 980 981 // lib9/goos.c gets the default constants hard-coded. 982 if(streq(name, "goos.c")) { 983 vadd(&compile, "-D"); 984 vadd(&compile, bprintf(&b, "GOOS=\"%s\"", goos)); 985 vadd(&compile, "-D"); 986 vadd(&compile, bprintf(&b, "GOARCH=\"%s\"", goarch)); 987 bprintf(&b1, "%s", goroot_final); 988 bsubst(&b1, "\\", "\\\\"); // turn into C string 989 vadd(&compile, "-D"); 990 vadd(&compile, bprintf(&b, "GOROOT=\"%s\"", bstr(&b1))); 991 vadd(&compile, "-D"); 992 vadd(&compile, bprintf(&b, "GOVERSION=\"%s\"", goversion)); 993 vadd(&compile, "-D"); 994 vadd(&compile, bprintf(&b, "GOARM=\"%s\"", goarm)); 995 vadd(&compile, "-D"); 996 vadd(&compile, bprintf(&b, "GO386=\"%s\"", go386)); 997 vadd(&compile, "-D"); 998 vadd(&compile, bprintf(&b, "GO_EXTLINK_ENABLED=\"%s\"", goextlinkenabled)); 999 } 1000 1001 // gc/lex.c records the GOEXPERIMENT setting used during the build. 1002 if(streq(name, "lex.c")) { 1003 xgetenv(&b, "GOEXPERIMENT"); 1004 vadd(&compile, "-D"); 1005 vadd(&compile, bprintf(&b1, "GOEXPERIMENT=\"%s\"", bstr(&b))); 1006 } 1007 } else { 1008 // Supporting files for a Go package. 1009 if(hassuffix(files.p[i], ".s")) 1010 vadd(&compile, bpathf(&b, "%s/%sa", tooldir, gochar)); 1011 else { 1012 vadd(&compile, bpathf(&b, "%s/%sc", tooldir, gochar)); 1013 vadd(&compile, "-F"); 1014 vadd(&compile, "-V"); 1015 vadd(&compile, "-w"); 1016 } 1017 vadd(&compile, "-I"); 1018 vadd(&compile, workdir); 1019 vadd(&compile, "-I"); 1020 vadd(&compile, bprintf(&b, "%s/pkg/%s_%s", goroot, goos, goarch)); 1021 vadd(&compile, "-D"); 1022 vadd(&compile, bprintf(&b, "GOOS_%s", goos)); 1023 vadd(&compile, "-D"); 1024 vadd(&compile, bprintf(&b, "GOARCH_%s", goarch)); 1025 vadd(&compile, "-D"); 1026 vadd(&compile, bprintf(&b, "GOOS_GOARCH_%s_%s", goos, goarch)); 1027 } 1028 1029 bpathf(&b, "%s/%s", workdir, lastelem(files.p[i])); 1030 doclean = 1; 1031 if(!isgo && streq(gohostos, "darwin")) { 1032 // To debug C programs on OS X, it is not enough to say -ggdb 1033 // on the command line. You have to leave the object files 1034 // lying around too. Leave them in pkg/obj/, which does not 1035 // get removed when this tool exits. 1036 bpathf(&b1, "%s/pkg/obj/%s", goroot, dir); 1037 xmkdirall(bstr(&b1)); 1038 bpathf(&b, "%s/%s", bstr(&b1), lastelem(files.p[i])); 1039 doclean = 0; 1040 } 1041 1042 // Change the last character of the output file (which was c or s). 1043 if(streq(gohostos, "plan9")) 1044 b.p[b.len-1] = gohostchar[0]; 1045 else 1046 b.p[b.len-1] = 'o'; 1047 vadd(&compile, "-o"); 1048 vadd(&compile, bstr(&b)); 1049 vadd(&compile, files.p[i]); 1050 bgrunv(bstr(&path), CheckExit, &compile); 1051 1052 vadd(&link, bstr(&b)); 1053 if(doclean) 1054 vadd(&clean, bstr(&b)); 1055 } 1056 bgwait(); 1057 1058 if(isgo) { 1059 // The last loop was compiling individual files. 1060 // Hand the Go files to the compiler en masse. 1061 vreset(&compile); 1062 vadd(&compile, bpathf(&b, "%s/%sg", tooldir, gochar)); 1063 1064 bpathf(&b, "%s/_go_.a", workdir); 1065 vadd(&compile, "-pack"); 1066 vadd(&compile, "-o"); 1067 vadd(&compile, bstr(&b)); 1068 vadd(&clean, bstr(&b)); 1069 if(!ispackcmd) 1070 vadd(&link, bstr(&b)); 1071 1072 vadd(&compile, "-p"); 1073 if(hasprefix(dir, "pkg/")) 1074 vadd(&compile, dir+4); 1075 else 1076 vadd(&compile, "main"); 1077 1078 if(streq(dir, "runtime")) 1079 vadd(&compile, "-+"); 1080 1081 vcopy(&compile, go.p, go.len); 1082 1083 runv(nil, bstr(&path), CheckExit, &compile); 1084 1085 if(ispackcmd) { 1086 xremove(link.p[targ]); 1087 dopack(link.p[targ], bstr(&b), &link.p[targ+1], link.len - (targ+1)); 1088 goto nobuild; 1089 } 1090 } 1091 1092 if(!islib && !isgo) { 1093 // C binaries need the libraries explicitly, and -lm. 1094 vcopy(&link, lib.p, lib.len); 1095 if(!streq(gohostos, "plan9")) 1096 vadd(&link, "-lm"); 1097 } 1098 1099 // Remove target before writing it. 1100 xremove(link.p[targ]); 1101 1102 runv(nil, nil, CheckExit, &link); 1103 1104 nobuild: 1105 // In package runtime, we install runtime.h and cgocall.h too, 1106 // for use by cgo compilation. 1107 if(streq(dir, "runtime")) { 1108 copyfile(bpathf(&b, "%s/pkg/%s_%s/cgocall.h", goroot, goos, goarch), 1109 bpathf(&b1, "%s/src/runtime/cgocall.h", goroot), 0); 1110 copyfile(bpathf(&b, "%s/pkg/%s_%s/runtime.h", goroot, goos, goarch), 1111 bpathf(&b1, "%s/src/runtime/runtime.h", goroot), 0); 1112 } 1113 1114 1115 out: 1116 for(i=0; i<clean.len; i++) 1117 xremove(clean.p[i]); 1118 1119 bfree(&b); 1120 bfree(&b1); 1121 bfree(&path); 1122 vfree(&compile); 1123 vfree(&files); 1124 vfree(&link); 1125 vfree(&go); 1126 vfree(&missing); 1127 vfree(&clean); 1128 vfree(&lib); 1129 vfree(&extra); 1130 } 1131 1132 // matchfield reports whether the field matches this build. 1133 static bool 1134 matchfield(char *f) 1135 { 1136 char *p; 1137 bool res; 1138 1139 p = xstrrchr(f, ','); 1140 if(p == nil) 1141 return streq(f, goos) || streq(f, goarch) || streq(f, "cmd_go_bootstrap") || streq(f, "go1.1") || (streq(goos, "android") && streq(f, "linux")); 1142 *p = 0; 1143 res = matchfield(f) && matchfield(p+1); 1144 *p = ','; 1145 return res; 1146 } 1147 1148 // shouldbuild reports whether we should build this file. 1149 // It applies the same rules that are used with context tags 1150 // in package go/build, except that the GOOS and GOARCH 1151 // can appear anywhere in the file name, not just after _. 1152 // In particular, they can be the entire file name (like windows.c). 1153 // We also allow the special tag cmd_go_bootstrap. 1154 // See ../go/bootstrap.go and package go/build. 1155 static bool 1156 shouldbuild(char *file, char *dir) 1157 { 1158 char *name, *p; 1159 int i, j, ret; 1160 Buf b; 1161 Vec lines, fields; 1162 1163 // Check file name for GOOS or GOARCH. 1164 name = lastelem(file); 1165 for(i=0; i<nelem(okgoos); i++) 1166 if(contains(name, okgoos[i]) && !streq(okgoos[i], goos)) 1167 return 0; 1168 for(i=0; i<nelem(okgoarch); i++) 1169 if(contains(name, okgoarch[i]) && !streq(okgoarch[i], goarch)) 1170 return 0; 1171 1172 // Omit test files. 1173 if(contains(name, "_test")) 1174 return 0; 1175 1176 // cmd/go/doc.go has a giant /* */ comment before 1177 // it gets to the important detail that it is not part of 1178 // package main. We don't parse those comments, 1179 // so special case that file. 1180 if(hassuffix(file, "cmd/go/doc.go") || hassuffix(file, "cmd\\go\\doc.go")) 1181 return 0; 1182 if(hassuffix(file, "cmd/cgo/doc.go") || hassuffix(file, "cmd\\cgo\\doc.go")) 1183 return 0; 1184 1185 // Check file contents for // +build lines. 1186 binit(&b); 1187 vinit(&lines); 1188 vinit(&fields); 1189 1190 ret = 1; 1191 readfile(&b, file); 1192 splitlines(&lines, bstr(&b)); 1193 for(i=0; i<lines.len; i++) { 1194 p = lines.p[i]; 1195 while(*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') 1196 p++; 1197 if(*p == '\0') 1198 continue; 1199 if(contains(p, "package documentation")) { 1200 ret = 0; 1201 goto out; 1202 } 1203 if(contains(p, "package main") && !streq(dir, "cmd/go") && !streq(dir, "cmd/cgo")) { 1204 ret = 0; 1205 goto out; 1206 } 1207 if(!hasprefix(p, "//")) 1208 break; 1209 if(!contains(p, "+build")) 1210 continue; 1211 splitfields(&fields, lines.p[i]); 1212 if(fields.len < 2 || !streq(fields.p[1], "+build")) 1213 continue; 1214 for(j=2; j<fields.len; j++) { 1215 p = fields.p[j]; 1216 if((*p == '!' && !matchfield(p+1)) || matchfield(p)) 1217 goto fieldmatch; 1218 } 1219 ret = 0; 1220 goto out; 1221 fieldmatch:; 1222 } 1223 1224 out: 1225 bfree(&b); 1226 vfree(&lines); 1227 vfree(&fields); 1228 1229 return ret; 1230 } 1231 1232 // copy copies the file src to dst, via memory (so only good for small files). 1233 void 1234 copyfile(char *dst, char *src, int exec) 1235 { 1236 Buf b; 1237 1238 if(vflag > 1) 1239 errprintf("cp %s %s\n", src, dst); 1240 1241 binit(&b); 1242 readfile(&b, src); 1243 writefile(&b, dst, exec); 1244 bfree(&b); 1245 } 1246 1247 // dopack copies the package src to dst, 1248 // appending the files listed in extra. 1249 // The archive format is the traditional Unix ar format. 1250 static void 1251 dopack(char *dst, char *src, char **extra, int nextra) 1252 { 1253 int i; 1254 char c, *p, *q; 1255 Buf b, bdst; 1256 1257 binit(&b); 1258 binit(&bdst); 1259 1260 readfile(&bdst, src); 1261 for(i=0; i<nextra; i++) { 1262 readfile(&b, extra[i]); 1263 // find last path element for archive member name 1264 p = xstrrchr(extra[i], '/'); 1265 if(p) 1266 p++; 1267 q = xstrrchr(extra[i], '\\'); 1268 if(q) { 1269 q++; 1270 if(p == nil || q > p) 1271 p = q; 1272 } 1273 if(p == nil) 1274 p = extra[i]; 1275 bwritef(&bdst, "%-16.16s%-12d%-6d%-6d%-8o%-10d`\n", p, 0, 0, 0, 0644, b.len); 1276 bwriteb(&bdst, &b); 1277 if(b.len&1) { 1278 c = 0; 1279 bwrite(&bdst, &c, 1); 1280 } 1281 } 1282 1283 writefile(&bdst, dst, 0); 1284 1285 bfree(&b); 1286 bfree(&bdst); 1287 } 1288 1289 // buildorder records the order of builds for the 'go bootstrap' command. 1290 static char *buildorder[] = { 1291 "lib9", 1292 "libbio", 1293 "liblink", 1294 1295 "misc/pprof", 1296 1297 "cmd/cc", // must be before c 1298 "cmd/gc", // must be before g 1299 "cmd/%sl", // must be before a, c, g 1300 "cmd/%sa", 1301 "cmd/%sc", 1302 "cmd/%sg", 1303 1304 // The dependency order here was copied from a buildscript 1305 // back when there were build scripts. Will have to 1306 // be maintained by hand, but shouldn't change very 1307 // often. 1308 "runtime", 1309 "errors", 1310 "sync/atomic", 1311 "sync", 1312 "io", 1313 "unicode", 1314 "unicode/utf8", 1315 "unicode/utf16", 1316 "bytes", 1317 "math", 1318 "strings", 1319 "strconv", 1320 "bufio", 1321 "sort", 1322 "container/heap", 1323 "encoding/base64", 1324 "syscall", 1325 "time", 1326 "os", 1327 "reflect", 1328 "fmt", 1329 "encoding", 1330 "encoding/json", 1331 "flag", 1332 "path/filepath", 1333 "path", 1334 "io/ioutil", 1335 "log", 1336 "regexp/syntax", 1337 "regexp", 1338 "go/token", 1339 "go/scanner", 1340 "go/ast", 1341 "go/parser", 1342 "os/exec", 1343 "os/signal", 1344 "net/url", 1345 "text/template/parse", 1346 "text/template", 1347 "go/doc", 1348 "go/build", 1349 "cmd/go", 1350 }; 1351 1352 // cleantab records the directories to clean in 'go clean'. 1353 // It is bigger than the buildorder because we clean all the 1354 // compilers but build only the $GOARCH ones. 1355 static char *cleantab[] = { 1356 // Commands and C libraries. 1357 "cmd/5a", 1358 "cmd/5c", 1359 "cmd/5g", 1360 "cmd/5l", 1361 "cmd/6a", 1362 "cmd/6c", 1363 "cmd/6g", 1364 "cmd/6l", 1365 "cmd/8a", 1366 "cmd/8c", 1367 "cmd/8g", 1368 "cmd/8l", 1369 "cmd/cc", 1370 "cmd/gc", 1371 "cmd/go", 1372 "lib9", 1373 "libbio", 1374 "liblink", 1375 1376 // Go packages. 1377 "bufio", 1378 "bytes", 1379 "container/heap", 1380 "encoding", 1381 "encoding/base64", 1382 "encoding/json", 1383 "errors", 1384 "flag", 1385 "fmt", 1386 "go/ast", 1387 "go/build", 1388 "go/doc", 1389 "go/parser", 1390 "go/scanner", 1391 "go/token", 1392 "io", 1393 "io/ioutil", 1394 "log", 1395 "math", 1396 "net/url", 1397 "os", 1398 "os/exec", 1399 "path", 1400 "path/filepath", 1401 "reflect", 1402 "regexp", 1403 "regexp/syntax", 1404 "runtime", 1405 "sort", 1406 "strconv", 1407 "strings", 1408 "sync", 1409 "sync/atomic", 1410 "syscall", 1411 "text/template", 1412 "text/template/parse", 1413 "time", 1414 "unicode", 1415 "unicode/utf16", 1416 "unicode/utf8", 1417 }; 1418 1419 static void 1420 clean(void) 1421 { 1422 int i, j, k; 1423 Buf b, path; 1424 Vec dir; 1425 1426 binit(&b); 1427 binit(&path); 1428 vinit(&dir); 1429 1430 for(i=0; i<nelem(cleantab); i++) { 1431 bpathf(&path, "%s/src/%s", goroot, cleantab[i]); 1432 xreaddir(&dir, bstr(&path)); 1433 // Remove generated files. 1434 for(j=0; j<dir.len; j++) { 1435 for(k=0; k<nelem(gentab); k++) { 1436 if(hasprefix(dir.p[j], gentab[k].nameprefix)) 1437 xremove(bpathf(&b, "%s/%s", bstr(&path), dir.p[j])); 1438 } 1439 } 1440 // Remove generated binary named for directory. 1441 if(hasprefix(cleantab[i], "cmd/")) 1442 xremove(bpathf(&b, "%s/%s", bstr(&path), cleantab[i]+4)); 1443 } 1444 1445 // remove src/runtime/z* unconditionally 1446 vreset(&dir); 1447 bpathf(&path, "%s/src/runtime", goroot); 1448 xreaddir(&dir, bstr(&path)); 1449 for(j=0; j<dir.len; j++) { 1450 if(hasprefix(dir.p[j], "z")) 1451 xremove(bpathf(&b, "%s/%s", bstr(&path), dir.p[j])); 1452 } 1453 1454 if(rebuildall) { 1455 // Remove object tree. 1456 xremoveall(bpathf(&b, "%s/pkg/obj/%s_%s", goroot, gohostos, gohostarch)); 1457 1458 // Remove installed packages and tools. 1459 xremoveall(bpathf(&b, "%s/pkg/%s_%s", goroot, gohostos, gohostarch)); 1460 xremoveall(bpathf(&b, "%s/pkg/%s_%s", goroot, goos, goarch)); 1461 xremoveall(tooldir); 1462 1463 // Remove cached version info. 1464 xremove(bpathf(&b, "%s/VERSION.cache", goroot)); 1465 } 1466 1467 bfree(&b); 1468 bfree(&path); 1469 vfree(&dir); 1470 } 1471 1472 /* 1473 * command implementations 1474 */ 1475 1476 void 1477 usage(void) 1478 { 1479 xprintf("usage: go tool dist [command]\n" 1480 "Commands are:\n" 1481 "\n" 1482 "banner print installation banner\n" 1483 "bootstrap rebuild everything\n" 1484 "clean deletes all built files\n" 1485 "env [-p] print environment (-p: include $PATH)\n" 1486 "install [dir] install individual directory\n" 1487 "version print Go version\n" 1488 "\n" 1489 "All commands take -v flags to emit extra information.\n" 1490 ); 1491 xexit(2); 1492 } 1493 1494 // The env command prints the default environment. 1495 void 1496 cmdenv(int argc, char **argv) 1497 { 1498 bool pflag; 1499 char *sep; 1500 Buf b, b1; 1501 char *format; 1502 1503 binit(&b); 1504 binit(&b1); 1505 1506 format = "%s=\"%s\"\n"; 1507 pflag = 0; 1508 ARGBEGIN{ 1509 case '9': 1510 format = "%s='%s'\n"; 1511 break; 1512 case 'p': 1513 pflag = 1; 1514 break; 1515 case 'v': 1516 vflag++; 1517 break; 1518 case 'w': 1519 format = "set %s=%s\r\n"; 1520 break; 1521 default: 1522 usage(); 1523 }ARGEND 1524 1525 if(argc > 0) 1526 usage(); 1527 1528 xprintf(format, "CC", defaultcc); 1529 xprintf(format, "CC_FOR_TARGET", defaultcctarget); 1530 xprintf(format, "GOROOT", goroot); 1531 xprintf(format, "GOBIN", gobin); 1532 xprintf(format, "GOARCH", goarch); 1533 xprintf(format, "GOOS", goos); 1534 xprintf(format, "GOHOSTARCH", gohostarch); 1535 xprintf(format, "GOHOSTOS", gohostos); 1536 xprintf(format, "GOTOOLDIR", tooldir); 1537 xprintf(format, "GOCHAR", gochar); 1538 if(streq(goarch, "arm")) 1539 xprintf(format, "GOARM", goarm); 1540 if(streq(goarch, "386")) 1541 xprintf(format, "GO386", go386); 1542 1543 if(pflag) { 1544 sep = ":"; 1545 if(streq(gohostos, "windows")) 1546 sep = ";"; 1547 xgetenv(&b, "PATH"); 1548 bprintf(&b1, "%s%s%s", gobin, sep, bstr(&b)); 1549 xprintf(format, "PATH", bstr(&b1)); 1550 } 1551 1552 bfree(&b); 1553 bfree(&b1); 1554 } 1555 1556 // The bootstrap command runs a build from scratch, 1557 // stopping at having installed the go_bootstrap command. 1558 void 1559 cmdbootstrap(int argc, char **argv) 1560 { 1561 int i; 1562 Buf b; 1563 char *oldgoos, *oldgoarch, *oldgochar; 1564 1565 binit(&b); 1566 1567 ARGBEGIN{ 1568 case 'a': 1569 rebuildall = 1; 1570 break; 1571 case 's': 1572 sflag++; 1573 break; 1574 case 'v': 1575 vflag++; 1576 break; 1577 default: 1578 usage(); 1579 }ARGEND 1580 1581 if(argc > 0) 1582 usage(); 1583 1584 if(isdir(bpathf(&b, "%s/src/pkg", goroot))) { 1585 fatal("\n\n" 1586 "The Go package sources have moved to $GOROOT/src.\n" 1587 "*** %s still exists. ***\n" 1588 "It probably contains stale files that may confuse the build.\n" 1589 "Please (check what's there and) remove it and try again.\n" 1590 "See http://golang.org/s/go14nopkg\n", bpathf(&b, "%s/src/pkg", goroot)); 1591 } 1592 1593 if(rebuildall) 1594 clean(); 1595 goversion = findgoversion(); 1596 setup(); 1597 1598 xsetenv("GOROOT", goroot); 1599 xsetenv("GOROOT_FINAL", goroot_final); 1600 1601 // For the main bootstrap, building for host os/arch. 1602 oldgoos = goos; 1603 oldgoarch = goarch; 1604 oldgochar = gochar; 1605 goos = gohostos; 1606 goarch = gohostarch; 1607 gochar = gohostchar; 1608 xsetenv("GOARCH", goarch); 1609 xsetenv("GOOS", goos); 1610 1611 for(i=0; i<nelem(buildorder); i++) { 1612 install(bprintf(&b, buildorder[i], gohostchar)); 1613 if(!streq(oldgochar, gohostchar) && xstrstr(buildorder[i], "%s")) 1614 install(bprintf(&b, buildorder[i], oldgochar)); 1615 } 1616 1617 goos = oldgoos; 1618 goarch = oldgoarch; 1619 gochar = oldgochar; 1620 xsetenv("GOARCH", goarch); 1621 xsetenv("GOOS", goos); 1622 1623 // Build runtime for actual goos/goarch too. 1624 if(!streq(goos, gohostos) || !streq(goarch, gohostarch)) 1625 install("runtime"); 1626 1627 bfree(&b); 1628 } 1629 1630 static char* 1631 defaulttarg(void) 1632 { 1633 char *p; 1634 Buf pwd, src, real_src; 1635 1636 binit(&pwd); 1637 binit(&src); 1638 binit(&real_src); 1639 1640 // xgetwd might return a path with symlinks fully resolved, and if 1641 // there happens to be symlinks in goroot, then the hasprefix test 1642 // will never succeed. Instead, we use xrealwd to get a canonical 1643 // goroot/src before the comparison to avoid this problem. 1644 xgetwd(&pwd); 1645 p = btake(&pwd); 1646 bpathf(&src, "%s/src/", goroot); 1647 xrealwd(&real_src, bstr(&src)); 1648 if(!hasprefix(p, bstr(&real_src))) 1649 fatal("current directory %s is not under %s", p, bstr(&real_src)); 1650 p += real_src.len; 1651 // guard againt xrealwd return the directory without the trailing / 1652 if(*p == slash[0]) 1653 p++; 1654 1655 bfree(&pwd); 1656 bfree(&src); 1657 bfree(&real_src); 1658 1659 return p; 1660 } 1661 1662 // Install installs the list of packages named on the command line. 1663 void 1664 cmdinstall(int argc, char **argv) 1665 { 1666 int i; 1667 1668 ARGBEGIN{ 1669 case 's': 1670 sflag++; 1671 break; 1672 case 'v': 1673 vflag++; 1674 break; 1675 default: 1676 usage(); 1677 }ARGEND 1678 1679 if(argc == 0) 1680 install(defaulttarg()); 1681 1682 for(i=0; i<argc; i++) 1683 install(argv[i]); 1684 } 1685 1686 // Clean deletes temporary objects. 1687 // Clean -i deletes the installed objects too. 1688 void 1689 cmdclean(int argc, char **argv) 1690 { 1691 ARGBEGIN{ 1692 case 'v': 1693 vflag++; 1694 break; 1695 default: 1696 usage(); 1697 }ARGEND 1698 1699 if(argc > 0) 1700 usage(); 1701 1702 clean(); 1703 } 1704 1705 // Banner prints the 'now you've installed Go' banner. 1706 void 1707 cmdbanner(int argc, char **argv) 1708 { 1709 char *pathsep, *pid, *ns; 1710 Buf b, b1, search, path; 1711 1712 ARGBEGIN{ 1713 case 'v': 1714 vflag++; 1715 break; 1716 default: 1717 usage(); 1718 }ARGEND 1719 1720 if(argc > 0) 1721 usage(); 1722 1723 binit(&b); 1724 binit(&b1); 1725 binit(&search); 1726 binit(&path); 1727 1728 xprintf("\n"); 1729 xprintf("---\n"); 1730 xprintf("Installed Go for %s/%s in %s\n", goos, goarch, goroot); 1731 xprintf("Installed commands in %s\n", gobin); 1732 1733 if(!xsamefile(goroot_final, goroot)) { 1734 // If the files are to be moved, don't check that gobin 1735 // is on PATH; assume they know what they are doing. 1736 } else if(streq(gohostos, "plan9")) { 1737 // Check that gobin is bound before /bin. 1738 readfile(&b, "#c/pid"); 1739 bsubst(&b, " ", ""); 1740 pid = btake(&b); 1741 bprintf(&b, "/proc/%s/ns", pid); 1742 ns = btake(&b); 1743 readfile(&b, ns); 1744 bprintf(&search, "bind -b %s /bin\n", gobin); 1745 if(xstrstr(bstr(&b), bstr(&search)) == nil) 1746 xprintf("*** You need to bind %s before /bin.\n", gobin); 1747 } else { 1748 // Check that gobin appears in $PATH. 1749 xgetenv(&b, "PATH"); 1750 pathsep = ":"; 1751 if(streq(gohostos, "windows")) 1752 pathsep = ";"; 1753 bprintf(&b1, "%s%s%s", pathsep, bstr(&b), pathsep); 1754 bprintf(&search, "%s%s%s", pathsep, gobin, pathsep); 1755 if(xstrstr(bstr(&b1), bstr(&search)) == nil) 1756 xprintf("*** You need to add %s to your PATH.\n", gobin); 1757 } 1758 1759 if(streq(gohostos, "darwin")) { 1760 if(isfile(bpathf(&path, "%s/cov", tooldir))) 1761 xprintf("\n" 1762 "On OS X the debuggers must be installed setgid procmod.\n" 1763 "Read and run ./sudo.bash to install the debuggers.\n"); 1764 } 1765 1766 if(!xsamefile(goroot_final, goroot)) { 1767 xprintf("\n" 1768 "The binaries expect %s to be copied or moved to %s\n", 1769 goroot, goroot_final); 1770 } 1771 1772 bfree(&b); 1773 bfree(&b1); 1774 bfree(&search); 1775 bfree(&path); 1776 } 1777 1778 // Version prints the Go version. 1779 void 1780 cmdversion(int argc, char **argv) 1781 { 1782 ARGBEGIN{ 1783 case 'v': 1784 vflag++; 1785 break; 1786 default: 1787 usage(); 1788 }ARGEND 1789 1790 if(argc > 0) 1791 usage(); 1792 1793 xprintf("%s\n", goversion); 1794 }