static bool shouldbuild(char*, char*);
static void copy(char*, char*, int);
+static void dopack(char*, char*, char**, int);
static char *findgoversion(void);
// The known architecture letters.
install(char *dir)
{
char *name, *p, *elem, *prefix, *exe;
- bool islib, ispkg, isgo, stale;
+ bool islib, ispkg, isgo, stale, ispackcmd;
Buf b, b1, path;
Vec compile, files, link, go, missing, clean, lib, extra;
Time ttarg, t;
// Start final link command line.
// Note: code below knows that link.p[targ] is the target.
+ ispackcmd = 0;
if(islib) {
// C library.
vadd(&link, "ar");
vadd(&link, bpathf(&b, "%s/pkg/obj/%s_%s/%s%s.a", goroot, gohostos, gohostarch, prefix, name));
} else if(ispkg) {
// Go library (package).
- vadd(&link, bpathf(&b, "%s/pack", tooldir));
- vadd(&link, "grc");
+ ispackcmd = 1;
+ vadd(&link, "pack"); // program name - unused here, but all the other cases record one
p = bprintf(&b, "%s/pkg/%s_%s/%s", goroot, goos, goarch, dir+4);
*xstrrchr(p, '/') = '\0';
xmkdirall(p);
vreset(&compile);
vadd(&compile, bpathf(&b, "%s/%sg", tooldir, gochar));
- bpathf(&b, "%s/_go_.%s", workdir, gochar);
+ bpathf(&b, "%s/_go_.a", workdir);
+ vadd(&compile, "-pack");
vadd(&compile, "-o");
vadd(&compile, bstr(&b));
vadd(&clean, bstr(&b));
- vadd(&link, bstr(&b));
+ if(!ispackcmd)
+ vadd(&link, bstr(&b));
vadd(&compile, "-p");
if(hasprefix(dir, "pkg/"))
vcopy(&compile, go.p, go.len);
runv(nil, bstr(&path), CheckExit, &compile);
+
+ if(ispackcmd) {
+ xremove(link.p[targ]);
+ dopack(link.p[targ], bstr(&b), &link.p[targ+1], link.len - (targ+1));
+ goto nobuild;
+ }
}
if(!islib && !isgo) {
bfree(&b);
}
+// dopack copies the package src to dst,
+// appending the files listed in extra.
+// The archive format is the traditional Unix ar format.
+static void
+dopack(char *dst, char *src, char **extra, int nextra)
+{
+ int i;
+ char c, *p, *q;
+ Buf b, bdst;
+
+ binit(&b);
+ binit(&bdst);
+
+ readfile(&bdst, src);
+ for(i=0; i<nextra; i++) {
+ readfile(&b, extra[i]);
+ // find last path element for archive member name
+ p = xstrrchr(extra[i], '/');
+ if(p)
+ p++;
+ q = xstrrchr(extra[i], '\\');
+ if(q) {
+ q++;
+ if(p == nil || q > p)
+ p = q;
+ }
+ if(p == nil)
+ p = extra[i];
+ bwritef(&bdst, "%-16.16s%-12d%-6d%-6d%-8o%-10d`\n", p, 0, 0, 0, 0644, b.len);
+ bwriteb(&bdst, &b);
+ if(b.len&1) {
+ c = 0;
+ bwrite(&bdst, &c, 1);
+ }
+ }
+
+ writefile(&bdst, dst, 0);
+
+ bfree(&b);
+ bfree(&bdst);
+}
+
// buildorder records the order of builds for the 'go bootstrap' command.
static char *buildorder[] = {
"lib9",