Replace gox with a go script to do cross compiling

gox wasn't building the mips binaries for some reason.
This commit is contained in:
Nick Craig-Wood 2017-02-17 21:54:32 +00:00
parent 1d7f95da8e
commit 69a15ae173
3 changed files with 155 additions and 70 deletions

View File

@ -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)

View File

@ -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 ..

152
bin/cross-compile.go Normal file
View File

@ -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 <version>", 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)
}