mirror of
https://github.com/golang/go
synced 2024-11-05 11:46:12 -07:00
build packages in obj/ subdirectory that mimics $GOROOT/pkg.
for example, if building in src/lib/container, objects go in obj/container/, so that 6g -Iobj will find "container/vector". install packages in hierarchy in $GOROOT. this change only updates gobuild. another change will have to update all the sources to refer to "container/vector" etc and regenerate all the Makefiles. there are some pretty lame functions here (e.g., Mkdir, Remove, the Getenv("PWD")) but i will implement better ones in another CL. R=r DELTA=117 (99 added, 2 deleted, 16 changed) OCL=27550 CL=27574
This commit is contained in:
parent
3761da2d01
commit
0f153ec6b4
@ -46,14 +46,29 @@ $(O1): newpkg
|
|||||||
$(O2): a1
|
$(O2): a1
|
||||||
$(O3): a2
|
$(O3): a2
|
||||||
|
|
||||||
gobuild: main.$O gobuild.a
|
# zzgobuild is a fake target that will always run, even if
|
||||||
|
# "gobuild" existed at the beginning of the make.
|
||||||
|
# The problem is that if you "make install" and install
|
||||||
|
# depends on gobuild and this rule says gobuild,
|
||||||
|
# and gobuild.a depends on phases, "phases" gets
|
||||||
|
# run, which cleans everything and then rebuilds
|
||||||
|
# gobuild.a. So now make thinks gobuild was up to date
|
||||||
|
# to begin with (and it ran "phases" just for good measure)
|
||||||
|
# but in fact gobuild is gone ("phases" removed it).
|
||||||
|
#
|
||||||
|
# Calling the target zzgobuild instead means that
|
||||||
|
# make will always run this rule, rebuilding gobuild
|
||||||
|
# before trying to install it. Sigh.
|
||||||
|
zzgobuild: main.$O gobuild.a
|
||||||
$(LD) -o gobuild main.$O
|
$(LD) -o gobuild main.$O
|
||||||
|
|
||||||
main.$O: gobuild.a
|
gobuild: zzgobuild
|
||||||
|
|
||||||
|
main.$O: phases
|
||||||
|
|
||||||
nuke: clean
|
nuke: clean
|
||||||
rm -f $(HOME)/bin/gobuild
|
rm -f $(HOME)/bin/gobuild
|
||||||
|
|
||||||
install: gobuild
|
install: zzgobuild
|
||||||
cp gobuild $(HOME)/bin/gobuild
|
cp gobuild $(HOME)/bin/gobuild
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ type Phase struct {
|
|||||||
type Info struct {
|
type Info struct {
|
||||||
Args []string;
|
Args []string;
|
||||||
Char string;
|
Char string;
|
||||||
|
Dir string;
|
||||||
|
ObjDir string;
|
||||||
Pkgmap map[string] *Pkg;
|
Pkgmap map[string] *Pkg;
|
||||||
Packages []*Pkg;
|
Packages []*Pkg;
|
||||||
Files map[string] *File;
|
Files map[string] *File;
|
||||||
@ -99,6 +101,30 @@ func (a FileArray) Swap(i, j int) {
|
|||||||
a[i], a[j] = a[j], a[i]
|
a[i], a[j] = a[j], a[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If current directory is under $GOROOT/src/lib, return the
|
||||||
|
// path relative to there. Otherwise return "".
|
||||||
|
func PkgDir() string {
|
||||||
|
goroot, err := os.Getenv("GOROOT");
|
||||||
|
if err != nil || goroot == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
srcroot := path.Clean(goroot + "/src/lib/");
|
||||||
|
pwd, err1 := os.Getenv("PWD"); // TODO(rsc): real pwd
|
||||||
|
if err1 != nil || pwd == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if pwd == srcroot {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
n := len(srcroot);
|
||||||
|
if len(pwd) < n || pwd[n] != '/' || pwd[0:n] != srcroot {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := pwd[n+1:len(pwd)];
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
func ScanFiles(filenames []string) *Info {
|
func ScanFiles(filenames []string) *Info {
|
||||||
// Build list of imports, local packages, and files.
|
// Build list of imports, local packages, and files.
|
||||||
// Exclude *_test.go and anything in package main.
|
// Exclude *_test.go and anything in package main.
|
||||||
@ -106,7 +132,9 @@ func ScanFiles(filenames []string) *Info {
|
|||||||
|
|
||||||
z := new(Info);
|
z := new(Info);
|
||||||
z.Args = sys.Args;
|
z.Args = sys.Args;
|
||||||
z.Char = theChar;
|
z.Dir = PkgDir();
|
||||||
|
z.Char = theChar; // for template
|
||||||
|
z.ObjDir = ObjDir; // for template
|
||||||
z.Pkgmap = make(map[string] *Pkg);
|
z.Pkgmap = make(map[string] *Pkg);
|
||||||
z.Files = make(map[string] *File);
|
z.Files = make(map[string] *File);
|
||||||
z.Imports = make(map[string] bool);
|
z.Imports = make(map[string] bool);
|
||||||
@ -114,7 +142,7 @@ func ScanFiles(filenames []string) *Info {
|
|||||||
// Read Go files to find out packages and imports.
|
// Read Go files to find out packages and imports.
|
||||||
var pkg *Pkg;
|
var pkg *Pkg;
|
||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
if strings.HasSuffix(filename, "_test.go") {
|
if strings.Index(filename, "_test.") >= 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
f := new(File);
|
f := new(File);
|
||||||
@ -168,6 +196,14 @@ func ScanFiles(filenames []string) *Info {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update destination directory.
|
||||||
|
// If destination directory has same
|
||||||
|
// name as package name, cut it off.
|
||||||
|
dir, name := path.Split(z.Dir);
|
||||||
|
if len(z.Packages) == 1 && z.Packages[0].Name == name {
|
||||||
|
z.Dir = dir;
|
||||||
|
}
|
||||||
|
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,9 +212,14 @@ func PackageObj(pkg string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (z *Info) Build() {
|
func (z *Info) Build() {
|
||||||
|
// Create empty object directory tree.
|
||||||
|
RemoveAll(ObjDir);
|
||||||
|
obj := path.Join(ObjDir, z.Dir) + "/";
|
||||||
|
MkdirAll(obj);
|
||||||
|
|
||||||
// Create empty archives.
|
// Create empty archives.
|
||||||
for pkgname := range z.Pkgmap {
|
for pkgname := range z.Pkgmap {
|
||||||
ar := PackageObj(pkgname);
|
ar := obj + PackageObj(pkgname);
|
||||||
os.Remove(ar);
|
os.Remove(ar);
|
||||||
Archive(ar, nil);
|
Archive(ar, nil);
|
||||||
}
|
}
|
||||||
@ -239,7 +280,7 @@ func (z *Info) Build() {
|
|||||||
f.Phase = phase;
|
f.Phase = phase;
|
||||||
}
|
}
|
||||||
if len(arfiles) > 0 {
|
if len(arfiles) > 0 {
|
||||||
Archive(pkg.Name + ".a", arfiles);
|
Archive(obj + pkg.Name + ".a", arfiles);
|
||||||
|
|
||||||
n := len(p.ArCmds);
|
n := len(p.ArCmds);
|
||||||
p.ArCmds = p.ArCmds[0:n+1];
|
p.ArCmds = p.ArCmds[0:n+1];
|
||||||
@ -255,6 +296,7 @@ func (z *Info) Build() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (z *Info) Clean() {
|
func (z *Info) Clean() {
|
||||||
|
RemoveAll(ObjDir);
|
||||||
for pkgname := range z.Pkgmap {
|
for pkgname := range z.Pkgmap {
|
||||||
os.Remove(PackageObj(pkgname));
|
os.Remove(PackageObj(pkgname));
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,15 @@ var makefileTemplate =
|
|||||||
"# DO NOT EDIT. Automatically generated by gobuild.\n"
|
"# DO NOT EDIT. Automatically generated by gobuild.\n"
|
||||||
"{Args|args} >Makefile\n"
|
"{Args|args} >Makefile\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"D={.section Dir}/{@}{.end}\n"
|
||||||
|
"\n"
|
||||||
"O_arm=5\n" // TODO(rsc): include something here?
|
"O_arm=5\n" // TODO(rsc): include something here?
|
||||||
"O_amd64=6\n"
|
"O_amd64=6\n"
|
||||||
"O_386=8\n"
|
"O_386=8\n"
|
||||||
"OS=568vq\n"
|
"OS=568vq\n"
|
||||||
"\n"
|
"\n"
|
||||||
"O=$(O_$(GOARCH))\n"
|
"O=$(O_$(GOARCH))\n"
|
||||||
"GC=$(O)g\n"
|
"GC=$(O)g -I{ObjDir}\n"
|
||||||
"CC=$(O)c -FVw\n"
|
"CC=$(O)c -FVw\n"
|
||||||
"AS=$(O)a\n"
|
"AS=$(O)a\n"
|
||||||
"AR=6ar\n"
|
"AR=6ar\n"
|
||||||
@ -30,7 +32,7 @@ var makefileTemplate =
|
|||||||
"default: packages\n"
|
"default: packages\n"
|
||||||
"\n"
|
"\n"
|
||||||
"clean:\n"
|
"clean:\n"
|
||||||
" rm -f *.[$(OS)] *.a [$(OS)].out\n"
|
" rm -rf *.[$(OS)] *.a [$(OS)].out {ObjDir}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"test: packages\n"
|
"test: packages\n"
|
||||||
" gotest\n"
|
" gotest\n"
|
||||||
@ -60,21 +62,22 @@ var makefileTemplate =
|
|||||||
"\n"
|
"\n"
|
||||||
"phases:{.repeated section Phases} a{Phase}{.end}\n"
|
"phases:{.repeated section Phases} a{Phase}{.end}\n"
|
||||||
"{.repeated section Packages}\n"
|
"{.repeated section Packages}\n"
|
||||||
"{Name}.a: phases\n"
|
"{ObjDir}$D/{Name}.a: phases\n"
|
||||||
"{.end}\n"
|
"{.end}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"{.repeated section Phases}\n"
|
"{.repeated section Phases}\n"
|
||||||
"a{Phase}: $(O{Phase})\n"
|
"a{Phase}: $(O{Phase})\n"
|
||||||
"{.repeated section ArCmds}\n"
|
"{.repeated section ArCmds}\n"
|
||||||
" $(AR) grc {.section Pkg}{Name}.a{.end}{.repeated section Files} {Name|basename}.$O{.end}\n"
|
" $(AR) grc {ObjDir}$D/{.section Pkg}{Name}.a{.end}{.repeated section Files} {Name|basename}.$O{.end}\n"
|
||||||
"{.end}\n"
|
"{.end}\n"
|
||||||
" rm -f $(O{Phase})\n"
|
" rm -f $(O{Phase})\n"
|
||||||
"\n"
|
"\n"
|
||||||
"{.end}\n"
|
"{.end}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"newpkg: clean\n"
|
"newpkg: clean\n"
|
||||||
|
" mkdir -p {ObjDir}$D\n"
|
||||||
"{.repeated section Packages}\n"
|
"{.repeated section Packages}\n"
|
||||||
" $(AR) grc {Name}.a\n"
|
" $(AR) grc {ObjDir}$D/{Name}.a\n"
|
||||||
"{.end}\n"
|
"{.end}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"$(O1): newpkg\n"
|
"$(O1): newpkg\n"
|
||||||
@ -83,13 +86,14 @@ var makefileTemplate =
|
|||||||
"{.end}\n"
|
"{.end}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"nuke: clean\n"
|
"nuke: clean\n"
|
||||||
" rm -f{.repeated section Packages} $(GOROOT)/pkg/{Name}.a{.end}\n"
|
" rm -f{.repeated section Packages} $(GOROOT)/pkg$D/{Name}.a{.end}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"packages:{.repeated section Packages} {Name}.a{.end}\n"
|
"packages:{.repeated section Packages} {ObjDir}$D/{Name}.a{.end}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"install: packages\n"
|
"install: packages\n"
|
||||||
|
" test -d $(GOROOT)/pkg && mkdir -p $(GOROOT)/pkg$D\n"
|
||||||
"{.repeated section Packages}\n"
|
"{.repeated section Packages}\n"
|
||||||
" cp {Name}.a $(GOROOT)/pkg/{Name}.a\n"
|
" cp {ObjDir}$D/{Name}.a $(GOROOT)/pkg$D/{Name}.a\n"
|
||||||
"{.end}\n"
|
"{.end}\n"
|
||||||
|
|
||||||
func argsFmt(w io.Write, x interface{}, format string) {
|
func argsFmt(w io.Write, x interface{}, format string) {
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
package gobuild
|
package gobuild
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"ast";
|
|
||||||
"exec";
|
"exec";
|
||||||
"fmt";
|
"fmt";
|
||||||
|
"go/ast";
|
||||||
|
"go/parser";
|
||||||
"os";
|
"os";
|
||||||
"parser";
|
|
||||||
"path";
|
"path";
|
||||||
"sort";
|
"sort";
|
||||||
"strconv";
|
"strconv";
|
||||||
@ -30,6 +30,8 @@ var theChars = map[string] string {
|
|||||||
"arm": "5"
|
"arm": "5"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ObjDir = "_obj"
|
||||||
|
|
||||||
func fatal(args ...) {
|
func fatal(args ...) {
|
||||||
fmt.Fprintf(os.Stderr, "gobuild: %s\n", fmt.Sprint(args));
|
fmt.Fprintf(os.Stderr, "gobuild: %s\n", fmt.Sprint(args));
|
||||||
sys.Exit(1);
|
sys.Exit(1);
|
||||||
@ -124,7 +126,7 @@ func Archive(pkg string, files []string) {
|
|||||||
func Compiler(file string) []string {
|
func Compiler(file string) []string {
|
||||||
switch {
|
switch {
|
||||||
case strings.HasSuffix(file, ".go"):
|
case strings.HasSuffix(file, ".go"):
|
||||||
return []string{ theChar + "g" };
|
return []string{ theChar + "g", "-I", ObjDir };
|
||||||
case strings.HasSuffix(file, ".c"):
|
case strings.HasSuffix(file, ".c"):
|
||||||
return []string{ theChar + "c", "-FVw" };
|
return []string{ theChar + "c", "-FVw" };
|
||||||
case strings.HasSuffix(file, ".s"):
|
case strings.HasSuffix(file, ".s"):
|
||||||
@ -242,3 +244,37 @@ func SourceFiles(dir string) ([]string, *os.Error) {
|
|||||||
sort.SortStrings(out);
|
sort.SortStrings(out);
|
||||||
return out, nil;
|
return out, nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(rsc): Implement these for real as
|
||||||
|
// os.MkdirAll and os.RemoveAll and then
|
||||||
|
// make these wrappers that call fatal on error.
|
||||||
|
|
||||||
|
func MkdirAll(name string) {
|
||||||
|
p, err := exec.Run("/bin/mkdir", []string{"mkdir", "-p", name}, os.Environ(), exec.DevNull, exec.PassThrough, exec.PassThrough);
|
||||||
|
if err != nil {
|
||||||
|
fatal("run /bin/mkdir: %v", err);
|
||||||
|
}
|
||||||
|
w, err1 := p.Wait(0);
|
||||||
|
if err1 != nil {
|
||||||
|
fatal("wait /bin/mkdir: %v", err);
|
||||||
|
}
|
||||||
|
if !w.Exited() || w.ExitStatus() != 0 {
|
||||||
|
fatal("/bin/mkdir: %v", w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveAll(name string) {
|
||||||
|
p, err := exec.Run("/bin/rm", []string{"rm", "-rf", name}, os.Environ(), exec.DevNull, exec.PassThrough, exec.PassThrough);
|
||||||
|
if err != nil {
|
||||||
|
fatal("run /bin/rm: %v", err);
|
||||||
|
}
|
||||||
|
w, err1 := p.Wait(0);
|
||||||
|
if err1 != nil {
|
||||||
|
fatal("wait /bin/rm: %v", err);
|
||||||
|
}
|
||||||
|
if !w.Exited() || w.ExitStatus() != 0 {
|
||||||
|
fatal("/bin/rm: %v", w);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user