summaryrefslogtreecommitdiff
path: root/misc/dist/bindist.go
diff options
context:
space:
mode:
Diffstat (limited to 'misc/dist/bindist.go')
-rw-r--r--misc/dist/bindist.go184
1 files changed, 163 insertions, 21 deletions
diff --git a/misc/dist/bindist.go b/misc/dist/bindist.go
index 19b0baac2..223d2dc17 100644
--- a/misc/dist/bindist.go
+++ b/misc/dist/bindist.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// This is a tool for packaging binary releases.
-// It supports FreeBSD, Linux, NetBSD, OS X, and Windows.
+// It supports FreeBSD, Linux, NetBSD, OpenBSD, OS X, and Windows.
package main
import (
@@ -22,6 +22,7 @@ import (
"net/http"
"os"
"os/exec"
+ "path"
"path/filepath"
"regexp"
"runtime"
@@ -30,22 +31,36 @@ import (
var (
tag = flag.String("tag", "release", "mercurial tag to check out")
+ toolTag = flag.String("tool", defaultToolTag, "go.tools tag to check out")
repo = flag.String("repo", "https://code.google.com/p/go", "repo URL")
- tourPath = flag.String("tour", "code.google.com/p/go-tour", "Go tour repo import path")
verbose = flag.Bool("v", false, "verbose output")
upload = flag.Bool("upload", true, "upload resulting files to Google Code")
wxsFile = flag.String("wxs", "", "path to custom installer.wxs")
addLabel = flag.String("label", "", "additional label to apply to file when uploading")
includeRace = flag.Bool("race", true, "build race detector packages")
versionOverride = flag.String("version", "", "override version name")
+ staticToolchain = flag.Bool("static", true, "try to build statically linked toolchain (only supported on ELF targets)")
username, password string // for Google Code upload
)
const (
- uploadURL = "https://go.googlecode.com/files"
+ uploadURL = "https://go.googlecode.com/files"
+ blogPath = "code.google.com/p/go.blog"
+ toolPath = "code.google.com/p/go.tools"
+ tourPath = "code.google.com/p/go-tour"
+ defaultToolTag = "release-branch.go1.2"
)
+// Import paths for tool commands.
+// These must be the command that cmd/go knows to install to $GOROOT/bin
+// or $GOROOT/pkg/tool.
+var toolPaths = []string{
+ "code.google.com/p/go.tools/cmd/cover",
+ "code.google.com/p/go.tools/cmd/godoc",
+ "code.google.com/p/go.tools/cmd/vet",
+}
+
var preBuildCleanFiles = []string{
"lib/codereview",
"misc/dashboard/godashboard",
@@ -74,12 +89,16 @@ var tourPackages = []string{
}
var tourContent = []string{
+ "content",
"js",
- "prog",
"solutions",
"static",
"template",
- "tour.article",
+}
+
+var blogContent = []string{
+ "content",
+ "template",
}
// The os-arches that support the race toolchain.
@@ -89,7 +108,17 @@ var raceAvailable = []string{
"windows-amd64",
}
-var fileRe = regexp.MustCompile(`^(go[a-z0-9-.]+)\.(src|([a-z0-9]+)-([a-z0-9]+))\.`)
+// The OSes that support building statically linked toolchain
+// Only ELF platforms are supported.
+var staticLinkAvailable = []string{
+ "linux",
+ "freebsd",
+ "openbsd",
+ "netbsd",
+}
+
+var fileRe = regexp.MustCompile(
+ `^(go[a-z0-9-.]+)\.(src|([a-z0-9]+)-([a-z0-9]+)(?:-([a-z0-9.]))?)\.`)
func main() {
flag.Usage = func() {
@@ -120,6 +149,7 @@ func main() {
} else {
b.OS = m[3]
b.Arch = m[4]
+ b.Label = m[5]
}
if !*upload {
log.Printf("%s: -upload=false, skipping", targ)
@@ -133,20 +163,30 @@ func main() {
if targ == "source" {
b.Source = true
} else {
- p := strings.SplitN(targ, "-", 2)
- if len(p) != 2 {
+ p := strings.SplitN(targ, "-", 3)
+ if len(p) < 2 {
log.Println("Ignoring unrecognized target:", targ)
continue
}
b.OS = p[0]
b.Arch = p[1]
+ if len(p) >= 3 {
+ b.Label = p[2]
+ }
if *includeRace {
for _, t := range raceAvailable {
- if t == targ {
+ if t == targ || strings.HasPrefix(targ, t+"-") {
b.Race = true
}
}
}
+ if *staticToolchain {
+ for _, os := range staticLinkAvailable {
+ if b.OS == os {
+ b.static = true
+ }
+ }
+ }
}
if err := b.Do(); err != nil {
log.Printf("%s: %v", targ, err)
@@ -159,8 +199,10 @@ type Build struct {
Race bool // build race toolchain
OS string
Arch string
+ Label string
root string
gopath string
+ static bool // if true, build statically linked toolchain
}
func (b *Build) Do() error {
@@ -173,11 +215,11 @@ func (b *Build) Do() error {
b.gopath = work
// Clone Go distribution and update to tag.
- _, err = b.run(work, "hg", "clone", "-q", *repo, b.root)
+ _, err = b.hgCmd(work, "clone", *repo, b.root)
if err != nil {
return err
}
- _, err = b.run(b.root, "hg", "update", *tag)
+ _, err = b.hgCmd(b.root, "update", *tag)
if err != nil {
return err
}
@@ -214,12 +256,26 @@ func (b *Build) Do() error {
return err
}
// Re-install std without -race, so that we're not left
- // with a slower, race-enabled cmd/go, cmd/godoc, etc.
+ // with a slower, race-enabled cmd/go, etc.
_, err = b.run(src, goCmd, "install", "-a", "std")
+ // Re-building go command leaves old versions of go.exe as go.exe~ on windows.
+ // See (*builder).copyFile in $GOROOT/src/cmd/go/build.go for details.
+ // Remove it manually.
+ if b.OS == "windows" {
+ os.Remove(goCmd + "~")
+ }
}
if err != nil {
return err
}
+ err = b.tools()
+ if err != nil {
+ return err
+ }
+ err = b.blog()
+ if err != nil {
+ return err
+ }
err = b.tour()
}
if err != nil {
@@ -268,6 +324,9 @@ func (b *Build) Do() error {
// Create packages.
base := fmt.Sprintf("%s.%s-%s", version, b.OS, b.Arch)
+ if b.Label != "" {
+ base += "-" + b.Label
+ }
if !strings.HasPrefix(base, "go") {
base = "go." + base
}
@@ -316,7 +375,7 @@ func (b *Build) Do() error {
dist := filepath.Join(runtime.GOROOT(), "misc/dist")
_, err = b.run("", "pkgbuild",
"--identifier", "com.googlecode.go",
- "--version", "1.0",
+ "--version", version,
"--scripts", filepath.Join(dist, "darwin/scripts"),
"--root", work,
filepath.Join(pkgdest, "com.googlecode.go.pkg"))
@@ -402,15 +461,79 @@ func (b *Build) Do() error {
return err
}
+func (b *Build) tools() error {
+ defer b.cleanGopath()
+
+ // Fetch the tool packages (without building/installing).
+ args := append([]string{"get", "-d"}, toolPaths...)
+ _, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"), args...)
+ if err != nil {
+ return err
+ }
+
+ // Update the repo to the revision specified by -tool.
+ repoPath := filepath.Join(b.gopath, "src", filepath.FromSlash(toolPath))
+ _, err = b.run(repoPath, "hg", "update", *toolTag)
+ if err != nil {
+ return err
+ }
+
+ // Install tools.
+ args = append([]string{"install"}, toolPaths...)
+ _, err = b.run(b.gopath, filepath.Join(b.root, "bin", "go"), args...)
+ if err != nil {
+ return err
+ }
+
+ // Copy doc.go from go.tools/cmd/$CMD to $GOROOT/src/cmd/$CMD
+ // while rewriting "package main" to "package documentation".
+ for _, p := range toolPaths {
+ d, err := ioutil.ReadFile(filepath.Join(b.gopath, "src",
+ filepath.FromSlash(p), "doc.go"))
+ if err != nil {
+ return err
+ }
+ d = bytes.Replace(d, []byte("\npackage main\n"),
+ []byte("\npackage documentation\n"), 1)
+ cmdDir := filepath.Join(b.root, "src", "cmd", path.Base(p))
+ if err := os.MkdirAll(cmdDir, 0755); err != nil {
+ return err
+ }
+ docGo := filepath.Join(cmdDir, "doc.go")
+ if err := ioutil.WriteFile(docGo, d, 0644); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (b *Build) blog() error {
+ defer b.cleanGopath()
+
+ // Fetch the blog repository.
+ _, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"), "get", "-d", blogPath+"/blog")
+ if err != nil {
+ return err
+ }
+
+ // Copy blog content to $GOROOT/blog.
+ blogSrc := filepath.Join(b.gopath, "src", filepath.FromSlash(blogPath))
+ contentDir := filepath.Join(b.root, "blog")
+ return cpAllDir(contentDir, blogSrc, blogContent...)
+}
+
func (b *Build) tour() error {
+ defer b.cleanGopath()
+
// go get the gotour package.
- _, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"), "get", *tourPath+"/gotour")
+ _, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"), "get", tourPath+"/gotour")
if err != nil {
return err
}
// Copy all the tour content to $GOROOT/misc/tour.
- importPath := filepath.FromSlash(*tourPath)
+ importPath := filepath.FromSlash(tourPath)
tourSrc := filepath.Join(b.gopath, "src", importPath)
contentDir := filepath.Join(b.root, "misc", "tour")
if err = cpAllDir(contentDir, tourSrc, tourContent...); err != nil {
@@ -423,16 +546,29 @@ func (b *Build) tour() error {
}
// Copy gotour binary to tool directory as "tour"; invoked as "go tool tour".
- ext := ""
- if runtime.GOOS == "windows" {
- ext = ".exe"
- }
return cp(
- filepath.Join(b.root, "pkg", "tool", b.OS+"_"+b.Arch, "tour"+ext),
- filepath.Join(b.gopath, "bin", "gotour"+ext),
+ filepath.Join(b.root, "pkg", "tool", b.OS+"_"+b.Arch, "tour"+ext()),
+ filepath.Join(b.gopath, "bin", "gotour"+ext()),
)
}
+func (b *Build) cleanGopath() {
+ for _, d := range []string{"bin", "pkg", "src"} {
+ os.RemoveAll(filepath.Join(b.gopath, d))
+ }
+}
+
+func ext() string {
+ if runtime.GOOS == "windows" {
+ return ".exe"
+ }
+ return ""
+}
+
+func (b *Build) hgCmd(dir string, args ...string) ([]byte, error) {
+ return b.run(dir, "hg", append([]string{"--config", "extensions.codereview=!"}, args...)...)
+}
+
func (b *Build) run(dir, name string, args ...string) ([]byte, error) {
buf := new(bytes.Buffer)
absName, err := lookPath(name)
@@ -489,6 +625,9 @@ func (b *Build) env() []string {
"GOROOT_FINAL="+final,
"GOPATH="+b.gopath,
)
+ if b.static {
+ env = append(env, "GO_DISTFLAGS=-s")
+ }
return env
}
@@ -548,6 +687,9 @@ func (b *Build) Upload(version string, filename string) error {
if ftype != "" {
labels = append(labels, "Type-"+ftype)
}
+ if b.Label != "" {
+ labels = append(labels, b.Label)
+ }
if *addLabel != "" {
labels = append(labels, *addLabel)
}