mirror of https://github.com/golang/go.git
build: dist-based build for Plan 9
R=rsc, iant, iant, seed CC=golang-dev https://golang.org/cl/5608059
This commit is contained in:
parent
ce30769ce3
commit
3859032980
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/rc -e
|
||||||
|
# Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
# Use of this source code is governed by a BSD-style
|
||||||
|
# license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
if(! test -f make.rc){
|
||||||
|
echo 'all.rc must be run from $GOROOT/src' >[1=2]
|
||||||
|
exit wrongdir
|
||||||
|
}
|
||||||
|
|
||||||
|
. ./make.rc --no-banner
|
||||||
|
./run.rc --no-rebuild
|
||||||
|
$GOTOOLDIR/dist banner # print build info
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/rc -e
|
||||||
|
# Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
# Use of this source code is governed by a BSD-style
|
||||||
|
# license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
eval `{go tool dist env -9}
|
||||||
|
|
||||||
|
if(! test -x $GOTOOLDIR/dist){
|
||||||
|
echo 'cannot find $GOTOOLDIR/dist; nothing to clean' >[1=2]
|
||||||
|
exit noclean
|
||||||
|
}
|
||||||
|
|
||||||
|
$GOBIN/go clean -i std
|
||||||
|
$GOTOOLDIR/dist clean
|
||||||
|
|
@ -10,7 +10,9 @@ typedef long long Time;
|
||||||
|
|
||||||
#define nil ((void*)0)
|
#define nil ((void*)0)
|
||||||
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
||||||
|
#ifndef PLAN9
|
||||||
#define USED(x) ((void)(x))
|
#define USED(x) ((void)(x))
|
||||||
|
#endif
|
||||||
|
|
||||||
// A Buf is a byte buffer, like Go's []byte.
|
// A Buf is a byte buffer, like Go's []byte.
|
||||||
typedef struct Buf Buf;
|
typedef struct Buf Buf;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ THE SOFTWARE.
|
||||||
|
|
||||||
/* command line */
|
/* command line */
|
||||||
extern char *argv0;
|
extern char *argv0;
|
||||||
#define ARGBEGIN for((argv0?0:(argv0=(*argv))),argv++,argc--;\
|
#define ARGBEGIN for((argv0=(argv0?argv0:*argv)),argv++,argc--;\
|
||||||
argv[0] && argv[0][0]=='-' && argv[0][1];\
|
argv[0] && argv[0][0]=='-' && argv[0][1];\
|
||||||
argc--, argv++) {\
|
argc--, argv++) {\
|
||||||
char *_args, *_argt;\
|
char *_args, *_argt;\
|
||||||
|
|
@ -37,7 +37,6 @@ extern char *argv0;
|
||||||
if(_args[0]=='-' && _args[1]==0){\
|
if(_args[0]=='-' && _args[1]==0){\
|
||||||
argc--; argv++; break;\
|
argc--; argv++; break;\
|
||||||
}\
|
}\
|
||||||
_argc = 0;\
|
|
||||||
while((_argc = *_args++) != 0)\
|
while((_argc = *_args++) != 0)\
|
||||||
switch(_argc)
|
switch(_argc)
|
||||||
#define ARGEND _argt=0;USED(_argt);USED(_argc);USED(_args);}USED(argv);USED(argc);
|
#define ARGEND _argt=0;USED(_argt);USED(_argc);USED(_args);}USED(argv);USED(argc);
|
||||||
|
|
|
||||||
|
|
@ -539,7 +539,7 @@ install(char *dir)
|
||||||
Buf b, b1, path;
|
Buf b, b1, path;
|
||||||
Vec compile, files, link, go, missing, clean, lib, extra;
|
Vec compile, files, link, go, missing, clean, lib, extra;
|
||||||
Time ttarg, t;
|
Time ttarg, t;
|
||||||
int i, j, k, n, doclean, targ;
|
int i, j, k, n, doclean, targ, usecpp;
|
||||||
|
|
||||||
if(vflag) {
|
if(vflag) {
|
||||||
if(!streq(goos, gohostos) || !streq(goarch, gohostarch))
|
if(!streq(goos, gohostos) || !streq(goarch, gohostarch))
|
||||||
|
|
@ -560,6 +560,7 @@ install(char *dir)
|
||||||
vinit(&lib);
|
vinit(&lib);
|
||||||
vinit(&extra);
|
vinit(&extra);
|
||||||
|
|
||||||
|
|
||||||
// path = full path to dir.
|
// path = full path to dir.
|
||||||
bpathf(&path, "%s/src/%s", goroot, dir);
|
bpathf(&path, "%s/src/%s", goroot, dir);
|
||||||
name = lastelem(dir);
|
name = lastelem(dir);
|
||||||
|
|
@ -605,7 +606,10 @@ install(char *dir)
|
||||||
if(islib) {
|
if(islib) {
|
||||||
// C library.
|
// C library.
|
||||||
vadd(&link, "ar");
|
vadd(&link, "ar");
|
||||||
vadd(&link, "rsc");
|
if(streq(gohostos, "plan9"))
|
||||||
|
vadd(&link, "rc");
|
||||||
|
else
|
||||||
|
vadd(&link, "rsc");
|
||||||
prefix = "";
|
prefix = "";
|
||||||
if(!hasprefix(name, "lib"))
|
if(!hasprefix(name, "lib"))
|
||||||
prefix = "lib";
|
prefix = "lib";
|
||||||
|
|
@ -631,14 +635,21 @@ install(char *dir)
|
||||||
vadd(&link, bpathf(&b, "%s/%s%s", tooldir, elem, exe));
|
vadd(&link, bpathf(&b, "%s/%s%s", tooldir, elem, exe));
|
||||||
} else {
|
} else {
|
||||||
// C command. Use gccargs.
|
// C command. Use gccargs.
|
||||||
vcopy(&link, gccargs.p, gccargs.len);
|
if(streq(gohostos, "plan9")) {
|
||||||
vadd(&link, "-o");
|
vadd(&link, bprintf(&b, "%sl", gohostchar));
|
||||||
targ = link.len;
|
vadd(&link, "-o");
|
||||||
vadd(&link, bpathf(&b, "%s/%s%s", tooldir, name, exe));
|
targ = link.len;
|
||||||
if(streq(gohostarch, "amd64"))
|
vadd(&link, bpathf(&b, "%s/%s", tooldir, name));
|
||||||
vadd(&link, "-m64");
|
} else {
|
||||||
else if(streq(gohostarch, "386"))
|
vcopy(&link, gccargs.p, gccargs.len);
|
||||||
vadd(&link, "-m32");
|
vadd(&link, "-o");
|
||||||
|
targ = link.len;
|
||||||
|
vadd(&link, bpathf(&b, "%s/%s%s", tooldir, name, exe));
|
||||||
|
if(streq(gohostarch, "amd64"))
|
||||||
|
vadd(&link, "-m64");
|
||||||
|
else if(streq(gohostarch, "386"))
|
||||||
|
vadd(&link, "-m32");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ttarg = mtime(link.p[targ]);
|
ttarg = mtime(link.p[targ]);
|
||||||
|
|
||||||
|
|
@ -672,6 +683,8 @@ install(char *dir)
|
||||||
bsubst(&b1, "$GOARCH", goarch);
|
bsubst(&b1, "$GOARCH", goarch);
|
||||||
p = bstr(&b1);
|
p = bstr(&b1);
|
||||||
if(hassuffix(p, ".a")) {
|
if(hassuffix(p, ".a")) {
|
||||||
|
if(streq(gohostos, "plan9") && hassuffix(p, "libbio.a"))
|
||||||
|
continue;
|
||||||
vadd(&lib, bpathf(&b, "%s", p));
|
vadd(&lib, bpathf(&b, "%s", p));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -741,6 +754,10 @@ install(char *dir)
|
||||||
}
|
}
|
||||||
files.len = n;
|
files.len = n;
|
||||||
|
|
||||||
|
// If there are no files to compile, we're done.
|
||||||
|
if(files.len == 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
for(i=0; i<lib.len && !stale; i++)
|
for(i=0; i<lib.len && !stale; i++)
|
||||||
if(mtime(lib.p[i]) > ttarg)
|
if(mtime(lib.p[i]) > ttarg)
|
||||||
stale = 1;
|
stale = 1;
|
||||||
|
|
@ -799,10 +816,10 @@ install(char *dir)
|
||||||
p = files.p[i];
|
p = files.p[i];
|
||||||
if(!hassuffix(p, ".goc"))
|
if(!hassuffix(p, ".goc"))
|
||||||
continue;
|
continue;
|
||||||
// b = path/zp but with _goarch.c instead of .goc
|
// b = path/zp but with _goos_goarch.c instead of .goc
|
||||||
bprintf(&b, "%s%sz%s", bstr(&path), slash, lastelem(p));
|
bprintf(&b, "%s%sz%s", bstr(&path), slash, lastelem(p));
|
||||||
b.len -= 4;
|
b.len -= 4;
|
||||||
bwritef(&b, "_%s.c", goarch);
|
bwritef(&b, "_%s_%s.c", goos, goarch);
|
||||||
goc2c(p, bstr(&b));
|
goc2c(p, bstr(&b));
|
||||||
vadd(&files, bstr(&b));
|
vadd(&files, bstr(&b));
|
||||||
}
|
}
|
||||||
|
|
@ -816,6 +833,20 @@ install(char *dir)
|
||||||
goto nobuild;
|
goto nobuild;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The files generated by GNU Bison use macros that aren't
|
||||||
|
// supported by the Plan 9 compilers so we have to use the
|
||||||
|
// external preprocessor when compiling.
|
||||||
|
usecpp = 0;
|
||||||
|
if(streq(gohostos, "plan9")) {
|
||||||
|
for(i=0; i<files.len; i++) {
|
||||||
|
p = files.p[i];
|
||||||
|
if(hassuffix(p, "y.tab.c") || hassuffix(p, "y.tab.h")){
|
||||||
|
usecpp = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Compile the files.
|
// Compile the files.
|
||||||
for(i=0; i<files.len; i++) {
|
for(i=0; i<files.len; i++) {
|
||||||
if(!hassuffix(files.p[i], ".c") && !hassuffix(files.p[i], ".s"))
|
if(!hassuffix(files.p[i], ".c") && !hassuffix(files.p[i], ".s"))
|
||||||
|
|
@ -825,17 +856,26 @@ install(char *dir)
|
||||||
vreset(&compile);
|
vreset(&compile);
|
||||||
if(!isgo) {
|
if(!isgo) {
|
||||||
// C library or tool.
|
// C library or tool.
|
||||||
vcopy(&compile, gccargs.p, gccargs.len);
|
if(streq(gohostos, "plan9")) {
|
||||||
vadd(&compile, "-c");
|
vadd(&compile, bprintf(&b, "%sc", gohostchar));
|
||||||
if(streq(gohostarch, "amd64"))
|
vadd(&compile, "-FTVw");
|
||||||
vadd(&compile, "-m64");
|
if(usecpp)
|
||||||
else if(streq(gohostarch, "386"))
|
vadd(&compile, "-Bp+");
|
||||||
vadd(&compile, "-m32");
|
vadd(&compile, bpathf(&b, "-I%s/include/plan9", goroot));
|
||||||
if(streq(dir, "lib9"))
|
vadd(&compile, bpathf(&b, "-I%s/include/plan9/%s", goroot, gohostarch));
|
||||||
vadd(&compile, "-DPLAN9PORT");
|
} else {
|
||||||
|
vcopy(&compile, gccargs.p, gccargs.len);
|
||||||
vadd(&compile, "-I");
|
vadd(&compile, "-c");
|
||||||
vadd(&compile, bpathf(&b, "%s/include", goroot));
|
if(streq(gohostarch, "amd64"))
|
||||||
|
vadd(&compile, "-m64");
|
||||||
|
else if(streq(gohostarch, "386"))
|
||||||
|
vadd(&compile, "-m32");
|
||||||
|
if(streq(dir, "lib9"))
|
||||||
|
vadd(&compile, "-DPLAN9PORT");
|
||||||
|
|
||||||
|
vadd(&compile, "-I");
|
||||||
|
vadd(&compile, bpathf(&b, "%s/include", goroot));
|
||||||
|
}
|
||||||
|
|
||||||
vadd(&compile, "-I");
|
vadd(&compile, "-I");
|
||||||
vadd(&compile, bstr(&path));
|
vadd(&compile, bstr(&path));
|
||||||
|
|
@ -882,7 +922,11 @@ install(char *dir)
|
||||||
doclean = 0;
|
doclean = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
b.p[b.len-1] = 'o'; // was c or s
|
// Change the last character of the output file (which was c or s).
|
||||||
|
if(streq(gohostos, "plan9"))
|
||||||
|
b.p[b.len-1] = gohostchar[0];
|
||||||
|
else
|
||||||
|
b.p[b.len-1] = 'o';
|
||||||
vadd(&compile, "-o");
|
vadd(&compile, "-o");
|
||||||
vadd(&compile, bstr(&b));
|
vadd(&compile, bstr(&b));
|
||||||
vadd(&compile, files.p[i]);
|
vadd(&compile, files.p[i]);
|
||||||
|
|
@ -923,7 +967,8 @@ install(char *dir)
|
||||||
if(!islib && !isgo) {
|
if(!islib && !isgo) {
|
||||||
// C binaries need the libraries explicitly, and -lm.
|
// C binaries need the libraries explicitly, and -lm.
|
||||||
vcopy(&link, lib.p, lib.len);
|
vcopy(&link, lib.p, lib.len);
|
||||||
vadd(&link, "-lm");
|
if(!streq(gohostos, "plan9"))
|
||||||
|
vadd(&link, "-lm");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove target before writing it.
|
// Remove target before writing it.
|
||||||
|
|
@ -981,6 +1026,16 @@ shouldbuild(char *file, char *dir)
|
||||||
Buf b;
|
Buf b;
|
||||||
Vec lines, fields;
|
Vec lines, fields;
|
||||||
|
|
||||||
|
// On Plan 9, most of the libraries are already present.
|
||||||
|
// The main exception is libmach which has been modified
|
||||||
|
// in various places to support Go object files.
|
||||||
|
if(streq(gohostos, "plan9")) {
|
||||||
|
if(streq(dir, "lib9") && !hassuffix(file, "lib9/goos.c"))
|
||||||
|
return 0;
|
||||||
|
if(streq(dir, "libbio"))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Check file name for GOOS or GOARCH.
|
// Check file name for GOOS or GOARCH.
|
||||||
name = lastelem(file);
|
name = lastelem(file);
|
||||||
for(i=0; i<nelem(okgoos); i++)
|
for(i=0; i<nelem(okgoos); i++)
|
||||||
|
|
@ -1285,6 +1340,9 @@ cmdenv(int argc, char **argv)
|
||||||
format = "%s=\"%s\"\n";
|
format = "%s=\"%s\"\n";
|
||||||
pflag = 0;
|
pflag = 0;
|
||||||
ARGBEGIN{
|
ARGBEGIN{
|
||||||
|
case '9':
|
||||||
|
format = "%s='%s'\n";
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
pflag = 1;
|
pflag = 1;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
#include "a.h"
|
#include "a.h"
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helpers for building cmd/gc.
|
* Helpers for building cmd/gc.
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
#include "a.h"
|
#include "a.h"
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helpers for building pkg/runtime.
|
* Helpers for building pkg/runtime.
|
||||||
|
|
@ -20,6 +19,8 @@ mkzversion(char *dir, char *file)
|
||||||
{
|
{
|
||||||
Buf b, out;
|
Buf b, out;
|
||||||
|
|
||||||
|
USED(dir);
|
||||||
|
|
||||||
binit(&b);
|
binit(&b);
|
||||||
binit(&out);
|
binit(&out);
|
||||||
|
|
||||||
|
|
@ -46,6 +47,8 @@ void
|
||||||
mkzgoarch(char *dir, char *file)
|
mkzgoarch(char *dir, char *file)
|
||||||
{
|
{
|
||||||
Buf b, out;
|
Buf b, out;
|
||||||
|
|
||||||
|
USED(dir);
|
||||||
|
|
||||||
binit(&b);
|
binit(&b);
|
||||||
binit(&out);
|
binit(&out);
|
||||||
|
|
@ -72,6 +75,8 @@ void
|
||||||
mkzgoos(char *dir, char *file)
|
mkzgoos(char *dir, char *file)
|
||||||
{
|
{
|
||||||
Buf b, out;
|
Buf b, out;
|
||||||
|
|
||||||
|
USED(dir);
|
||||||
|
|
||||||
binit(&b);
|
binit(&b);
|
||||||
binit(&out);
|
binit(&out);
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ static struct {
|
||||||
{"int64", 8},
|
{"int64", 8},
|
||||||
{"uint64", 8},
|
{"uint64", 8},
|
||||||
|
|
||||||
{nil},
|
{nil, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Fixed structure alignment (non-gcc only) */
|
/* Fixed structure alignment (non-gcc only) */
|
||||||
|
|
@ -570,8 +570,9 @@ write_gcc_func_header(char *package, char *name, struct params *params,
|
||||||
static void
|
static void
|
||||||
write_gcc_func_trailer(char *package, char *name, struct params *rets)
|
write_gcc_func_trailer(char *package, char *name, struct params *rets)
|
||||||
{
|
{
|
||||||
if (rets == nil)
|
if (rets == nil) {
|
||||||
;
|
// nothing to do
|
||||||
|
}
|
||||||
else if (rets->next == nil)
|
else if (rets->next == nil)
|
||||||
bwritef(output, "return %s;\n", rets->name);
|
bwritef(output, "return %s;\n", rets->name);
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,734 @@
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// These #ifdefs are being used as a substitute for
|
||||||
|
// build configuration, so that on any system, this
|
||||||
|
// tool can be built with the local equivalent of
|
||||||
|
// cc *.c
|
||||||
|
//
|
||||||
|
#ifdef PLAN9
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#undef nil
|
||||||
|
#undef nelem
|
||||||
|
#include "a.h"
|
||||||
|
|
||||||
|
// bprintf replaces the buffer with the result of the printf formatting
|
||||||
|
// and returns a pointer to the NUL-terminated buffer contents.
|
||||||
|
char*
|
||||||
|
bprintf(Buf *b, char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list arg;
|
||||||
|
char buf[4096];
|
||||||
|
|
||||||
|
breset(b);
|
||||||
|
va_start(arg, fmt);
|
||||||
|
vsnprintf(buf, sizeof buf, fmt, arg);
|
||||||
|
va_end(arg);
|
||||||
|
bwritestr(b, buf);
|
||||||
|
return bstr(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bpathf is the same as bprintf (on windows it turns / into \ after the printf).
|
||||||
|
// It returns a pointer to the NUL-terminated buffer contents.
|
||||||
|
char*
|
||||||
|
bpathf(Buf *b, char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list arg;
|
||||||
|
char buf[4096];
|
||||||
|
|
||||||
|
breset(b);
|
||||||
|
va_start(arg, fmt);
|
||||||
|
vsnprintf(buf, sizeof buf, fmt, arg);
|
||||||
|
va_end(arg);
|
||||||
|
bwritestr(b, buf);
|
||||||
|
return bstr(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bwritef is like bprintf but does not reset the buffer
|
||||||
|
// and does not return the NUL-terminated string.
|
||||||
|
void
|
||||||
|
bwritef(Buf *b, char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list arg;
|
||||||
|
char buf[4096];
|
||||||
|
|
||||||
|
va_start(arg, fmt);
|
||||||
|
vsnprintf(buf, sizeof buf, fmt, arg);
|
||||||
|
va_end(arg);
|
||||||
|
bwritestr(b, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// breadfrom appends to b all the data that can be read from fd.
|
||||||
|
static void
|
||||||
|
breadfrom(Buf *b, int fd)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
bgrow(b, 4096);
|
||||||
|
n = read(fd, b->p+b->len, 4096);
|
||||||
|
if(n < 0)
|
||||||
|
fatal("read");
|
||||||
|
if(n == 0)
|
||||||
|
break;
|
||||||
|
b->len += n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// xgetenv replaces b with the value of the named environment variable.
|
||||||
|
void
|
||||||
|
xgetenv(Buf *b, char *name)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
breset(b);
|
||||||
|
p = getenv(name);
|
||||||
|
if(p != nil)
|
||||||
|
bwritestr(b, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void genrun(Buf *b, char *dir, int mode, Vec *argv, int bg);
|
||||||
|
|
||||||
|
// run runs the command named by cmd.
|
||||||
|
// If b is not nil, run replaces b with the output of the command.
|
||||||
|
// If dir is not nil, run runs the command in that directory.
|
||||||
|
// If mode is CheckExit, run calls fatal if the command is not successful.
|
||||||
|
void
|
||||||
|
run(Buf *b, char *dir, int mode, char *cmd, ...)
|
||||||
|
{
|
||||||
|
va_list arg;
|
||||||
|
Vec argv;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
vinit(&argv);
|
||||||
|
vadd(&argv, cmd);
|
||||||
|
va_start(arg, cmd);
|
||||||
|
while((p = va_arg(arg, char*)) != nil)
|
||||||
|
vadd(&argv, p);
|
||||||
|
va_end(arg);
|
||||||
|
|
||||||
|
runv(b, dir, mode, &argv);
|
||||||
|
|
||||||
|
vfree(&argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// runv is like run but takes a vector.
|
||||||
|
void
|
||||||
|
runv(Buf *b, char *dir, int mode, Vec *argv)
|
||||||
|
{
|
||||||
|
genrun(b, dir, mode, argv, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bgrunv is like run but runs the command in the background.
|
||||||
|
// bgwait waits for pending bgrunv to finish.
|
||||||
|
void
|
||||||
|
bgrunv(char *dir, int mode, Vec *argv)
|
||||||
|
{
|
||||||
|
genrun(nil, dir, mode, argv, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAXBG 4 /* maximum number of jobs to run at once */
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
int pid;
|
||||||
|
int mode;
|
||||||
|
char *cmd;
|
||||||
|
Buf *b;
|
||||||
|
} bg[MAXBG];
|
||||||
|
static int nbg;
|
||||||
|
static int maxnbg = nelem(bg);
|
||||||
|
|
||||||
|
static void bgwait1(void);
|
||||||
|
|
||||||
|
// genrun is the generic run implementation.
|
||||||
|
static void
|
||||||
|
genrun(Buf *b, char *dir, int mode, Vec *argv, int wait)
|
||||||
|
{
|
||||||
|
int i, p[2], pid;
|
||||||
|
Buf b1, cmd;
|
||||||
|
char *q;
|
||||||
|
|
||||||
|
while(nbg >= maxnbg)
|
||||||
|
bgwait1();
|
||||||
|
|
||||||
|
binit(&b1);
|
||||||
|
binit(&cmd);
|
||||||
|
|
||||||
|
if(!isabs(argv->p[0])) {
|
||||||
|
bpathf(&b1, "/bin/%s", argv->p[0]);
|
||||||
|
free(argv->p[0]);
|
||||||
|
argv->p[0] = xstrdup(bstr(&b1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a copy of the command to show in a log.
|
||||||
|
// Substitute $WORK for the work directory.
|
||||||
|
for(i=0; i<argv->len; i++) {
|
||||||
|
if(i > 0)
|
||||||
|
bwritestr(&cmd, " ");
|
||||||
|
q = argv->p[i];
|
||||||
|
if(workdir != nil && hasprefix(q, workdir)) {
|
||||||
|
bwritestr(&cmd, "$WORK");
|
||||||
|
q += strlen(workdir);
|
||||||
|
}
|
||||||
|
bwritestr(&cmd, q);
|
||||||
|
}
|
||||||
|
if(vflag > 1)
|
||||||
|
xprintf("%s\n", bstr(&cmd));
|
||||||
|
|
||||||
|
if(b != nil) {
|
||||||
|
breset(b);
|
||||||
|
if(pipe(p) < 0)
|
||||||
|
fatal("pipe");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(pid = fork()) {
|
||||||
|
case -1:
|
||||||
|
fatal("fork");
|
||||||
|
case 0:
|
||||||
|
if(b != nil) {
|
||||||
|
close(0);
|
||||||
|
close(p[0]);
|
||||||
|
dup(p[1], 1);
|
||||||
|
dup(p[1], 2);
|
||||||
|
if(p[1] > 2)
|
||||||
|
close(p[1]);
|
||||||
|
}
|
||||||
|
if(dir != nil) {
|
||||||
|
if(chdir(dir) < 0) {
|
||||||
|
fprint(2, "chdir: %r\n");
|
||||||
|
_exits("chdir");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vadd(argv, nil);
|
||||||
|
exec(argv->p[0], argv->p);
|
||||||
|
fprint(2, "%s\n", bstr(&cmd));
|
||||||
|
fprint(2, "exec: %r\n");
|
||||||
|
_exits("exec");
|
||||||
|
}
|
||||||
|
if(b != nil) {
|
||||||
|
close(p[1]);
|
||||||
|
breadfrom(b, p[0]);
|
||||||
|
close(p[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nbg < 0)
|
||||||
|
fatal("bad bookkeeping");
|
||||||
|
bg[nbg].pid = pid;
|
||||||
|
bg[nbg].mode = mode;
|
||||||
|
bg[nbg].cmd = btake(&cmd);
|
||||||
|
bg[nbg].b = b;
|
||||||
|
nbg++;
|
||||||
|
|
||||||
|
if(wait)
|
||||||
|
bgwait();
|
||||||
|
|
||||||
|
bfree(&cmd);
|
||||||
|
bfree(&b1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bgwait1 waits for a single background job.
|
||||||
|
static void
|
||||||
|
bgwait1(void)
|
||||||
|
{
|
||||||
|
Waitmsg *w;
|
||||||
|
int i, mode;
|
||||||
|
char *cmd;
|
||||||
|
Buf *b;
|
||||||
|
|
||||||
|
w = wait();
|
||||||
|
if(w == nil)
|
||||||
|
fatal("wait");
|
||||||
|
|
||||||
|
for(i=0; i<nbg; i++)
|
||||||
|
if(bg[i].pid == w->pid)
|
||||||
|
goto ok;
|
||||||
|
fatal("wait: unexpected pid");
|
||||||
|
|
||||||
|
ok:
|
||||||
|
cmd = bg[i].cmd;
|
||||||
|
mode = bg[i].mode;
|
||||||
|
bg[i].pid = 0;
|
||||||
|
b = bg[i].b;
|
||||||
|
bg[i].b = nil;
|
||||||
|
bg[i] = bg[--nbg];
|
||||||
|
|
||||||
|
if(mode == CheckExit && w->msg[0]) {
|
||||||
|
if(b != nil)
|
||||||
|
xprintf("%s\n", bstr(b));
|
||||||
|
fatal("FAILED: %s", cmd);
|
||||||
|
}
|
||||||
|
xfree(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bgwait waits for all the background jobs.
|
||||||
|
void
|
||||||
|
bgwait(void)
|
||||||
|
{
|
||||||
|
while(nbg > 0)
|
||||||
|
bgwait1();
|
||||||
|
}
|
||||||
|
|
||||||
|
// xgetwd replaces b with the current directory.
|
||||||
|
void
|
||||||
|
xgetwd(Buf *b)
|
||||||
|
{
|
||||||
|
char buf[4096];
|
||||||
|
|
||||||
|
breset(b);
|
||||||
|
if(getwd(buf, sizeof buf) == nil)
|
||||||
|
fatal("getwd");
|
||||||
|
bwritestr(b, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xrealwd replaces b with the 'real' name for the given path.
|
||||||
|
// real is defined as what getcwd returns in that directory.
|
||||||
|
void
|
||||||
|
xrealwd(Buf *b, char *path)
|
||||||
|
{
|
||||||
|
char buf[4096];
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(path, OREAD);
|
||||||
|
if(fd2path(fd, buf, sizeof buf) < 0)
|
||||||
|
fatal("fd2path");
|
||||||
|
close(fd);
|
||||||
|
breset(b);
|
||||||
|
bwritestr(b, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// isdir reports whether p names an existing directory.
|
||||||
|
bool
|
||||||
|
isdir(char *p)
|
||||||
|
{
|
||||||
|
Dir *d;
|
||||||
|
ulong mode;
|
||||||
|
|
||||||
|
d = dirstat(p);
|
||||||
|
if(d == nil)
|
||||||
|
return 0;
|
||||||
|
mode = d->mode;
|
||||||
|
free(d);
|
||||||
|
return (mode & DMDIR) == DMDIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// isfile reports whether p names an existing file.
|
||||||
|
bool
|
||||||
|
isfile(char *p)
|
||||||
|
{
|
||||||
|
Dir *d;
|
||||||
|
ulong mode;
|
||||||
|
|
||||||
|
d = dirstat(p);
|
||||||
|
if(d == nil)
|
||||||
|
return 0;
|
||||||
|
mode = d->mode;
|
||||||
|
free(d);
|
||||||
|
return (mode & DMDIR) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mtime returns the modification time of the file p.
|
||||||
|
Time
|
||||||
|
mtime(char *p)
|
||||||
|
{
|
||||||
|
Dir *d;
|
||||||
|
ulong t;
|
||||||
|
|
||||||
|
d = dirstat(p);
|
||||||
|
if(d == nil)
|
||||||
|
return 0;
|
||||||
|
t = d->mtime;
|
||||||
|
free(d);
|
||||||
|
return (Time)t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// isabs reports whether p is an absolute path.
|
||||||
|
bool
|
||||||
|
isabs(char *p)
|
||||||
|
{
|
||||||
|
return hasprefix(p, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
// readfile replaces b with the content of the named file.
|
||||||
|
void
|
||||||
|
readfile(Buf *b, char *file)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
breset(b);
|
||||||
|
fd = open(file, OREAD);
|
||||||
|
if(fd < 0)
|
||||||
|
fatal("open %s", file);
|
||||||
|
breadfrom(b, fd);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// writefile writes b to the named file, creating it if needed.
|
||||||
|
void
|
||||||
|
writefile(Buf *b, char *file, int exec)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
Dir d;
|
||||||
|
|
||||||
|
fd = create(file, ORDWR, 0666);
|
||||||
|
if(fd < 0)
|
||||||
|
fatal("create %s", file);
|
||||||
|
if(write(fd, b->p, b->len) != b->len)
|
||||||
|
fatal("short write");
|
||||||
|
if(exec) {
|
||||||
|
nulldir(&d);
|
||||||
|
d.mode = 0755;
|
||||||
|
dirfwstat(fd, &d);
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xmkdir creates the directory p.
|
||||||
|
void
|
||||||
|
xmkdir(char *p)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if(isdir(p))
|
||||||
|
return;
|
||||||
|
fd = create(p, OREAD, 0777|DMDIR);
|
||||||
|
close(fd);
|
||||||
|
if(fd < 0)
|
||||||
|
fatal("mkdir %s", p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xmkdirall creates the directory p and its parents, as needed.
|
||||||
|
void
|
||||||
|
xmkdirall(char *p)
|
||||||
|
{
|
||||||
|
char *q;
|
||||||
|
|
||||||
|
if(isdir(p))
|
||||||
|
return;
|
||||||
|
q = strrchr(p, '/');
|
||||||
|
if(q != nil) {
|
||||||
|
*q = '\0';
|
||||||
|
xmkdirall(p);
|
||||||
|
*q = '/';
|
||||||
|
}
|
||||||
|
xmkdir(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xremove removes the file p.
|
||||||
|
void
|
||||||
|
xremove(char *p)
|
||||||
|
{
|
||||||
|
if(vflag > 2)
|
||||||
|
xprintf("rm %s\n", p);
|
||||||
|
remove(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xremoveall removes the file or directory tree rooted at p.
|
||||||
|
void
|
||||||
|
xremoveall(char *p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Buf b;
|
||||||
|
Vec dir;
|
||||||
|
|
||||||
|
binit(&b);
|
||||||
|
vinit(&dir);
|
||||||
|
|
||||||
|
if(isdir(p)) {
|
||||||
|
xreaddir(&dir, p);
|
||||||
|
for(i=0; i<dir.len; i++) {
|
||||||
|
bprintf(&b, "%s/%s", p, dir.p[i]);
|
||||||
|
xremoveall(bstr(&b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(vflag > 2)
|
||||||
|
xprintf("rm %s\n", p);
|
||||||
|
remove(p);
|
||||||
|
|
||||||
|
bfree(&b);
|
||||||
|
vfree(&dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xreaddir replaces dst with a list of the names of the files in dir.
|
||||||
|
// The names are relative to dir; they are not full paths.
|
||||||
|
void
|
||||||
|
xreaddir(Vec *dst, char *dir)
|
||||||
|
{
|
||||||
|
Dir *d;
|
||||||
|
int fd, i, n;
|
||||||
|
|
||||||
|
vreset(dst);
|
||||||
|
|
||||||
|
fd = open(dir, OREAD);
|
||||||
|
if(fd < 0)
|
||||||
|
fatal("open %s", dir);
|
||||||
|
n = dirreadall(fd, &d);
|
||||||
|
for(i=0; i<n; i++)
|
||||||
|
vadd(dst, d[i].name);
|
||||||
|
free(d);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xworkdir creates a new temporary directory to hold object files
|
||||||
|
// and returns the name of that directory.
|
||||||
|
char*
|
||||||
|
xworkdir(void)
|
||||||
|
{
|
||||||
|
Buf b;
|
||||||
|
char *p;
|
||||||
|
int fd, tries;
|
||||||
|
|
||||||
|
binit(&b);
|
||||||
|
|
||||||
|
fd = 0;
|
||||||
|
for(tries=0; tries<1000; tries++) {
|
||||||
|
bprintf(&b, "/tmp/go-cbuild-%06x", nrand((1<<24)-1));
|
||||||
|
fd = create(bstr(&b), OREAD|OEXCL, 0700|DMDIR);
|
||||||
|
if(fd >= 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
fatal("xworkdir create");
|
||||||
|
|
||||||
|
done:
|
||||||
|
close(fd);
|
||||||
|
p = btake(&b);
|
||||||
|
|
||||||
|
bfree(&b);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fatal prints an error message to standard error and exits.
|
||||||
|
void
|
||||||
|
fatal(char *msg, ...)
|
||||||
|
{
|
||||||
|
char buf[ERRMAX];
|
||||||
|
va_list arg;
|
||||||
|
|
||||||
|
rerrstr(buf, sizeof buf);
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
fprintf(stderr, "go tool dist: ");
|
||||||
|
va_start(arg, msg);
|
||||||
|
vfprintf(stderr, msg, arg);
|
||||||
|
va_end(arg);
|
||||||
|
|
||||||
|
if(buf[0])
|
||||||
|
fprintf(stderr, ": %s", buf);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
|
bgwait();
|
||||||
|
exits(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xmalloc returns a newly allocated zeroed block of n bytes of memory.
|
||||||
|
// It calls fatal if it runs out of memory.
|
||||||
|
void*
|
||||||
|
xmalloc(int n)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
p = malloc(n);
|
||||||
|
if(p == nil)
|
||||||
|
fatal("out of memory");
|
||||||
|
memset(p, 0, n);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// xstrdup returns a newly allocated copy of p.
|
||||||
|
// It calls fatal if it runs out of memory.
|
||||||
|
char*
|
||||||
|
xstrdup(char *p)
|
||||||
|
{
|
||||||
|
p = strdup(p);
|
||||||
|
if(p == nil)
|
||||||
|
fatal("out of memory");
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// xrealloc grows the allocation p to n bytes and
|
||||||
|
// returns the new (possibly moved) pointer.
|
||||||
|
// It calls fatal if it runs out of memory.
|
||||||
|
void*
|
||||||
|
xrealloc(void *p, int n)
|
||||||
|
{
|
||||||
|
p = realloc(p, n);
|
||||||
|
if(p == nil)
|
||||||
|
fatal("out of memory");
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// xfree frees the result returned by xmalloc, xstrdup, or xrealloc.
|
||||||
|
void
|
||||||
|
xfree(void *p)
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// hassuffix reports whether p ends with suffix.
|
||||||
|
bool
|
||||||
|
hassuffix(char *p, char *suffix)
|
||||||
|
{
|
||||||
|
int np, ns;
|
||||||
|
|
||||||
|
np = strlen(p);
|
||||||
|
ns = strlen(suffix);
|
||||||
|
return np >= ns && strcmp(p+np-ns, suffix) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hasprefix reports whether p begins wtih prefix.
|
||||||
|
bool
|
||||||
|
hasprefix(char *p, char *prefix)
|
||||||
|
{
|
||||||
|
return strncmp(p, prefix, strlen(prefix)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// contains reports whether sep appears in p.
|
||||||
|
bool
|
||||||
|
contains(char *p, char *sep)
|
||||||
|
{
|
||||||
|
return strstr(p, sep) != nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// streq reports whether p and q are the same string.
|
||||||
|
bool
|
||||||
|
streq(char *p, char *q)
|
||||||
|
{
|
||||||
|
return strcmp(p, q) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// lastelem returns the final path element in p.
|
||||||
|
char*
|
||||||
|
lastelem(char *p)
|
||||||
|
{
|
||||||
|
char *out;
|
||||||
|
|
||||||
|
out = p;
|
||||||
|
for(; *p; p++)
|
||||||
|
if(*p == '/')
|
||||||
|
out = p+1;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// xmemmove copies n bytes from src to dst.
|
||||||
|
void
|
||||||
|
xmemmove(void *dst, void *src, int n)
|
||||||
|
{
|
||||||
|
memmove(dst, src, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xmemcmp compares the n-byte regions starting at a and at b.
|
||||||
|
int
|
||||||
|
xmemcmp(void *a, void *b, int n)
|
||||||
|
{
|
||||||
|
return memcmp(a, b, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xstrlen returns the length of the NUL-terminated string at p.
|
||||||
|
int
|
||||||
|
xstrlen(char *p)
|
||||||
|
{
|
||||||
|
return strlen(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xexit exits the process with return code n.
|
||||||
|
void
|
||||||
|
xexit(int n)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
snprintf(buf, sizeof buf, "%d", n);
|
||||||
|
exits(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xatexit schedules the exit-handler f to be run when the program exits.
|
||||||
|
void
|
||||||
|
xatexit(void (*f)(void))
|
||||||
|
{
|
||||||
|
atexit(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xprintf prints a message to standard output.
|
||||||
|
void
|
||||||
|
xprintf(char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list arg;
|
||||||
|
|
||||||
|
va_start(arg, fmt);
|
||||||
|
vprintf(fmt, arg);
|
||||||
|
va_end(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xsetenv sets the environment variable $name to the given value.
|
||||||
|
void
|
||||||
|
xsetenv(char *name, char *value)
|
||||||
|
{
|
||||||
|
putenv(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// main takes care of OS-specific startup and dispatches to xmain.
|
||||||
|
void
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
Buf b;
|
||||||
|
|
||||||
|
setvbuf(stdout, nil, _IOLBF, BUFSIZ);
|
||||||
|
setvbuf(stderr, nil, _IOLBF, BUFSIZ);
|
||||||
|
|
||||||
|
binit(&b);
|
||||||
|
|
||||||
|
rfork(RFENVG);
|
||||||
|
|
||||||
|
slash = "/";
|
||||||
|
gohostos = "plan9";
|
||||||
|
|
||||||
|
xgetenv(&b, "objtype");
|
||||||
|
if(b.len == 0)
|
||||||
|
fatal("$objtype is unset");
|
||||||
|
gohostarch = btake(&b);
|
||||||
|
|
||||||
|
xgetenv(&b, "GOBIN");
|
||||||
|
if(b.len == 0){
|
||||||
|
bpathf(&b, "/%s/bin", gohostarch);
|
||||||
|
xsetenv("GOBIN", bstr(&b));
|
||||||
|
}
|
||||||
|
|
||||||
|
srand(time(0)+getpid());
|
||||||
|
init();
|
||||||
|
xmain(argc, argv);
|
||||||
|
|
||||||
|
bfree(&b);
|
||||||
|
exits(nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xqsort is a wrapper for the C standard qsort.
|
||||||
|
void
|
||||||
|
xqsort(void *data, int n, int elemsize, int (*cmp)(const void*, const void*))
|
||||||
|
{
|
||||||
|
qsort(data, n, elemsize, cmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xstrcmp compares the NUL-terminated strings a and b.
|
||||||
|
int
|
||||||
|
xstrcmp(char *a, char *b)
|
||||||
|
{
|
||||||
|
return strcmp(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xstrstr returns a pointer to the first occurrence of b in a.
|
||||||
|
char*
|
||||||
|
xstrstr(char *a, char *b)
|
||||||
|
{
|
||||||
|
return strstr(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xstrrchr returns a pointer to the final occurrence of c in p.
|
||||||
|
char*
|
||||||
|
xstrrchr(char *p, int c)
|
||||||
|
{
|
||||||
|
return strrchr(p, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PLAN9
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
#!/bin/rc -e
|
||||||
|
# Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
# Use of this source code is governed by a BSD-style
|
||||||
|
# license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
# Environment variables that control make.rc:
|
||||||
|
#
|
||||||
|
# GOROOT_FINAL: The expected final Go root, baked into binaries.
|
||||||
|
# The default is the location of the Go tree during the build.
|
||||||
|
#
|
||||||
|
# GOHOSTARCH: The architecture for host tools (compilers and
|
||||||
|
# binaries). Binaries of this type must be executable on the current
|
||||||
|
# system, so the only common reason to set this is to set
|
||||||
|
# GOHOSTARCH=386 on an amd64 machine.
|
||||||
|
#
|
||||||
|
# GOARCH: The target architecture for installed packages and tools.
|
||||||
|
#
|
||||||
|
# GOOS: The target operating system for installed packages and tools.
|
||||||
|
#
|
||||||
|
# GO_GCFLAGS: Additional 5g/6g/8g arguments to use when
|
||||||
|
# building the packages and commands.
|
||||||
|
#
|
||||||
|
# GO_LDFLAGS: Additional 5l/6l/8l arguments to use when
|
||||||
|
# building the commands.
|
||||||
|
#
|
||||||
|
# CGO_ENABLED: Setting this to 0 disables the use of cgo
|
||||||
|
# in the built and installed packages and tools.
|
||||||
|
|
||||||
|
rfork e
|
||||||
|
if(! test -f run.bash){
|
||||||
|
echo 'make.rc must be run from $GOROOT/src' >[1=2]
|
||||||
|
exit wrongdir
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clean old generated file that will cause problems in the build.
|
||||||
|
rm -rf ./pkg/runtime/runtime_defs.go
|
||||||
|
|
||||||
|
# Determine the host compiler toolchain.
|
||||||
|
eval `{grep '^(CC|LD|O)=' /$objtype/mkfile}
|
||||||
|
|
||||||
|
echo '# Building C bootstrap tool.'
|
||||||
|
echo cmd/dist
|
||||||
|
GOROOT = `{cd .. && pwd}
|
||||||
|
if(! ~ $#GOROOT_FINAL 1)
|
||||||
|
GOROOT_FINAL = $GOROOT
|
||||||
|
DEFGOROOT='-DGOROOT_FINAL="'$GOROOT_FINAL'"'
|
||||||
|
|
||||||
|
for(i in cmd/dist/*.c)
|
||||||
|
$CC -FTVwp+ -DPLAN9 $DEFGOROOT $i
|
||||||
|
$LD -o cmd/dist/dist *.$O
|
||||||
|
rm *.$O
|
||||||
|
|
||||||
|
eval `{./cmd/dist/dist env -9}
|
||||||
|
echo
|
||||||
|
|
||||||
|
if(~ $1 --dist-tool){
|
||||||
|
# Stop after building dist tool.
|
||||||
|
mkdir -p $GOTOOLDIR
|
||||||
|
if(! ~ $2 '')
|
||||||
|
cp cmd/dist/dist $2
|
||||||
|
mv cmd/dist/dist $GOTOOLDIR/dist
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '# Building compilers and Go bootstrap tool for host,' $GOHOSTOS/$GOHOSTARCH^.
|
||||||
|
buildall = -a
|
||||||
|
if(~ $1 --no-clean)
|
||||||
|
buildall = ()
|
||||||
|
./cmd/dist/dist bootstrap $buildall -v # builds go_bootstrap
|
||||||
|
# Delay move of dist tool to now, because bootstrap may clear tool directory.
|
||||||
|
mv cmd/dist/dist $GOTOOLDIR/dist
|
||||||
|
$GOTOOLDIR/go_bootstrap clean -i std
|
||||||
|
echo
|
||||||
|
|
||||||
|
# TODO(ality): remove the -p flag once the exec/await/RFNOTEG race is fixed.
|
||||||
|
|
||||||
|
if(! ~ $GOHOSTARCH $GOARCH || ! ~ $GOHOSTOS $GOOS){
|
||||||
|
echo '# Building packages and commands for host,' $GOHOSTOS/$GOHOSTARCH^.
|
||||||
|
GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH \
|
||||||
|
$GOTOOLDIR/go_bootstrap install -gcflags $"GO_GCFLAGS -ldflags $"GO_LDFLAGS -v -p 1 std
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '# Building packages and commands for' $GOOS/$GOARCH^.
|
||||||
|
$GOTOOLDIR/go_bootstrap install -gcflags $"GO_GCFLAGS -ldflags $"GO_LDFLAGS -v -p 1 std
|
||||||
|
echo
|
||||||
|
|
||||||
|
rm -f $GOTOOLDIR/go_bootstrap
|
||||||
|
|
||||||
|
if(! ~ $1 --no-banner)
|
||||||
|
$GOTOOLDIR/dist banner
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
#!/bin/rc -e
|
||||||
|
# Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
# Use of this source code is governed by a BSD-style
|
||||||
|
# license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
eval `{go env -9}
|
||||||
|
|
||||||
|
# allow all.rc to avoid double-build of everything
|
||||||
|
rebuild = true
|
||||||
|
if(~ $1 --no-rebuild)
|
||||||
|
shift
|
||||||
|
if not {
|
||||||
|
echo '# Building packages and commands.'
|
||||||
|
time go install -a -v -p 1 std
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '# Testing packages.'
|
||||||
|
time go test std -short -timeout 120s
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo '# GOMAXPROCS=2 runtime -cpu=1,2,4'
|
||||||
|
GOMAXPROCS=2 go test runtime -short -timeout 120s -cpu 1,2,4
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo '# sync -cpu=10'
|
||||||
|
go test sync -short -timeout 120s -cpu 10
|
||||||
|
echo
|
||||||
|
|
||||||
|
fn xcd {
|
||||||
|
echo
|
||||||
|
echo '#' $1
|
||||||
|
cd $"GOROOT/src/$1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo '#' ../misc/dashboard/builder ../misc/goplay
|
||||||
|
go build ../misc/dashboard/builder ../misc/gplay
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo '#' ../test/bench/go1
|
||||||
|
go test ../test/bench/go1
|
||||||
|
|
||||||
|
@{
|
||||||
|
xcd ../test
|
||||||
|
time go run run.go
|
||||||
|
}
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo ALL TESTS PASSED
|
||||||
Loading…
Reference in New Issue