2015-05-08 12:21:51 +03:00
#!/bin/bash
#
# Contains the main cross compiler, that individually sets up each target build
# platform, compiles all the C dependencies, then build the requested executable
# itself.
#
# Usage: build.sh <import path>
#
# Needed environment variables:
# REPO_REMOTE - Optional VCS remote if not the primary repository is needed
# REPO_BRANCH - Optional VCS branch to use, if not the master branch
# DEPS - Optional list of C dependency packages to build
# PACK - Optional sub-package, if not the import path is being built
# OUT - Optional output prefix to override the package name
# FLAG_V - Optional verbosity flag to set on the Go builder
2015-09-14 18:02:27 +03:00
# FLAG_X - Optional flag to print the build progress commands
2015-05-08 12:21:51 +03:00
# FLAG_RACE - Optional race flag to set on the Go builder
2015-09-14 18:02:27 +03:00
# TARGETS - Comma separated list of build targets to compile for
# GO_VERSION - Bootstrapped version of Go to disable uncupported targets
2015-09-17 16:10:47 +03:00
# EXT_GOPATH - GOPATH elements mounted from the host filesystem
2015-05-08 12:21:51 +03:00
2015-09-17 16:10:47 +03:00
if [ " $EXT_GOPATH " != "" ] ; then
# If local builds are requested, inject the sources
echo " Building locally $1 ... "
export GOPATH = $GOPATH :$EXT_GOPATH
set -e
2015-05-08 12:21:51 +03:00
2015-09-17 16:10:47 +03:00
# Find and change into the package folder
cd ` go list -e -f { { .Dir} } $1 `
export GOPATH = $GOPATH :` pwd ` /Godeps/_workspace
else
2015-09-29 10:35:27 +03:00
# Inject all possible Godep paths to short circuit go gets
GOPATH_ROOT = $GOPATH /src
IMPORT_PATH = $1
while [ " $IMPORT_PATH " != "." ] ; do
export GOPATH = $GOPATH :$GOPATH_ROOT /$IMPORT_PATH /Godeps/_workspace
IMPORT_PATH = ` dirname $IMPORT_PATH `
done
2015-09-17 16:10:47 +03:00
# Otherwise download the canonical import path (may fail, don't allow failures beyond)
echo " Fetching main repository $1 ... "
2015-09-29 10:35:27 +03:00
go get -v -d $1
2015-09-17 16:10:47 +03:00
set -e
2015-05-08 12:21:51 +03:00
2015-09-29 10:35:27 +03:00
cd $GOPATH_ROOT /$1
2015-05-08 12:21:51 +03:00
2015-09-17 16:10:47 +03:00
# Switch over the code-base to another checkout if requested
2015-09-29 11:38:35 +03:00
if [ " $REPO_REMOTE " != "" ] || [ " $REPO_BRANCH " != "" ] ; then
# Detect the version control system type
IMPORT_PATH = $1
while [ " $IMPORT_PATH " != "." ] && [ " $REPO_TYPE " = = "" ] ; do
if [ -d " $GOPATH_ROOT / $IMPORT_PATH /.git " ] ; then
REPO_TYPE = "git"
elif [ -d " $GOPATH_ROOT / $IMPORT_PATH /.hg " ] ; then
REPO_TYPE = "hg"
fi
IMPORT_PATH = ` dirname $IMPORT_PATH `
done
if [ " $REPO_TYPE " = = "" ] ; then
echo "Unknown version control system type, cannot switch remotes and branches."
exit -1
2015-09-17 16:10:47 +03:00
fi
2015-09-29 11:38:35 +03:00
# If we have a valid VCS, execute the switch operations
if [ " $REPO_REMOTE " != "" ] ; then
echo " Switching over to remote $REPO_REMOTE ... "
if [ " $REPO_TYPE " = = "git" ] ; then
git remote set-url origin $REPO_REMOTE
git pull
elif [ " $REPO_TYPE " = = "hg" ] ; then
echo -e " [paths]\ndefault = $REPO_REMOTE \n " >> .hg/hgrc
hg pull
fi
fi
if [ " $REPO_BRANCH " != "" ] ; then
echo " Switching over to branch $REPO_BRANCH ... "
if [ " $REPO_TYPE " = = "git" ] ; then
git checkout $REPO_BRANCH
elif [ " $REPO_TYPE " = = "hg" ] ; then
hg checkout $REPO_BRANCH
fi
2015-09-17 16:10:47 +03:00
fi
2015-05-08 12:21:51 +03:00
fi
fi
# Download all the C dependencies
mkdir /deps
DEPS = ( $DEPS ) && for dep in " ${ DEPS [@] } " ; do
2015-09-19 18:36:24 +03:00
if [ " ${ dep ##*. } " = = "tar" ] ; then cat " /deps-cache/`basename $dep ` " | tar -C /deps -x; fi
if [ " ${ dep ##*. } " = = "gz" ] ; then cat " /deps-cache/`basename $dep ` " | tar -C /deps -xz; fi
if [ " ${ dep ##*. } " = = "bz2" ] ; then cat " /deps-cache/`basename $dep ` " | tar -C /deps -xj; fi
2015-05-08 12:21:51 +03:00
done
# Configure some global build parameters
NAME = ` basename $1 /$PACK `
if [ " $OUT " != "" ] ; then
NAME = $OUT
fi
2015-10-28 12:16:25 +02:00
if [ " $FLAG_V " = = "true" ] ; then V = -v; fi
if [ " $FLAG_X " = = "true" ] ; then X = -x; fi
2015-05-08 12:21:51 +03:00
if [ " $FLAG_RACE " = = "true" ] ; then R = -race; fi
2015-10-28 12:16:25 +02:00
if [ " $FLAG_TAGS " != "" ] ; then T = ( --tags " $FLAG_TAGS " ) ; fi
if [ " $FLAG_LDFLAGS " != "" ] ; then LD = " $FLAG_LDFLAGS " ; fi
2015-05-08 12:21:51 +03:00
2015-09-14 18:02:27 +03:00
# If no build targets were specified, inject a catch all wildcard
if [ " $TARGETS " = = "" ] ; then
TARGETS = "./."
fi
# Build for each requested platform individually
for TARGET in $TARGETS ; do
# Split the target into platform and architecture
XGOOS = ` echo $TARGET | cut -d '/' -f 1`
XGOARCH = ` echo $TARGET | cut -d '/' -f 2`
# Check and build for Android targets
if ( [ $XGOOS = = "." ] || [ [ $XGOOS = = android* ] ] ) ; then
# Split the platform version and configure the linker options
PLATFORM = ` echo $XGOOS | cut -d '-' -f 2`
2015-11-03 18:59:59 +02:00
if [ " $PLATFORM " = = "" ] || [ " $PLATFORM " = = "." ] || [ " $PLATFORM " = = "android" ] ; then
PLATFORM = 16 # Jelly Bean 4.0.0
2015-09-14 18:02:27 +03:00
fi
2015-09-14 18:28:45 +03:00
if [ " $PLATFORM " -ge 16 ] ; then
2015-09-14 18:02:27 +03:00
CGO_CCPIE = "-fPIE"
CGO_LDPIE = "-fPIE"
2015-10-22 19:07:35 +03:00
EXT_LDPIE = "-extldflags=-pie -extldflags=-Wl,--allow-multiple-definition"
2015-09-17 18:47:31 +03:00
else
unset CGO_CCPIE CGO_LDPIE EXT_LDPIE
2015-09-14 18:02:27 +03:00
fi
# Iterate over the requested architectures, bootstrap and
if [ $XGOARCH = = "." ] || [ $XGOARCH = = "arm" ] ; then
if [ " $GO_VERSION " -lt 150 ] ; then
echo " Go version too low, skipping android- $PLATFORM /arm... "
else
2015-09-16 17:10:18 +03:00
echo " Assembling toolchain for android- $PLATFORM /arm... "
2015-09-17 18:47:31 +03:00
$ANDROID_NDK_ROOT /build/tools/make-standalone-toolchain.sh --ndk-dir= $ANDROID_NDK_ROOT --install-dir= /usr/$ANDROID_CHAIN_ARM --toolchain= $ANDROID_CHAIN_ARM --arch= arm --system= linux-x86_64 > /dev/null 2>& 1
2015-09-14 18:02:27 +03:00
echo " Bootstrapping android- $PLATFORM /arm... "
2015-09-16 17:10:18 +03:00
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
2015-09-14 18:02:27 +03:00
echo " Compiling for android- $PLATFORM /arm... "
2015-09-17 16:10:47 +03:00
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
2015-10-28 12:16:25 +02:00
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 " ${ T [@] } " --ldflags= " $LD " -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 $V $X " ${ T [@] } " --ldflags= " $EXT_LDPIE $LD " -o /build/$NAME -android-$PLATFORM -arm ./$PACK
2015-09-14 18:02:27 +03:00
fi
fi
fi
# Check and build for Linux targets
if ( [ $XGOOS = = "." ] || [ $XGOOS = = "linux" ] ) && ( [ $XGOARCH = = "." ] || [ $XGOARCH = = "amd64" ] ) ; then
echo "Compiling for linux/amd64..."
HOST = x86_64-linux PREFIX = /usr/local $BUILD_DEPS /deps
2015-10-28 12:16:25 +02:00
GOOS = linux GOARCH = amd64 CGO_ENABLED = 1 go get $V $X " ${ T [@] } " --ldflags= " $LD " -d ./$PACK
GOOS = linux GOARCH = amd64 CGO_ENABLED = 1 go build $V $X " ${ T [@] } " --ldflags= " $LD " $R -o /build/$NAME -linux-amd64$R ./$PACK
2015-09-14 18:02:27 +03:00
fi
if ( [ $XGOOS = = "." ] || [ $XGOOS = = "linux" ] ) && ( [ $XGOARCH = = "." ] || [ $XGOARCH = = "386" ] ) ; then
echo "Compiling for linux/386..."
HOST = i686-linux PREFIX = /usr/local $BUILD_DEPS /deps
2015-10-28 12:16:25 +02:00
GOOS = linux GOARCH = 386 CGO_ENABLED = 1 go get $V $X " ${ T [@] } " --ldflags= " $LD " -d ./$PACK
GOOS = linux GOARCH = 386 CGO_ENABLED = 1 go build $V $X " ${ T [@] } " --ldflags= " $LD " -o /build/$NAME -linux-386 ./$PACK
2015-09-14 18:02:27 +03:00
fi
if ( [ $XGOOS = = "." ] || [ $XGOOS = = "linux" ] ) && ( [ $XGOARCH = = "." ] || [ $XGOARCH = = "arm" ] ) ; then
echo "Compiling for linux/arm..."
2015-11-03 12:35:56 +02:00
CC = arm-linux-gnueabi-gcc-5 CXX = arm-linux-gnueabi-g++-5 HOST = arm-linux PREFIX = /usr/local/arm $BUILD_DEPS /deps
CC = arm-linux-gnueabi-gcc-5 CXX = arm-linux-gnueabi-g++-5 GOOS = linux GOARCH = arm CGO_ENABLED = 1 GOARM = 5 go get $V $X " ${ T [@] } " --ldflags= " $LD " -d ./$PACK
CC = arm-linux-gnueabi-gcc-5 CXX = arm-linux-gnueabi-g++-5 GOOS = linux GOARCH = arm CGO_ENABLED = 1 GOARM = 5 go build $V $X " ${ T [@] } " --ldflags= " $LD " -o /build/$NAME -linux-arm ./$PACK
2015-09-14 18:02:27 +03:00
fi
# Check and build for Windows targets
2015-11-03 18:04:33 +02:00
if [ $XGOOS = = "." ] || [ [ $XGOOS = = windows* ] ] ; then
# Split the platform version and configure the Windows NT version
PLATFORM = ` echo $XGOOS | cut -d '-' -f 2`
2015-11-03 18:59:59 +02:00
if [ " $PLATFORM " = = "" ] || [ " $PLATFORM " = = "." ] || [ " $PLATFORM " = = "windows" ] ; then
PLATFORM = 4.0 # Windows NT
fi
MAJOR = ` echo $PLATFORM | cut -d '.' -f 1`
if [ " ${ PLATFORM /. } " != " $PLATFORM " ] ; then
MINOR = ` echo $PLATFORM | cut -d '.' -f 2`
2015-11-03 18:04:33 +02:00
fi
2015-11-03 18:59:59 +02:00
CGO_NTDEF = "-D_WIN32_WINNT=0x`printf " %02d" $MAJOR ``printf " %02d" $MINOR ` "
2015-11-03 18:04:33 +02:00
# Build the requested windows binaries
if [ $XGOARCH = = "." ] || [ $XGOARCH = = "amd64" ] ; then
2015-11-03 18:59:59 +02:00
echo " Compiling for windows- $PLATFORM /amd64... "
2015-11-03 18:04:33 +02:00
CC = x86_64-w64-mingw32-gcc-posix CXX = x86_64-w64-mingw32-g++-posix HOST = x86_64-w64-mingw32 PREFIX = /usr/x86_64-w64-mingw32 $BUILD_DEPS /deps
CC = x86_64-w64-mingw32-gcc-posix CXX = x86_64-w64-mingw32-g++-posix GOOS = windows GOARCH = amd64 CGO_ENABLED = 1 CGO_CFLAGS = " $CGO_NTDEF " CGO_CXXFLAGS = " $CGO_NTDEF " go get $V $X " ${ T [@] } " --ldflags= " $LD " -d ./$PACK
2015-11-03 18:59:59 +02:00
CC = x86_64-w64-mingw32-gcc-posix CXX = x86_64-w64-mingw32-g++-posix GOOS = windows GOARCH = amd64 CGO_ENABLED = 1 CGO_CFLAGS = " $CGO_NTDEF " CGO_CXXFLAGS = " $CGO_NTDEF " go build $V $X " ${ T [@] } " --ldflags= " $LD " $R -o /build/$NAME -windows-$PLATFORM -amd64$R .exe ./$PACK
2015-11-03 18:04:33 +02:00
fi
if [ $XGOARCH = = "." ] || [ $XGOARCH = = "386" ] ; then
2015-11-03 18:59:59 +02:00
echo " Compiling for windows- $PLATFORM /386... "
2015-11-03 18:04:33 +02:00
CC = i686-w64-mingw32-gcc-posix CXX = i686-w64-mingw32-g++-posix HOST = i686-w64-mingw32 PREFIX = /usr/i686-w64-mingw32 $BUILD_DEPS /deps
CC = i686-w64-mingw32-gcc-posix CXX = i686-w64-mingw32-g++-posix GOOS = windows GOARCH = 386 CGO_ENABLED = 1 CGO_CFLAGS = " $CGO_NTDEF " CGO_CXXFLAGS = " $CGO_NTDEF " go get $V $X " ${ T [@] } " --ldflags= " $LD " -d ./$PACK
2015-11-03 18:59:59 +02:00
CC = i686-w64-mingw32-gcc-posix CXX = i686-w64-mingw32-g++-posix GOOS = windows GOARCH = 386 CGO_ENABLED = 1 CGO_CFLAGS = " $CGO_NTDEF " CGO_CXXFLAGS = " $CGO_NTDEF " go build $V $X " ${ T [@] } " --ldflags= " $LD " -o /build/$NAME -windows-$PLATFORM -386.exe ./$PACK
2015-11-03 18:04:33 +02:00
fi
2015-09-14 18:02:27 +03:00
fi
# Check and build for OSX targets
2015-11-03 18:04:33 +02:00
if [ $XGOOS = = "." ] || [ [ $XGOOS = = darwin* ] ] ; then
# Split the platform version and configure the deployment target
PLATFORM = ` echo $XGOOS | cut -d '-' -f 2`
2015-11-03 18:59:59 +02:00
if [ " $PLATFORM " = = "" ] || [ " $PLATFORM " = = "." ] || [ " $PLATFORM " = = "darwin" ] ; then
PLATFORM = 10.6 # OS X Snow Leopard
2015-11-03 18:04:33 +02:00
fi
2015-11-03 18:59:59 +02:00
export MACOSX_DEPLOYMENT_TARGET = $PLATFORM
2015-11-03 18:04:33 +02:00
# Build the requested darwin binaries
if [ $XGOARCH = = "." ] || [ $XGOARCH = = "amd64" ] ; then
2015-11-03 18:59:59 +02:00
echo " Compiling for darwin- $PLATFORM /amd64... "
2015-11-03 18:04:33 +02:00
CC = o64-clang CXX = o64-clang++ HOST = x86_64-apple-darwin13 PREFIX = /usr/local $BUILD_DEPS /deps
CC = o64-clang CXX = o64-clang++ GOOS = darwin GOARCH = amd64 CGO_ENABLED = 1 go get $V $X " ${ T [@] } " --ldflags= " -s $LD " -d ./$PACK
2015-11-03 18:59:59 +02:00
CC = o64-clang CXX = o64-clang++ GOOS = darwin GOARCH = amd64 CGO_ENABLED = 1 go build $V $X " ${ T [@] } " --ldflags= " -s $LD " $R -o /build/$NAME -darwin-$PLATFORM -amd64$R ./$PACK
2015-11-03 18:04:33 +02:00
fi
if [ $XGOARCH = = "." ] || [ $XGOARCH = = "386" ] ; then
2015-11-03 18:59:59 +02:00
echo " Compiling for darwin- $PLATFORM /386... "
2015-11-03 18:04:33 +02:00
CC = o32-clang CXX = o32-clang++ HOST = i386-apple-darwin13 PREFIX = /usr/local $BUILD_DEPS /deps
CC = o32-clang CXX = o32-clang++ GOOS = darwin GOARCH = 386 CGO_ENABLED = 1 go get $V $X " ${ T [@] } " --ldflags= " -s $LD " -d ./$PACK
2015-11-03 18:59:59 +02:00
CC = o32-clang CXX = o32-clang++ GOOS = darwin GOARCH = 386 CGO_ENABLED = 1 go build $V $X " ${ T [@] } " --ldflags= " -s $LD " -o /build/$NAME -darwin-$PLATFORM -386 ./$PACK
2015-11-03 18:04:33 +02:00
fi
# Remove any automatically injected deployment target vars
unset MACOSX_DEPLOYMENT_TARGET
2015-09-14 18:02:27 +03:00
fi
done