Commit 4340b57d authored by Andrew Gerrand's avatar Andrew Gerrand

goinstall, go/build: support building cgo packages

Fixes #1962.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/4636044
parent ca91ce2d
...@@ -197,7 +197,7 @@ func install(pkg, parent string) { ...@@ -197,7 +197,7 @@ func install(pkg, parent string) {
errorf("%s: %v\n", pkg, err) errorf("%s: %v\n", pkg, err)
return return
} }
if len(dirInfo.GoFiles) == 0 { if len(dirInfo.GoFiles)+len(dirInfo.CgoFiles) == 0 {
errorf("%s: package has no files\n", pkg) errorf("%s: package has no files\n", pkg)
return return
} }
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"regexp"
"runtime" "runtime"
"strings" "strings"
) )
...@@ -22,14 +23,14 @@ func Build(tree *Tree, pkg string, info *DirInfo) (*Script, os.Error) { ...@@ -22,14 +23,14 @@ func Build(tree *Tree, pkg string, info *DirInfo) (*Script, os.Error) {
script: s, script: s,
path: filepath.Join(tree.SrcDir(), pkg), path: filepath.Join(tree.SrcDir(), pkg),
} }
b.obj = b.abs("_obj") + "/" b.obj = b.abs("_obj") + string(filepath.Separator)
goarch := runtime.GOARCH b.goarch = runtime.GOARCH
if g := os.Getenv("GOARCH"); g != "" { if g := os.Getenv("GOARCH"); g != "" {
goarch = g b.goarch = g
} }
var err os.Error var err os.Error
b.arch, err = ArchChar(goarch) b.arch, err = ArchChar(b.goarch)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -82,6 +83,9 @@ func Build(tree *Tree, pkg string, info *DirInfo) (*Script, os.Error) { ...@@ -82,6 +83,9 @@ func Build(tree *Tree, pkg string, info *DirInfo) (*Script, os.Error) {
if info.IsCommand() { if info.IsCommand() {
// use the last part of the import path as binary name // use the last part of the import path as binary name
_, bin := filepath.Split(pkg) _, bin := filepath.Split(pkg)
if runtime.GOOS == "windows" {
bin += ".exe"
}
targ = filepath.Join(tree.BinDir(), bin) targ = filepath.Join(tree.BinDir(), bin)
} else { } else {
targ = filepath.Join(tree.PkgDir(), pkg+".a") targ = filepath.Join(tree.PkgDir(), pkg+".a")
...@@ -186,6 +190,7 @@ type Cmd struct { ...@@ -186,6 +190,7 @@ type Cmd struct {
Args []string // command-line Args []string // command-line
Stdout string // write standard output to this file, "" is passthrough Stdout string // write standard output to this file, "" is passthrough
Dir string // working directory Dir string // working directory
Env []string // environment
Input []string // file paths (dependencies) Input []string // file paths (dependencies)
Output []string // file paths Output []string // file paths
} }
...@@ -199,6 +204,7 @@ func (c *Cmd) Run() os.Error { ...@@ -199,6 +204,7 @@ func (c *Cmd) Run() os.Error {
out := new(bytes.Buffer) out := new(bytes.Buffer)
cmd := exec.Command(c.Args[0], c.Args[1:]...) cmd := exec.Command(c.Args[0], c.Args[1:]...)
cmd.Dir = c.Dir cmd.Dir = c.Dir
cmd.Env = c.Env
cmd.Stdout = out cmd.Stdout = out
cmd.Stderr = out cmd.Stderr = out
if c.Stdout != "" { if c.Stdout != "" {
...@@ -233,6 +239,7 @@ type build struct { ...@@ -233,6 +239,7 @@ type build struct {
script *Script script *Script
path string path string
obj string obj string
goarch string
arch string arch string
} }
...@@ -341,6 +348,8 @@ func (b *build) gccArgs(args ...string) []string { ...@@ -341,6 +348,8 @@ func (b *build) gccArgs(args ...string) []string {
return append(a, args...) return append(a, args...)
} }
var cgoRe = regexp.MustCompile("[/\\:]")
func (b *build) cgo(cgofiles []string) (outGo, outObj []string) { func (b *build) cgo(cgofiles []string) (outGo, outObj []string) {
// cgo // cgo
// TODO(adg): CGOPKGPATH // TODO(adg): CGOPKGPATH
...@@ -348,7 +357,7 @@ func (b *build) cgo(cgofiles []string) (outGo, outObj []string) { ...@@ -348,7 +357,7 @@ func (b *build) cgo(cgofiles []string) (outGo, outObj []string) {
gofiles := []string{b.obj + "_cgo_gotypes.go"} gofiles := []string{b.obj + "_cgo_gotypes.go"}
cfiles := []string{b.obj + "_cgo_main.c", b.obj + "_cgo_export.c"} cfiles := []string{b.obj + "_cgo_main.c", b.obj + "_cgo_export.c"}
for _, fn := range cgofiles { for _, fn := range cgofiles {
f := b.obj + strings.Replace(fn[:len(fn)-2], "/", "_", -1) f := b.obj + cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
gofiles = append(gofiles, f+"cgo1.go") gofiles = append(gofiles, f+"cgo1.go")
cfiles = append(cfiles, f+"cgo2.c") cfiles = append(cfiles, f+"cgo2.c")
} }
...@@ -358,6 +367,7 @@ func (b *build) cgo(cgofiles []string) (outGo, outObj []string) { ...@@ -358,6 +367,7 @@ func (b *build) cgo(cgofiles []string) (outGo, outObj []string) {
b.add(Cmd{ b.add(Cmd{
Args: append([]string{"cgo", "--"}, cgofiles...), Args: append([]string{"cgo", "--"}, cgofiles...),
Dir: b.path, Dir: b.path,
Env: append(os.Environ(), "GOARCH="+b.goarch),
Input: cgofiles, Input: cgofiles,
Output: output, Output: output,
}) })
......
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