mirror of
https://github.com/golang/go
synced 2024-11-22 05:24:39 -07:00
go: build runtime
R=golang-dev, r, adg CC=golang-dev https://golang.org/cl/5495068
This commit is contained in:
parent
b49625663e
commit
a1198fcc03
@ -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) {
|
|||||||
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
|
|||||||
}
|
}
|
||||||
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 {
|
|||||||
// 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 {
|
|||||||
|
|
||||||
// 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
|
|||||||
// 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
|
|||||||
// 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:
|
|||||||
// 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) {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
// 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
|
|||||||
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 {
|
|||||||
&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 {
|
|||||||
|
|
||||||
// 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) {
|
|||||||
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) {
|
|||||||
|
|
||||||
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) {
|
|||||||
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) {
|
|||||||
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user