From 69a15ae1739e9bd8b92f5571e0a625f892ef76ec Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 17 Feb 2017 21:54:32 +0000 Subject: [PATCH] Replace gox with a go script to do cross compiling gox wasn't building the mips binaries for some reason. --- Makefile | 7 +- bin/cross-compile | 66 ------------------- bin/cross-compile.go | 152 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+), 70 deletions(-) delete mode 100755 bin/cross-compile create mode 100644 bin/cross-compile.go diff --git a/Makefile b/Makefile index 315478a9b..a040067b8 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,6 @@ ifdef GO_LATEST go get -u github.com/kisielk/errcheck go get -u golang.org/x/tools/cmd/goimports go get -u github.com/golang/lint/golint - go get -u github.com/mitchellh/gox go get -u github.com/inconshreveable/mousetrap go get -u github.com/tools/godep endif @@ -99,16 +98,16 @@ upload_github: ./bin/upload-github $(TAG) cross: doc - ./bin/cross-compile $(TAG) + go run bin/cross-compile.go $(TAG) beta: - ./bin/cross-compile $(TAG)β + go run bin/cross-compile.go $(TAG)β rm build/*-current-* rclone -v copy build/ memstore:pub-rclone-org/$(TAG)β @echo Beta release ready at http://pub.rclone.org/$(TAG)%CE%B2/ travis_beta: - ./bin/cross-compile $(TAG)β + go run bin/cross-compile.go $(TAG)β rm build/*-current-* rclone --config bin/travis.rclone.conf -v copy build/ memstore:beta-rclone-org/$(TAG) @echo Beta release ready at $(BETA_URL) diff --git a/bin/cross-compile b/bin/cross-compile deleted file mode 100755 index 899eebd64..000000000 --- a/bin/cross-compile +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash - -set -e - -# This uses gox from https://github.com/mitchellh/gox -# Make sure you've run gox -build-toolchain - not required for go >= 1.5 - -if [ "$1" == "" ]; then - echo "Syntax: $0 Version" - exit 1 -fi -VERSION="$1" - -rm -rf build - -# Disable CGO and dynamic builds on all platforms (including build patform) -export CGO_ENABLED=0 - -# Arch pairs we build for -# gox -osarch-list - for definitive list -# go tool dist list - or this - -OSARCH="\ -windows/386 -windows/amd64 -darwin/386 -darwin/amd64 -linux/386 -linux/amd64 -linux/arm -linux/arm64 -linux/mips -linux/mipsle -freebsd/386 -freebsd/amd64 -freebsd/arm -netbsd/386 -netbsd/amd64 -netbsd/arm -openbsd/386 -openbsd/amd64 -plan9/386 -plan9/amd64 -solaris/amd64" - -# Make space separated -OSARCH=${OSARCH//$'\n'/ } - -gox --ldflags "-s -X github.com/ncw/rclone/fs.Version=${VERSION}" -output "build/{{.Dir}}-${VERSION}-{{.OS}}-{{.Arch}}/{{.Dir}}" -osarch "${OSARCH}" - -mv build/rclone-${VERSION}-darwin-amd64 build/rclone-${VERSION}-osx-amd64 -mv build/rclone-${VERSION}-darwin-386 build/rclone-${VERSION}-osx-386 - -cd build - -for d in `ls`; do - cp -a ../MANUAL.txt $d/README.txt - cp -a ../MANUAL.html $d/README.html - cp -a ../rclone.1 $d/ - zip -r9 $d.zip $d - d_current=${d/-${VERSION}/-current} - ln $d.zip $d_current.zip - rm -rf $d -done - -cd .. diff --git a/bin/cross-compile.go b/bin/cross-compile.go new file mode 100644 index 000000000..17b6ad112 --- /dev/null +++ b/bin/cross-compile.go @@ -0,0 +1,152 @@ +// +build ignore + +// Cross compile rclone - in go because I hate bash ;-) + +package main + +import ( + "flag" + "log" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "sync" + "time" +) + +var ( + // Flags + debug = flag.Bool("d", false, "Print commands instead of running them.") + parallel = flag.Int("parallel", runtime.NumCPU(), "Number of commands to run in parallel.") +) + +// GOOS/GOARCH pairs we build for +var osarches = []string{ + "windows/386", + "windows/amd64", + "darwin/386", + "darwin/amd64", + "linux/386", + "linux/amd64", + "linux/arm", + "linux/arm64", + "linux/mips", + "linux/mipsle", + "freebsd/386", + "freebsd/amd64", + "freebsd/arm", + "netbsd/386", + "netbsd/amd64", + "netbsd/arm", + "openbsd/386", + "openbsd/amd64", + "plan9/386", + "plan9/amd64", + "solaris/amd64", +} + +// runEnv - run a shell command with env +func runEnv(args, env []string) { + if *debug { + args = append([]string{"echo"}, args...) + } + cmd := exec.Command(args[0], args[1:]...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if env != nil { + cmd.Env = append(os.Environ(), env...) + } + err := cmd.Run() + if err != nil { + log.Fatalf("Failed to run %v: %v", args, err) + } +} + +// run a shell command +func run(args ...string) { + runEnv(args, nil) +} + +// build the binary in dir +func compileArch(version, goos, goarch, dir string) { + log.Printf("Compiling %s/%s", goos, goarch) + output := filepath.Join(dir, "rclone") + err := os.MkdirAll(dir, 0777) + if err != nil { + log.Fatalf("Failed to mkdir: %v", err) + } + args := []string{ + "go", "build", + "--ldflags", "-s -X github.com/ncw/rclone/fs.Version=" + version, + "-i", + "-o", output, + "..", + } + env := []string{ + "GOOS=" + goos, + "GOARCH=" + goarch, + "CGO_ENABLED=0", + } + runEnv(args, env) + // Now build the zip + run("cp", "-a", "../MANUAL.txt", filepath.Join(dir, "README.txt")) + run("cp", "-a", "../MANUAL.html", filepath.Join(dir, "README.html")) + run("cp", "-a", "../rclone.1", dir) + zip := dir + ".zip" + run("zip", "-r9", zip, dir) + currentZip := strings.Replace(zip, "-"+version, "-current", 1) + run("ln", zip, currentZip) + run("rm", "-rf", dir) + log.Printf("Done compiling %s/%s", goos, goarch) +} + +func compile(version string) { + start := time.Now() + wg := new(sync.WaitGroup) + run := make(chan func(), *parallel) + for i := 0; i < *parallel; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for f := range run { + f() + } + }() + } + for _, osarch := range osarches { + parts := strings.Split(osarch, "/") + if len(parts) != 2 { + log.Fatalf("Bad osarch %q", osarch) + } + goos, goarch := parts[0], parts[1] + userGoos := goos + if goos == "darwin" { + userGoos = "osx" + } + dir := filepath.Join("rclone-" + version + "-" + userGoos + "-" + goarch) + run <- func() { + compileArch(version, goos, goarch, dir) + } + } + close(run) + wg.Wait() + log.Printf("Compiled %d arches in %v", len(osarches), time.Since(start)) +} + +func main() { + flag.Parse() + args := flag.Args() + if len(args) != 1 { + log.Fatalf("Syntax: %s ", os.Args[0]) + } + version := args[0] + run("rm", "-rf", "build") + run("mkdir", "build") + err := os.Chdir("build") + if err != nil { + log.Fatalf("Couldn't cd into build dir: %v", err) + } + compile(version) +}