mirror of https://github.com/status-im/xgo.git
Add support for local import paths.
This commit is contained in:
parent
3544aa27ec
commit
1827c25933
|
@ -62,6 +62,10 @@ Simply specify the import path you want to build, and xgo will do the rest:
|
|||
-rwxr-xr-x 1 root root 7131477 Sep 14 18:05 iris-windows-386.exe
|
||||
-rwxr-xr-x 1 root root 8963900 Sep 14 18:05 iris-windows-amd64.exe
|
||||
|
||||
If the path is not a canonical import path, but rather a local path (starts with
|
||||
a dot `.` or a dash `/`), xgo will use the local GOPATH contents for the cross
|
||||
compilation.
|
||||
|
||||
|
||||
### Build flags
|
||||
|
||||
|
|
|
@ -17,33 +17,44 @@
|
|||
# FLAG_RACE - Optional race flag to set on the Go builder
|
||||
# TARGETS - Comma separated list of build targets to compile for
|
||||
# GO_VERSION - Bootstrapped version of Go to disable uncupported targets
|
||||
# EXT_GOPATH - GOPATH elements mounted from the host filesystem
|
||||
|
||||
# Download the canonical import path (may fail, don't allow failures beyond)
|
||||
echo "Fetching main repository $1..."
|
||||
go get -d $1
|
||||
set -e
|
||||
if [ "$EXT_GOPATH" != "" ]; then
|
||||
# If local builds are requested, inject the sources
|
||||
echo "Building locally $1..."
|
||||
export GOPATH=$GOPATH:$EXT_GOPATH
|
||||
set -e
|
||||
|
||||
cd $GOPATH/src/$1
|
||||
export GOPATH=$GOPATH:`pwd`/Godeps/_workspace
|
||||
# Find and change into the package folder
|
||||
cd `go list -e -f {{.Dir}} $1`
|
||||
export GOPATH=$GOPATH:`pwd`/Godeps/_workspace
|
||||
else
|
||||
# Otherwise download the canonical import path (may fail, don't allow failures beyond)
|
||||
echo "Fetching main repository $1..."
|
||||
go get -d $1
|
||||
set -e
|
||||
|
||||
# Switch over the code-base to another checkout if requested
|
||||
if [ "$REPO_REMOTE" != "" ]; then
|
||||
echo "Switching over to remote $REPO_REMOTE..."
|
||||
if [ -d ".git" ]; then
|
||||
git remote set-url origin $REPO_REMOTE
|
||||
git pull
|
||||
elif [ -d ".hg" ]; then
|
||||
echo -e "[paths]\ndefault = $REPO_REMOTE\n" >> .hg/hgrc
|
||||
hg pull
|
||||
cd $GOPATH/src/$1
|
||||
export GOPATH=$GOPATH:`pwd`/Godeps/_workspace
|
||||
|
||||
# Switch over the code-base to another checkout if requested
|
||||
if [ "$REPO_REMOTE" != "" ]; then
|
||||
echo "Switching over to remote $REPO_REMOTE..."
|
||||
if [ -d ".git" ]; then
|
||||
git remote set-url origin $REPO_REMOTE
|
||||
git pull
|
||||
elif [ -d ".hg" ]; then
|
||||
echo -e "[paths]\ndefault = $REPO_REMOTE\n" >> .hg/hgrc
|
||||
hg pull
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$REPO_BRANCH" != "" ]; then
|
||||
echo "Switching over to branch $REPO_BRANCH..."
|
||||
if [ -d ".git" ]; then
|
||||
git checkout $REPO_BRANCH
|
||||
elif [ -d ".hg" ]; then
|
||||
hg checkout $REPO_BRANCH
|
||||
if [ "$REPO_BRANCH" != "" ]; then
|
||||
echo "Switching over to branch $REPO_BRANCH..."
|
||||
if [ -d ".git" ]; then
|
||||
git checkout $REPO_BRANCH
|
||||
elif [ -d ".hg" ]; then
|
||||
hg checkout $REPO_BRANCH
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -73,7 +84,6 @@ if [ "$TARGETS" == "" ]; then
|
|||
fi
|
||||
|
||||
# Build for each requested platform individually
|
||||
builds=0
|
||||
for TARGET in $TARGETS; do
|
||||
# Split the target into platform and architecture
|
||||
XGOOS=`echo $TARGET | cut -d '/' -f 1`
|
||||
|
@ -103,10 +113,9 @@ for TARGET in $TARGETS; do
|
|||
CC=arm-linux-androideabi-gcc GOOS=android GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go install std
|
||||
|
||||
echo "Compiling for android-$PLATFORM/arm..."
|
||||
CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ HOST=arm-linux-androideabi PREFIX=/usr/$ANDROID_CHAIN_ARM $BUILD_DEPS /deps
|
||||
CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ HOST=arm-linux-androideabi PREFIX=/usr/$ANDROID_CHAIN_ARM/arm-linux-androideabi $BUILD_DEPS /deps
|
||||
CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ GOOS=android GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE" CGO_CXXFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go get $V $X -d ./$PACK
|
||||
CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ GOOS=android GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE" CGO_CXXFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go build --ldflags="$EXT_LDPIE" $V $X $R -o $NAME-android-$PLATFORM-arm$R ./$PACK
|
||||
builds=$((builds+1))
|
||||
CC=arm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ GOOS=android GOARCH=arm GOARM=7 CGO_ENABLED=1 CGO_CFLAGS="$CGO_CCPIE" CGO_CXXFLAGS="$CGO_CCPIE" CGO_LDFLAGS="$CGO_LDPIE" go build --ldflags="$EXT_LDPIE" $V $X $R -o /build/$NAME-android-$PLATFORM-arm$R ./$PACK
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
@ -115,58 +124,44 @@ for TARGET in $TARGETS; do
|
|||
echo "Compiling for linux/amd64..."
|
||||
HOST=x86_64-linux PREFIX=/usr/local $BUILD_DEPS /deps
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go get $V $X -d ./$PACK
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build $V $X $R -o $NAME-linux-amd64$R ./$PACK
|
||||
builds=$((builds+1))
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build $V $X $R -o /build/$NAME-linux-amd64$R ./$PACK
|
||||
fi
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "386" ]); then
|
||||
echo "Compiling for linux/386..."
|
||||
HOST=i686-linux PREFIX=/usr/local $BUILD_DEPS /deps
|
||||
GOOS=linux GOARCH=386 CGO_ENABLED=1 go get $V $X -d ./$PACK
|
||||
GOOS=linux GOARCH=386 CGO_ENABLED=1 go build $V $X -o $NAME-linux-386 ./$PACK
|
||||
builds=$((builds+1))
|
||||
GOOS=linux GOARCH=386 CGO_ENABLED=1 go build $V $X -o /build/$NAME-linux-386 ./$PACK
|
||||
fi
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "arm" ]); then
|
||||
echo "Compiling for linux/arm..."
|
||||
CC=arm-linux-gnueabi-gcc CXX=arm-linux-gnueabi-g++ HOST=arm-linux PREFIX=/usr/local/arm $BUILD_DEPS /deps
|
||||
CC=arm-linux-gnueabi-gcc CXX=arm-linux-gnueabi-g++ GOOS=linux GOARCH=arm CGO_ENABLED=1 GOARM=5 go get $V $X -d ./$PACK
|
||||
CC=arm-linux-gnueabi-gcc CXX=arm-linux-gnueabi-g++ GOOS=linux GOARCH=arm CGO_ENABLED=1 GOARM=5 go build $V $X -o $NAME-linux-arm ./$PACK
|
||||
builds=$((builds+1))
|
||||
CC=arm-linux-gnueabi-gcc CXX=arm-linux-gnueabi-g++ GOOS=linux GOARCH=arm CGO_ENABLED=1 GOARM=5 go build $V $X -o /build/$NAME-linux-arm ./$PACK
|
||||
fi
|
||||
# Check and build for Windows targets
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "windows" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ]); then
|
||||
echo "Compiling for windows/amd64..."
|
||||
CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ HOST=x86_64-w64-mingw32 PREFIX=/usr/x86_64-w64-mingw32 $BUILD_DEPS /deps
|
||||
CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ GOOS=windows GOARCH=amd64 CGO_ENABLED=1 go get $V $X -d ./$PACK
|
||||
CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ GOOS=windows GOARCH=amd64 CGO_ENABLED=1 go build $V $X $R -o $NAME-windows-amd64$R.exe ./$PACK
|
||||
builds=$((builds+1))
|
||||
CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ GOOS=windows GOARCH=amd64 CGO_ENABLED=1 go build $V $X $R -o /build/$NAME-windows-amd64$R.exe ./$PACK
|
||||
fi
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "windows" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "386" ]); then
|
||||
echo "Compiling for windows/386..."
|
||||
CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ HOST=i686-w64-mingw32 PREFIX=/usr/i686-w64-mingw32 $BUILD_DEPS /deps
|
||||
CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ GOOS=windows GOARCH=386 CGO_ENABLED=1 go get $V $X -d ./$PACK
|
||||
CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ GOOS=windows GOARCH=386 CGO_ENABLED=1 go build $V $X -o $NAME-windows-386.exe ./$PACK
|
||||
builds=$((builds+1))
|
||||
CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ GOOS=windows GOARCH=386 CGO_ENABLED=1 go build $V $X -o /build/$NAME-windows-386.exe ./$PACK
|
||||
fi
|
||||
# Check and build for OSX targets
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "darwin" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ]); then
|
||||
echo "Compiling for darwin/amd64..."
|
||||
CC=o64-clang CXX=o64-clang++ HOST=x86_64-apple-darwin10 PREFIX=/usr/local $BUILD_DEPS /deps
|
||||
CC=o64-clang CXX=o64-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go get $V $X -d ./$PACK
|
||||
CC=o64-clang CXX=o64-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go build -ldflags=-s $V $X $R -o $NAME-darwin-amd64$R ./$PACK
|
||||
builds=$((builds+1))
|
||||
CC=o64-clang CXX=o64-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go build -ldflags=-s $V $X $R -o /build/$NAME-darwin-amd64$R ./$PACK
|
||||
fi
|
||||
if ([ $XGOOS == "." ] || [ $XGOOS == "darwin" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "386" ]); then
|
||||
echo "Compiling for darwin/386..."
|
||||
CC=o32-clang CXX=o32-clang++ HOST=i386-apple-darwin10 PREFIX=/usr/local $BUILD_DEPS /deps
|
||||
CC=o32-clang CXX=o32-clang++ GOOS=darwin GOARCH=386 CGO_ENABLED=1 go get $V $X -d ./$PACK
|
||||
CC=o32-clang CXX=o32-clang++ GOOS=darwin GOARCH=386 CGO_ENABLED=1 go build -ldflags=-s $V $X -o $NAME-darwin-386 ./$PACK
|
||||
builds=$((builds+1))
|
||||
CC=o32-clang CXX=o32-clang++ GOOS=darwin GOARCH=386 CGO_ENABLED=1 go build -ldflags=-s $V $X -o /build/$NAME-darwin-386 ./$PACK
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$builds" -eq 0 ]; then
|
||||
echo "No build targets matched!"
|
||||
else
|
||||
echo "Moving $builds binaries to host..."
|
||||
cp `ls -t | head -n $builds` /build
|
||||
fi
|
||||
|
|
80
xgo.go
80
xgo.go
|
@ -10,9 +10,12 @@ import (
|
|||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -21,14 +24,16 @@ var dockerBase = "karalabe/xgo-base"
|
|||
var dockerDist = "karalabe/xgo-"
|
||||
|
||||
// Command line arguments to fine tune the compilation
|
||||
var goVersion = flag.String("go", "latest", "Go release to use for cross compilation")
|
||||
var inPackage = flag.String("pkg", "", "Sub-package to build if not root import")
|
||||
var outPrefix = flag.String("out", "", "Prefix to use for output naming (empty = package name)")
|
||||
var srcRemote = flag.String("remote", "", "Version control remote repository to build")
|
||||
var srcBranch = flag.String("branch", "", "Version control branch to build")
|
||||
var crossDeps = flag.String("deps", "", "CGO dependencies (configure/make based archives)")
|
||||
var targets = flag.String("targets", "*/*", "Comma separated targets to build for")
|
||||
var dockerImage = flag.String("image", "", "Use a custom docker image instead of official distribution")
|
||||
var (
|
||||
goVersion = flag.String("go", "latest", "Go release to use for cross compilation")
|
||||
inPackage = flag.String("pkg", "", "Sub-package to build if not root import")
|
||||
outPrefix = flag.String("out", "", "Prefix to use for output naming (empty = package name)")
|
||||
srcRemote = flag.String("remote", "", "Version control remote repository to build")
|
||||
srcBranch = flag.String("branch", "", "Version control branch to build")
|
||||
crossDeps = flag.String("deps", "", "CGO dependencies (configure/make based archives)")
|
||||
targets = flag.String("targets", "*/*", "Comma separated targets to build for")
|
||||
dockerImage = flag.String("image", "", "Use custom docker image instead of official distribution")
|
||||
)
|
||||
|
||||
// Command line arguments to pass to go build
|
||||
var buildVerbose = flag.Bool("v", false, "Print the names of packages as they are compiled")
|
||||
|
@ -46,12 +51,11 @@ func main() {
|
|||
if len(flag.Args()) != 1 {
|
||||
log.Fatalf("Usage: %s [options] <go import path>", os.Args[0])
|
||||
}
|
||||
|
||||
// Select the image to use, either official or custom
|
||||
image := dockerDist + *goVersion
|
||||
if dockerImage != nil {
|
||||
if *dockerImage != "" {
|
||||
image = *dockerImage
|
||||
}
|
||||
|
||||
// Check that all required images are available
|
||||
found, err := checkDockerImage(image)
|
||||
switch {
|
||||
|
@ -99,23 +103,59 @@ func pullDockerImage(image string) error {
|
|||
|
||||
// Cross compiles a requested package into the current working directory.
|
||||
func compile(repo string, image string, remote string, branch string, pack string, deps string, prefix string, verbose bool, steps bool, race bool, targets []string) error {
|
||||
// Retrieve the current folder to store the binaries in
|
||||
folder, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to retrieve the working directory: %v.", err)
|
||||
}
|
||||
// If a local build was requested, find the import path and mount all GOPATH sources
|
||||
locals, mounts, paths := []string{}, []string{}, []string{}
|
||||
if strings.HasPrefix(repo, string(filepath.Separator)) || strings.HasPrefix(repo, ".") {
|
||||
// Resolve the repository import path from the file path
|
||||
path, err := filepath.Abs(repo)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to locate requested package: %v.", err)
|
||||
}
|
||||
stat, err := os.Stat(path)
|
||||
if err != nil || !stat.IsDir() {
|
||||
log.Fatalf("Requested path invalid.")
|
||||
}
|
||||
pack, err := build.ImportDir(path, build.FindOnly)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to resolve import path: %v.", err)
|
||||
}
|
||||
repo = pack.ImportPath
|
||||
|
||||
// Iterate over all the local libs and export the mount points
|
||||
for i, gopath := range strings.Split(os.Getenv("GOPATH"), string(os.PathListSeparator)) {
|
||||
locals = append(locals, filepath.Join(gopath, "src"))
|
||||
mounts = append(mounts, filepath.Join("/ext-go", strconv.Itoa(i), "src"))
|
||||
paths = append(paths, filepath.Join("/ext-go", strconv.Itoa(i)))
|
||||
}
|
||||
}
|
||||
// Assemble and run the cross compilation command
|
||||
fmt.Printf("Cross compiling %s...\n", repo)
|
||||
return run(exec.Command("docker", "run",
|
||||
"-v", folder+":/build",
|
||||
"-e", "REPO_REMOTE="+remote,
|
||||
"-e", "REPO_BRANCH="+branch,
|
||||
"-e", "PACK="+pack,
|
||||
"-e", "DEPS="+deps,
|
||||
"-e", "OUT="+prefix,
|
||||
|
||||
args := []string{
|
||||
"run",
|
||||
"-v", folder + ":/build",
|
||||
"-e", "REPO_REMOTE=" + remote,
|
||||
"-e", "REPO_BRANCH=" + branch,
|
||||
"-e", "PACK=" + pack,
|
||||
"-e", "DEPS=" + deps,
|
||||
"-e", "OUT=" + prefix,
|
||||
"-e", fmt.Sprintf("FLAG_V=%v", verbose),
|
||||
"-e", fmt.Sprintf("FLAG_X=%v", steps),
|
||||
"-e", fmt.Sprintf("FLAG_RACE=%v", race),
|
||||
"-e", "TARGETS="+strings.Replace(strings.Join(targets, " "), "*", ".", -1),
|
||||
image, repo))
|
||||
"-e", "TARGETS=" + strings.Replace(strings.Join(targets, " "), "*", ".", -1),
|
||||
}
|
||||
for i := 0; i < len(locals); i++ {
|
||||
args = append(args, []string{"-v", fmt.Sprintf("%s:%s:ro", locals[i], mounts[i])}...)
|
||||
}
|
||||
args = append(args, []string{"-e", "EXT_GOPATH=" + strings.Join(paths, ":")}...)
|
||||
|
||||
args = append(args, []string{image, repo}...)
|
||||
return run(exec.Command("docker", args...))
|
||||
}
|
||||
|
||||
// Executes a command synchronously, redirecting its output to stdout.
|
||||
|
|
Loading…
Reference in New Issue