Commit a1198fcc authored by Russ Cox's avatar Russ Cox

go: build runtime

R=golang-dev, r, adg
CC=golang-dev
https://golang.org/cl/5495068
parent b4962566
...@@ -106,6 +106,8 @@ type builder struct { ...@@ -106,6 +106,8 @@ type builder struct {
vflag bool // the -v flag vflag bool // the -v flag
arch string // e.g., "6" arch string // e.g., "6"
goroot string // the $GOROOT goroot string // the $GOROOT
goarch string // the $GOARCH
goos string // the $GOOS
actionCache map[cacheKey]*action // a cache of already-constructed actions actionCache map[cacheKey]*action // a cache of already-constructed actions
} }
...@@ -147,8 +149,10 @@ func (b *builder) init(aflag, nflag, vflag bool) { ...@@ -147,8 +149,10 @@ func (b *builder) init(aflag, nflag, vflag bool) {
b.vflag = vflag b.vflag = vflag
b.actionCache = make(map[cacheKey]*action) b.actionCache = make(map[cacheKey]*action)
b.goroot = runtime.GOROOT() b.goroot = runtime.GOROOT()
b.goarch = build.DefaultContext.GOARCH
b.goos = build.DefaultContext.GOOS
b.arch, err = build.ArchChar(build.DefaultContext.GOARCH) b.arch, err = build.ArchChar(b.goarch)
if err != nil { if err != nil {
fatalf("%s", err) fatalf("%s", err)
} }
...@@ -236,7 +240,7 @@ func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action ...@@ -236,7 +240,7 @@ func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action
} }
if p.Standard { if p.Standard {
switch p.ImportPath { switch p.ImportPath {
case "runtime", "runtime/cgo": case "runtime/cgo":
// Too complex - can't build. // Too complex - can't build.
a.f = (*builder).nop a.f = (*builder).nop
return a return a
...@@ -362,17 +366,60 @@ func (b *builder) build(a *action) error { ...@@ -362,17 +366,60 @@ func (b *builder) build(a *action) error {
// compile Go // compile Go
if len(gofiles) > 0 { if len(gofiles) > 0 {
out := "_go_.6" out := "_go_.6"
if err := b.gc(a.p.Dir, obj+out, a.p.ImportPath, inc, gofiles); err != nil { gcargs := []string{"-p", a.p.ImportPath}
if a.p.Standard && a.p.ImportPath == "runtime" {
// runtime compiles with a special 6g flag to emit
// additional reflect type data.
gcargs = append(gcargs, "-+")
}
if err := b.gc(a.p.Dir, obj+out, gcargs, inc, gofiles); err != nil {
return err return err
} }
objects = append(objects, out) objects = append(objects, out)
} }
// assemble .s files // copy .h files named for goos or goarch or goos_goarch
if len(a.p.SFiles) > 0 { // to names using GOOS and GOARCH.
for _, sfile := range a.p.SFiles { // For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
out := sfile[:len(sfile)-len(".s")] + "." + b.arch _goos_goarch := "_" + b.goos + "_" + b.goarch + ".h"
if err := b.asm(a.p.Dir, obj+out, sfile); err != nil { _goos := "_" + b.goos + ".h"
_goarch := "_" + b.goarch + ".h"
for _, file := range a.p.HFiles {
switch {
case strings.HasSuffix(file, _goos_goarch):
targ := file[:len(file)-len(_goos_goarch)] + "_GOOS_GOARCH.h"
if err := b.copyFile(obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
return err
}
case strings.HasSuffix(file, _goarch):
targ := file[:len(file)-len(_goarch)] + "_GOARCH.h"
if err := b.copyFile(obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
return err
}
case strings.HasSuffix(file, _goos):
targ := file[:len(file)-len(_goos)] + "_GOOS.h"
if err := b.copyFile(obj+targ, filepath.Join(a.p.Dir, file), 0666); err != nil {
return err
}
}
}
// in a cgo package, the .c files are compiled with gcc during b.cgo above.
// in a non-cgo package, the .c files are compiled with 5c/6c/8c.
// The same convention applies for .s files.
if len(a.p.CgoFiles) == 0 {
for _, file := range a.p.CFiles {
out := file[:len(file)-len(".c")] + "." + b.arch
if err := b.cc(a.p.Dir, obj+out, file); err != nil {
return err
}
objects = append(objects, out)
}
// assemble .s files
for _, file := range a.p.SFiles {
out := file[:len(file)-len(".s")] + "." + b.arch
if err := b.asm(a.p.Dir, obj+out, file); err != nil {
return err return err
} }
objects = append(objects, out) objects = append(objects, out)
...@@ -510,8 +557,10 @@ func (b *builder) mkdir(dir string) error { ...@@ -510,8 +557,10 @@ func (b *builder) mkdir(dir string) error {
// gc runs the Go compiler in a specific directory on a set of files // gc runs the Go compiler in a specific directory on a set of files
// to generate the named output file. // to generate the named output file.
func (b *builder) gc(dir, ofile, importPath string, importArgs []string, gofiles []string) error { func (b *builder) gc(dir, ofile string, gcargs, importArgs []string, gofiles []string) error {
args := append([]string{b.arch + "g", "-o", ofile, "-p", importPath}, importArgs...) args := []string{b.arch + "g", "-o", ofile}
args = append(args, gcargs...)
args = append(args, importArgs...)
args = append(args, gofiles...) args = append(args, gofiles...)
return b.run(dir, args...) return b.run(dir, args...)
} }
...@@ -519,7 +568,7 @@ func (b *builder) gc(dir, ofile, importPath string, importArgs []string, gofiles ...@@ -519,7 +568,7 @@ func (b *builder) gc(dir, ofile, importPath string, importArgs []string, gofiles
// asm runs the assembler in a specific directory on a specific file // asm runs the assembler in a specific directory on a specific file
// to generate the named output file. // to generate the named output file.
func (b *builder) asm(dir, ofile, sfile string) error { func (b *builder) asm(dir, ofile, sfile string) error {
return b.run(dir, b.arch+"a", "-o", ofile, sfile) return b.run(dir, b.arch+"a", "-o", ofile, "-DGOOS_"+b.goos, "-DGOARCH_"+b.goarch, sfile)
} }
// gopack runs the assembler in a specific directory to create // gopack runs the assembler in a specific directory to create
...@@ -538,8 +587,8 @@ func (b *builder) ld(dir, out string, importArgs []string, mainpkg string) error ...@@ -538,8 +587,8 @@ func (b *builder) ld(dir, out string, importArgs []string, mainpkg string) error
// to produce an output file. // to produce an output file.
func (b *builder) cc(dir, ofile, cfile string) error { func (b *builder) cc(dir, ofile, cfile string) error {
inc := filepath.Join(runtime.GOROOT(), "pkg", inc := filepath.Join(runtime.GOROOT(), "pkg",
fmt.Sprintf("%s_%s", build.DefaultContext.GOOS, build.DefaultContext.GOARCH)) fmt.Sprintf("%s_%s", b.goos, b.goarch))
return b.run(dir, b.arch+"c", "-FVW", "-I", inc, "-o", ofile, cfile) return b.run(dir, b.arch+"c", "-FVw", "-I", inc, "-o", ofile, "-DGOOS_"+b.goos, "-DGOARCH_"+b.goarch, cfile)
} }
// gcc runs the gcc C compiler to create an object from a single C file. // gcc runs the gcc C compiler to create an object from a single C file.
......
...@@ -37,6 +37,7 @@ being passed to the template is: ...@@ -37,6 +37,7 @@ being passed to the template is:
// Source files // Source files
GoFiles []string // .go source files (excluding CgoFiles) GoFiles []string // .go source files (excluding CgoFiles)
CFiles []string // .c source files CFiles []string // .c source files
HFiles []string // .h source files
SFiles []string // .s source files SFiles []string // .s source files
CgoFiles []string // .go sources files that import "C" CgoFiles []string // .go sources files that import "C"
......
...@@ -239,7 +239,6 @@ func run(cmdline ...string) { ...@@ -239,7 +239,6 @@ func run(cmdline ...string) {
func allPackages() []string { func allPackages() []string {
have := make(map[string]bool) have := make(map[string]bool)
var pkgs []string var pkgs []string
runtime := filepath.Join(build.Path[0].SrcDir(), "runtime") + string(filepath.Separator)
for _, t := range build.Path { for _, t := range build.Path {
src := t.SrcDir() + string(filepath.Separator) src := t.SrcDir() + string(filepath.Separator)
filepath.Walk(src, func(path string, fi os.FileInfo, err error) error { filepath.Walk(src, func(path string, fi os.FileInfo, err error) error {
...@@ -251,13 +250,6 @@ func allPackages() []string { ...@@ -251,13 +250,6 @@ func allPackages() []string {
if strings.HasSuffix(path, string(filepath.Separator)+"testdata") { if strings.HasSuffix(path, string(filepath.Separator)+"testdata") {
return filepath.SkipDir return filepath.SkipDir
} }
// Avoid runtime subdirectories.
if strings.HasPrefix(path, runtime) {
switch path {
case runtime + "darwin", runtime + "freebsd", runtime + "linux", runtime + "netbsd", runtime + "openbsd", runtime + "windows":
return filepath.SkipDir
}
}
_, err = build.ScanDir(path) _, err = build.ScanDir(path)
if err != nil { if err != nil {
......
...@@ -29,6 +29,7 @@ type Package struct { ...@@ -29,6 +29,7 @@ type Package struct {
// Source files // Source files
GoFiles []string // .go source files (excluding CgoFiles) GoFiles []string // .go source files (excluding CgoFiles)
CFiles []string // .c source files CFiles []string // .c source files
HFiles []string // .h source files
SFiles []string // .s source files SFiles []string // .s source files
CgoFiles []string // .go sources files that import "C" CgoFiles []string // .go sources files that import "C"
...@@ -120,6 +121,7 @@ func scanPackage(ctxt *build.Context, t *build.Tree, arg, importPath, dir string ...@@ -120,6 +121,7 @@ func scanPackage(ctxt *build.Context, t *build.Tree, arg, importPath, dir string
Imports: info.Imports, Imports: info.Imports,
GoFiles: info.GoFiles, GoFiles: info.GoFiles,
CFiles: info.CFiles, CFiles: info.CFiles,
HFiles: info.HFiles,
SFiles: info.SFiles, SFiles: info.SFiles,
CgoFiles: info.CgoFiles, CgoFiles: info.CgoFiles,
Standard: t.Goroot && !strings.Contains(importPath, "."), Standard: t.Goroot && !strings.Contains(importPath, "."),
......
...@@ -48,6 +48,7 @@ var buildPkgs = []struct { ...@@ -48,6 +48,7 @@ var buildPkgs = []struct {
&DirInfo{ &DirInfo{
CgoFiles: []string{"cgotest.go"}, CgoFiles: []string{"cgotest.go"},
CFiles: []string{"cgotest.c"}, CFiles: []string{"cgotest.c"},
HFiles: []string{"cgotest.h"},
Imports: []string{"C", "unsafe"}, Imports: []string{"C", "unsafe"},
TestImports: []string{}, TestImports: []string{},
Package: "cgotest", Package: "cgotest",
......
...@@ -96,8 +96,9 @@ type DirInfo struct { ...@@ -96,8 +96,9 @@ type DirInfo struct {
// Source files // Source files
GoFiles []string // .go files in dir (excluding CgoFiles) GoFiles []string // .go files in dir (excluding CgoFiles)
HFiles []string // .h files in dir
CFiles []string // .c files in dir CFiles []string // .c files in dir
SFiles []string // .s files in dir SFiles []string // .s (and, when using cgo, .S files in dir)
CgoFiles []string // .go files that import "C" CgoFiles []string // .go files that import "C"
// Cgo directives // Cgo directives
...@@ -135,6 +136,7 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) { ...@@ -135,6 +136,7 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
return nil, err return nil, err
} }
var Sfiles []string // files with ".S" (capital S)
var di DirInfo var di DirInfo
imported := make(map[string]bool) imported := make(map[string]bool)
testImported := make(map[string]bool) testImported := make(map[string]bool)
...@@ -154,7 +156,7 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) { ...@@ -154,7 +156,7 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
ext := path.Ext(name) ext := path.Ext(name)
switch ext { switch ext {
case ".go", ".c", ".s": case ".go", ".c", ".s", ".h", ".S":
// tentatively okay // tentatively okay
default: default:
// skip // skip
...@@ -175,9 +177,15 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) { ...@@ -175,9 +177,15 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
case ".c": case ".c":
di.CFiles = append(di.CFiles, name) di.CFiles = append(di.CFiles, name)
continue continue
case ".h":
di.HFiles = append(di.HFiles, name)
continue
case ".s": case ".s":
di.SFiles = append(di.SFiles, name) di.SFiles = append(di.SFiles, name)
continue continue
case ".S":
Sfiles = append(Sfiles, name)
continue
} }
pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments) pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
...@@ -282,6 +290,15 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) { ...@@ -282,6 +290,15 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err error) {
di.TestImports[i] = p di.TestImports[i] = p
i++ i++
} }
// add the .S files only if we are using cgo
// (which means gcc will compile them).
// The standard assemblers expect .s files.
if len(di.CgoFiles) > 0 {
di.SFiles = append(di.SFiles, Sfiles...)
sort.Strings(di.SFiles)
}
// File name lists are sorted because ReadDir sorts. // File name lists are sorted because ReadDir sorts.
sort.Strings(di.Imports) sort.Strings(di.Imports)
sort.Strings(di.TestImports) sort.Strings(di.TestImports)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment