1
0
mirror of https://github.com/golang/go synced 2024-11-22 02:44:39 -07:00

goinstall: build with make by default, add -make flag

This is a temporary measure until go/build can build cgo packages.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/4627056
This commit is contained in:
Andrew Gerrand 2011-06-24 13:01:17 +10:00
parent 73d741fd5b
commit b4bab6f8b3
3 changed files with 210 additions and 20 deletions

View File

@ -8,5 +8,6 @@ TARG=goinstall
GOFILES=\ GOFILES=\
download.go\ download.go\
main.go\ main.go\
make.go\
include ../../Make.cmd include ../../Make.cmd

View File

@ -41,6 +41,7 @@ var (
doInstall = flag.Bool("install", true, "build and install") doInstall = flag.Bool("install", true, "build and install")
clean = flag.Bool("clean", false, "clean the package directory before installing") clean = flag.Bool("clean", false, "clean the package directory before installing")
nuke = flag.Bool("nuke", false, "clean the package directory and target before installing") nuke = flag.Bool("nuke", false, "clean the package directory and target before installing")
useMake = flag.Bool("make", true, "use make to build and install")
verbose = flag.Bool("v", false, "verbose") verbose = flag.Bool("v", false, "verbose")
) )
@ -211,27 +212,35 @@ func install(pkg, parent string) {
} }
// Install this package. // Install this package.
script, err := build.Build(tree, pkg, dirInfo) if *useMake {
if err != nil { err := domake(dir, pkg, tree, dirInfo.IsCommand())
errorf("%s: install: %v\n", pkg, err) if err != nil {
return errorf("%s: install: %v\n", pkg, err)
} return
if *nuke { }
printf("%s: nuke\n", pkg) } else {
script.Nuke() script, err := build.Build(tree, pkg, dirInfo)
} else if *clean { if err != nil {
printf("%s: clean\n", pkg) errorf("%s: install: %v\n", pkg, err)
script.Clean() return
} }
if *doInstall { if *nuke {
if script.Stale() { printf("%s: nuke\n", pkg)
printf("%s: install\n", pkg) script.Nuke()
if err := script.Run(); err != nil { } else if *clean {
errorf("%s: install: %v\n", pkg, err) printf("%s: clean\n", pkg)
return script.Clean()
}
if *doInstall {
if script.Stale() {
printf("%s: install\n", pkg)
if err := script.Run(); err != nil {
errorf("%s: install: %v\n", pkg, err)
return
}
} else {
printf("%s: up-to-date\n", pkg)
} }
} else {
printf("%s: up-to-date\n", pkg)
} }
} }
if remote { if remote {

180
src/cmd/goinstall/make.go Normal file
View File

@ -0,0 +1,180 @@
// Copyright 2011 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.
// Run "make install" to build package.
package main
import (
"bytes"
"go/build"
"os"
"path/filepath"
"strings"
"template"
)
// domake builds the package in dir.
// domake generates a standard Makefile and passes it
// to make on standard input.
func domake(dir, pkg string, tree *build.Tree, isCmd bool) (err os.Error) {
makefile, err := makeMakefile(dir, pkg, tree, isCmd)
if err != nil {
return err
}
cmd := []string{"bash", "gomake", "-f-"}
if *nuke {
cmd = append(cmd, "nuke")
} else if *clean {
cmd = append(cmd, "clean")
}
cmd = append(cmd, "install")
return run(dir, makefile, cmd...)
}
// makeMakefile computes the standard Makefile for the directory dir
// installing as package pkg. It includes all *.go files in the directory
// except those in package main and those ending in _test.go.
func makeMakefile(dir, pkg string, tree *build.Tree, isCmd bool) ([]byte, os.Error) {
if !safeName(pkg) {
return nil, os.NewError("unsafe name: " + pkg)
}
targ := pkg
targDir := tree.PkgDir()
if isCmd {
// use the last part of the package name for targ
_, targ = filepath.Split(pkg)
targDir = tree.BinDir()
}
dirInfo, err := build.ScanDir(dir, isCmd)
if err != nil {
return nil, err
}
cgoFiles := dirInfo.CgoFiles
isCgo := make(map[string]bool, len(cgoFiles))
for _, file := range cgoFiles {
if !safeName(file) {
return nil, os.NewError("bad name: " + file)
}
isCgo[file] = true
}
goFiles := make([]string, 0, len(dirInfo.GoFiles))
for _, file := range dirInfo.GoFiles {
if !safeName(file) {
return nil, os.NewError("unsafe name: " + file)
}
if !isCgo[file] {
goFiles = append(goFiles, file)
}
}
oFiles := make([]string, 0, len(dirInfo.CFiles)+len(dirInfo.SFiles))
cgoOFiles := make([]string, 0, len(dirInfo.CFiles))
for _, file := range dirInfo.CFiles {
if !safeName(file) {
return nil, os.NewError("unsafe name: " + file)
}
// When cgo is in use, C files are compiled with gcc,
// otherwise they're compiled with gc.
if len(cgoFiles) > 0 {
cgoOFiles = append(cgoOFiles, file[:len(file)-2]+".o")
} else {
oFiles = append(oFiles, file[:len(file)-2]+".$O")
}
}
for _, file := range dirInfo.SFiles {
if !safeName(file) {
return nil, os.NewError("unsafe name: " + file)
}
oFiles = append(oFiles, file[:len(file)-2]+".$O")
}
var imports []string
for _, t := range build.Path {
imports = append(imports, t.PkgDir())
}
var buf bytes.Buffer
md := makedata{targ, targDir, "pkg", goFiles, oFiles, cgoFiles, cgoOFiles, imports}
if isCmd {
md.Type = "cmd"
}
if err := makefileTemplate.Execute(&buf, &md); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var safeBytes = []byte("+-./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz")
func safeName(s string) bool {
if s == "" {
return false
}
if strings.Contains(s, "..") {
return false
}
for i := 0; i < len(s); i++ {
if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 {
return false
}
}
return true
}
// makedata is the data type for the makefileTemplate.
type makedata struct {
Targ string // build target
TargDir string // build target directory
Type string // build type: "pkg" or "cmd"
GoFiles []string // list of non-cgo .go files
OFiles []string // list of .$O files
CgoFiles []string // list of cgo .go files
CgoOFiles []string // list of cgo .o files, without extension
Imports []string // gc/ld import paths
}
var makefileTemplate = template.MustParse(`
include $(GOROOT)/src/Make.inc
TARG={Targ}
TARGDIR={TargDir}
{.section GoFiles}
GOFILES=\
{.repeated section @}
{@}\
{.end}
{.end}
{.section OFiles}
OFILES=\
{.repeated section @}
{@}\
{.end}
{.end}
{.section CgoFiles}
CGOFILES=\
{.repeated section @}
{@}\
{.end}
{.end}
{.section CgoOFiles}
CGO_OFILES=\
{.repeated section @}
{@}\
{.end}
{.end}
GCIMPORTS={.repeated section Imports}-I "{@}" {.end}
LDIMPORTS={.repeated section Imports}-L "{@}" {.end}
include $(GOROOT)/src/Make.{Type}
`,
nil)