Add support for iOS cross compilation.

This commit is contained in:
Péter Szilágyi 2015-11-24 16:47:29 +02:00
parent 1b23ab2797
commit 586ac3cd87
5 changed files with 153 additions and 68 deletions

View File

@ -53,14 +53,16 @@ Simply specify the import path you want to build, and xgo will do the rest:
... ...
$ ls -al $ ls -al
-rwxr-xr-x 1 root root 10899488 Sep 14 18:05 iris-android-21-arm -rwxr-xr-x 1 root root 9995000 Nov 24 16:44 iris-android-16-arm
-rwxr-xr-x 1 root root 6442188 Sep 14 18:05 iris-darwin-386 -rwxr-xr-x 1 root root 6776500 Nov 24 16:44 iris-darwin-10.6-386
-rwxr-xr-x 1 root root 8228756 Sep 14 18:05 iris-darwin-amd64 -rwxr-xr-x 1 root root 8755532 Nov 24 16:44 iris-darwin-10.6-amd64
-rwxr-xr-x 1 root root 9532568 Sep 14 18:05 iris-linux-386 -rwxr-xr-x 1 root root 7114176 Nov 24 16:45 iris-ios-5.0-arm
-rwxr-xr-x 1 root root 11776368 Sep 14 18:05 iris-linux-amd64 -rwxr-xr-x 1 root root 10135248 Nov 24 16:44 iris-linux-386
-rwxr-xr-x 1 root root 9408928 Sep 14 18:05 iris-linux-arm -rwxr-xr-x 1 root root 12598472 Nov 24 16:44 iris-linux-amd64
-rwxr-xr-x 1 root root 7131477 Sep 14 18:05 iris-windows-386.exe -rwxr-xr-x 1 root root 10040464 Nov 24 16:44 iris-linux-arm
-rwxr-xr-x 1 root root 8963900 Sep 14 18:05 iris-windows-amd64.exe -rwxr-xr-x 1 root root 7516368 Nov 24 16:44 iris-windows-4.0-386.exe
-rwxr-xr-x 1 root root 9549416 Nov 24 16:44 iris-windows-4.0-amd64.exe
If the path is not a canonical import path, but rather a local path (starts with 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 a dot `.` or a dash `/`), xgo will use the local GOPATH contents for the cross
@ -106,14 +108,16 @@ file prefix. This can be overridden with the `-out` flag.
... ...
$ ls -al $ ls -al
-rwxr-xr-x 1 root root 10899488 Sep 14 18:08 iris-v0.3.2-android-21-arm -rwxr-xr-x 1 root root 9995000 Nov 24 16:44 iris-v0.3.2-android-16-arm
-rwxr-xr-x 1 root root 6442188 Sep 14 18:08 iris-v0.3.2-darwin-386 -rwxr-xr-x 1 root root 6776500 Nov 24 16:44 iris-v0.3.2-darwin-10.6-386
-rwxr-xr-x 1 root root 8228756 Sep 14 18:08 iris-v0.3.2-darwin-amd64 -rwxr-xr-x 1 root root 8755532 Nov 24 16:44 iris-v0.3.2-darwin-10.6-amd64
-rwxr-xr-x 1 root root 9532568 Sep 14 18:08 iris-v0.3.2-linux-386 -rwxr-xr-x 1 root root 7114176 Nov 24 16:45 iris-v0.3.2-ios-5.0-arm
-rwxr-xr-x 1 root root 11776368 Sep 14 18:08 iris-v0.3.2-linux-amd64 -rwxr-xr-x 1 root root 10135248 Nov 24 16:44 iris-v0.3.2-linux-386
-rwxr-xr-x 1 root root 9408928 Sep 14 18:08 iris-v0.3.2-linux-arm -rwxr-xr-x 1 root root 12598472 Nov 24 16:44 iris-v0.3.2-linux-amd64
-rwxr-xr-x 1 root root 7131477 Sep 14 18:08 iris-v0.3.2-windows-386.exe -rwxr-xr-x 1 root root 10040464 Nov 24 16:44 iris-v0.3.2-linux-arm
-rwxr-xr-x 1 root root 8963900 Sep 14 18:08 iris-v0.3.2-windows-amd64.exe -rwxr-xr-x 1 root root 7516368 Nov 24 16:44 iris-v0.3.2-windows-4.0-386.exe
-rwxr-xr-x 1 root root 9549416 Nov 24 16:44 iris-v0.3.2-windows-4.0-amd64.exe
### Branch selection ### Branch selection
@ -125,14 +129,16 @@ the desired branch name through the `--branch` argument.
... ...
$ ls -al $ ls -al
-rwxr-xr-x 1 root root 4928992 Sep 14 18:10 goimports-android-21-arm -rwxr-xr-x 1 root root 4171248 Nov 24 16:40 goimports-android-16-arm
-rwxr-xr-x 1 root root 4139868 Sep 14 18:10 goimports-darwin-386 -rwxr-xr-x 1 root root 4139868 Nov 24 16:40 goimports-darwin-10.6-386
-rwxr-xr-x 1 root root 5186720 Sep 14 18:10 goimports-darwin-amd64 -rwxr-xr-x 1 root root 5186720 Nov 24 16:40 goimports-darwin-10.6-amd64
-rwxr-xr-x 1 root root 4189448 Sep 14 18:10 goimports-linux-386 -rwxr-xr-x 1 root root 3202364 Nov 24 16:40 goimports-ios-5.0-arm
-rwxr-xr-x 1 root root 5264120 Sep 14 18:10 goimports-linux-amd64 -rwxr-xr-x 1 root root 4189456 Nov 24 16:40 goimports-linux-386
-rwxr-xr-x 1 root root 4209400 Sep 14 18:10 goimports-linux-arm -rwxr-xr-x 1 root root 5264136 Nov 24 16:40 goimports-linux-amd64
-rwxr-xr-x 1 root root 4348416 Sep 14 18:10 goimports-windows-386.exe -rwxr-xr-x 1 root root 4209416 Nov 24 16:40 goimports-linux-arm
-rwxr-xr-x 1 root root 5415424 Sep 14 18:10 goimports-windows-amd64.exe -rwxr-xr-x 1 root root 4348416 Nov 24 16:40 goimports-windows-4.0-386.exe
-rwxr-xr-x 1 root root 5415424 Nov 24 16:40 goimports-windows-4.0-amd64.exe
### Remote selection ### Remote selection
@ -156,14 +162,15 @@ parameter to select the exact package within, honoring any prior *branch* and
... ...
$ ls -al $ ls -al
-rwxr-xr-x 1 root root 4924036 Sep 14 18:09 goimports-android-21-arm -rwxr-xr-x 1 root root 4194956 Nov 24 16:38 goimports-android-16-arm
-rwxr-xr-x 1 root root 4135776 Sep 14 18:09 goimports-darwin-386 -rwxr-xr-x 1 root root 4164448 Nov 24 16:38 goimports-darwin-10.6-386
-rwxr-xr-x 1 root root 5182624 Sep 14 18:09 goimports-darwin-amd64 -rwxr-xr-x 1 root root 5223584 Nov 24 16:38 goimports-darwin-10.6-amd64
-rwxr-xr-x 1 root root 4184416 Sep 14 18:09 goimports-linux-386 -rwxr-xr-x 1 root root 3222848 Nov 24 16:39 goimports-ios-5.0-arm
-rwxr-xr-x 1 root root 5254800 Sep 14 18:09 goimports-linux-amd64 -rwxr-xr-x 1 root root 4217184 Nov 24 16:38 goimports-linux-386
-rwxr-xr-x 1 root root 4204440 Sep 14 18:09 goimports-linux-arm -rwxr-xr-x 1 root root 5295768 Nov 24 16:38 goimports-linux-amd64
-rwxr-xr-x 1 root root 4343296 Sep 14 18:09 goimports-windows-386.exe -rwxr-xr-x 1 root root 4233120 Nov 24 16:38 goimports-linux-arm
-rwxr-xr-x 1 root root 5409280 Sep 14 18:09 goimports-windows-amd64.exe -rwxr-xr-x 1 root root 4373504 Nov 24 16:38 goimports-windows-4.0-386.exe
-rwxr-xr-x 1 root root 5450240 Nov 24 16:38 goimports-windows-4.0-amd64.exe
This argument may at some point be integrated into the import path itself, but for This argument may at some point be integrated into the import path itself, but for
now it exists as an independent build parameter. Also, there is not possibility now it exists as an independent build parameter. Also, there is not possibility
@ -189,6 +196,7 @@ versions of the same operating system. This however can lead to issues if a used
dependency is only supported by more recent systems. As such, `xgo` supports the dependency is only supported by more recent systems. As such, `xgo` supports the
selection of specific platform versions by appending them to the OS target string. selection of specific platform versions by appending them to the OS target string.
* `--targets=ios-8.1/*`: cross compile to iOS 8.1
* `--targets=android-16/*`: cross compile to Android Jelly Bean * `--targets=android-16/*`: cross compile to Android Jelly Bean
* `--targets=darwin-10.9/*`: cross compile to Mac OS X Mavericks * `--targets=darwin-10.9/*`: cross compile to Mac OS X Mavericks
* `--targets=windows-6.0/*`: cross compile to Windows Vista * `--targets=windows-6.0/*`: cross compile to Windows Vista
@ -198,6 +206,7 @@ The supported platforms are:
* All Android APIs up to Android Lollipop 5.0 ([API level ids](https://source.android.com/source/build-numbers.html)) * All Android APIs up to Android Lollipop 5.0 ([API level ids](https://source.android.com/source/build-numbers.html))
* All Windows APIs up to Windows 8.1 limited by `mingw-w64` ([API level ids](https://en.wikipedia.org/wiki/Windows_NT#Releases)) * All Windows APIs up to Windows 8.1 limited by `mingw-w64` ([API level ids](https://en.wikipedia.org/wiki/Windows_NT#Releases))
* OSX APIs in the range of 10.6 - 10.9 * OSX APIs in the range of 10.6 - 10.9
* All iOS APIs up to ios 8.1
### CGO dependencies ### CGO dependencies
@ -218,19 +227,24 @@ on subsequent calls.
A complex sample for such a scenario is building the Ethereum CLI node, which has A complex sample for such a scenario is building the Ethereum CLI node, which has
the GNU Multiple Precision Arithmetic Library as it's dependency. the GNU Multiple Precision Arithmetic Library as it's dependency.
$ xgo --deps=https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2 \ $ xgo --deps=https://gmplib.org/download/gmp/gmp-6.1.0.tar.bz2 \
--branch=develop github.com/ethereum/go-ethereum/cmd/geth --targets=windows/* github.com/ethereum/go-ethereum/cmd/geth
... ...
$ ls -al $ ls -al
-rwxr-xr-x 1 root root 23213372 Sep 14 17:59 geth-android-21-arm -rwxr-xr-x 1 root root 16315679 Nov 24 16:39 geth-windows-4.0-386.exe
-rwxr-xr-x 1 root root 14373980 Sep 14 17:59 geth-darwin-386 -rwxr-xr-x 1 root root 19452036 Nov 24 16:38 geth-windows-4.0-amd64.exe
-rwxr-xr-x 1 root root 17373676 Sep 14 17:59 geth-darwin-amd64
-rwxr-xr-x 1 root root 21098910 Sep 14 17:59 geth-linux-386 Some trivial arguments may be passed to the dependencies' configure script via
-rwxr-xr-x 1 root root 25049693 Sep 14 17:59 geth-linux-amd64 `--depsargs`.
-rwxr-xr-x 1 root root 20578535 Sep 14 17:59 geth-linux-arm
-rwxr-xr-x 1 root root 16351260 Sep 14 17:59 geth-windows-386.exe $ xgo --deps=https://gmplib.org/download/gmp/gmp-6.1.0.tar.bz2 \
-rwxr-xr-x 1 root root 19418071 Sep 14 17:59 geth-windows-amd64.exe --targets=ios/* --depsargs=--disable-assembly \
github.com/ethereum/go-ethereum/cmd/geth
...
$ ls -al
-rwxr-xr-x 1 root root 14804160 Nov 24 16:32 geth-ios-5.0-arm
Note, that since xgo needs to cross compile the dependencies for each platform Note, that since xgo needs to cross compile the dependencies for each platform
and architecture separately, build time can increase significantly. and architecture separately, build time can increase significantly.

View File

@ -63,6 +63,17 @@ RUN \
ENV PATH /usr/$ANDROID_CHAIN_ARM/bin:$PATH ENV PATH /usr/$ANDROID_CHAIN_ARM/bin:$PATH
# Configure the container for iOS cross compilation
ENV IOS_SDK iPhoneOS8.1.sdk.tar.bz2
ENV IOS_SDK_PATH http://iphone.howett.net/sdks/dl/iPhoneOS8.1.sdk.tbz2
RUN \
$FETCH $IOS_SDK_PATH 41203ed17a29743323cce0dd10b238efcea406e1 && \
mv `basename $IOS_SDK_PATH` $IOS_SDK && \
git clone https://github.com/tpoechtrager/cctools-port.git && \
/cctools-port/usage_examples/ios_toolchain/build.sh /$IOS_SDK armv7
ENV PATH /cctools-port/usage_examples/ios_toolchain/target/bin:$PATH
# Inject the old Go package downloader and tool-chain bootstrapper # Inject the old Go package downloader and tool-chain bootstrapper
ADD bootstrap.sh /bootstrap.sh ADD bootstrap.sh /bootstrap.sh
ENV BOOTSTRAP /bootstrap.sh ENV BOOTSTRAP /bootstrap.sh

View File

@ -10,6 +10,7 @@
# REPO_REMOTE - Optional VCS remote if not the primary repository is needed # REPO_REMOTE - Optional VCS remote if not the primary repository is needed
# REPO_BRANCH - Optional VCS branch to use, if not the master branch # REPO_BRANCH - Optional VCS branch to use, if not the master branch
# DEPS - Optional list of C dependency packages to build # DEPS - Optional list of C dependency packages to build
# ARGS - Optional arguments to pass to C dependency configure scripts
# PACK - Optional sub-package, if not the import path is being built # PACK - Optional sub-package, if not the import path is being built
# OUT - Optional output prefix to override the package name # OUT - Optional output prefix to override the package name
# FLAG_V - Optional verbosity flag to set on the Go builder # FLAG_V - Optional verbosity flag to set on the Go builder
@ -91,6 +92,8 @@ DEPS=($DEPS) && for dep in "${DEPS[@]}"; do
if [ "${dep##*.}" == "bz2" ]; then cat "/deps-cache/`basename $dep`" | tar -C /deps -xj; fi if [ "${dep##*.}" == "bz2" ]; then cat "/deps-cache/`basename $dep`" | tar -C /deps -xj; fi
done done
DEPS_ARGS=($ARGS)
# Configure some global build parameters # Configure some global build parameters
NAME=`basename $1/$PACK` NAME=`basename $1/$PACK`
if [ "$OUT" != "" ]; then if [ "$OUT" != "" ]; then
@ -140,10 +143,13 @@ 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 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..." 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/arm-linux-androideabi $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 ${DEPS_ARGS[@]}
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="$V $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 get $V $X "${T[@]}" --ldflags="$V $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="$V $EXT_LDPIE $LD" -o /build/$NAME-android-$PLATFORM-arm ./$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="$V $EXT_LDPIE $LD" -o /build/$NAME-android-$PLATFORM-arm ./$PACK
echo "Cleaning up Go runtime for android-$PLATFORM/arm..."
rm -rf /usr/local/go/pkg/android_arm
echo "Cleaning up toolchain for android-$PLATFORM/arm..." echo "Cleaning up toolchain for android-$PLATFORM/arm..."
rm -rf /usr/$ANDROID_CHAIN_ARM rm -rf /usr/$ANDROID_CHAIN_ARM
fi fi
@ -152,19 +158,19 @@ for TARGET in $TARGETS; do
# Check and build for Linux targets # Check and build for Linux targets
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ]); then if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ]); then
echo "Compiling for linux/amd64..." echo "Compiling for linux/amd64..."
HOST=x86_64-linux PREFIX=/usr/local $BUILD_DEPS /deps HOST=x86_64-linux PREFIX=/usr/local $BUILD_DEPS /deps ${DEPS_ARGS[@]}
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$V $LD" $R -o /build/$NAME-linux-amd64$R ./$PACK GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$V $LD" $R -o /build/$NAME-linux-amd64$R ./$PACK
fi fi
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "386" ]); then if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "386" ]); then
echo "Compiling for linux/386..." echo "Compiling for linux/386..."
HOST=i686-linux PREFIX=/usr/local $BUILD_DEPS /deps HOST=i686-linux PREFIX=/usr/local $BUILD_DEPS /deps ${DEPS_ARGS[@]}
GOOS=linux GOARCH=386 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK GOOS=linux GOARCH=386 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$V $LD" -d ./$PACK
GOOS=linux GOARCH=386 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$V $LD" -o /build/$NAME-linux-386 ./$PACK GOOS=linux GOARCH=386 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$V $LD" -o /build/$NAME-linux-386 ./$PACK
fi fi
if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "arm" ]); then if ([ $XGOOS == "." ] || [ $XGOOS == "linux" ]) && ([ $XGOARCH == "." ] || [ $XGOARCH == "arm" ]); then
echo "Compiling for linux/arm..." echo "Compiling for linux/arm..."
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 HOST=arm-linux PREFIX=/usr/local/arm $BUILD_DEPS /deps ${DEPS_ARGS[@]}
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="$V $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 get $V $X "${T[@]}" --ldflags="$V $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="$V $LD" -o /build/$NAME-linux-arm ./$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="$V $LD" -o /build/$NAME-linux-arm ./$PACK
fi fi
@ -185,13 +191,13 @@ for TARGET in $TARGETS; do
# Build the requested windows binaries # Build the requested windows binaries
if [ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ]; then if [ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ]; then
echo "Compiling for windows-$PLATFORM/amd64..." echo "Compiling for windows-$PLATFORM/amd64..."
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 HOST=x86_64-w64-mingw32 PREFIX=/usr/x86_64-w64-mingw32 $BUILD_DEPS /deps ${DEPS_ARGS[@]}
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="$V $LD" -d ./$PACK 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="$V $LD" -d ./$PACK
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="$V $LD" $R -o /build/$NAME-windows-$PLATFORM-amd64$R.exe ./$PACK 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="$V $LD" $R -o /build/$NAME-windows-$PLATFORM-amd64$R.exe ./$PACK
fi fi
if [ $XGOARCH == "." ] || [ $XGOARCH == "386" ]; then if [ $XGOARCH == "." ] || [ $XGOARCH == "386" ]; then
echo "Compiling for windows-$PLATFORM/386..." echo "Compiling for windows-$PLATFORM/386..."
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 HOST=i686-w64-mingw32 PREFIX=/usr/i686-w64-mingw32 $BUILD_DEPS /deps ${DEPS_ARGS[@]}
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="$V $LD" -d ./$PACK 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="$V $LD" -d ./$PACK
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="$V $LD" -o /build/$NAME-windows-$PLATFORM-386.exe ./$PACK 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="$V $LD" -o /build/$NAME-windows-$PLATFORM-386.exe ./$PACK
fi fi
@ -213,17 +219,47 @@ for TARGET in $TARGETS; do
# Build the requested darwin binaries # Build the requested darwin binaries
if [ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ]; then if [ $XGOARCH == "." ] || [ $XGOARCH == "amd64" ]; then
echo "Compiling for darwin-$PLATFORM/amd64..." echo "Compiling for darwin-$PLATFORM/amd64..."
CC=o64-clang CXX=o64-clang++ HOST=x86_64-apple-darwin13 PREFIX=/usr/local $BUILD_DEPS /deps CC=o64-clang CXX=o64-clang++ HOST=x86_64-apple-darwin13 PREFIX=/usr/local $BUILD_DEPS /deps ${DEPS_ARGS[@]}
CC=o64-clang CXX=o64-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" -d ./$PACK CC=o64-clang CXX=o64-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" -d ./$PACK
CC=o64-clang CXX=o64-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" $R -o /build/$NAME-darwin-$PLATFORM-amd64$R ./$PACK CC=o64-clang CXX=o64-clang++ GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" $R -o /build/$NAME-darwin-$PLATFORM-amd64$R ./$PACK
fi fi
if [ $XGOARCH == "." ] || [ $XGOARCH == "386" ]; then if [ $XGOARCH == "." ] || [ $XGOARCH == "386" ]; then
echo "Compiling for darwin-$PLATFORM/386..." echo "Compiling for darwin-$PLATFORM/386..."
CC=o32-clang CXX=o32-clang++ HOST=i386-apple-darwin13 PREFIX=/usr/local $BUILD_DEPS /deps CC=o32-clang CXX=o32-clang++ HOST=i386-apple-darwin13 PREFIX=/usr/local $BUILD_DEPS /deps ${DEPS_ARGS[@]}
CC=o32-clang CXX=o32-clang++ GOOS=darwin GOARCH=386 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" -d ./$PACK CC=o32-clang CXX=o32-clang++ GOOS=darwin GOARCH=386 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" -d ./$PACK
CC=o32-clang CXX=o32-clang++ GOOS=darwin GOARCH=386 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" -o /build/$NAME-darwin-$PLATFORM-386 ./$PACK CC=o32-clang CXX=o32-clang++ GOOS=darwin GOARCH=386 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" -o /build/$NAME-darwin-$PLATFORM-386 ./$PACK
fi fi
# Remove any automatically injected deployment target vars # Remove any automatically injected deployment target vars
unset MACOSX_DEPLOYMENT_TARGET unset MACOSX_DEPLOYMENT_TARGET
fi fi
# Check and build for iOS targets
if [ $XGOOS == "." ] || [[ $XGOOS == ios* ]]; then
# Split the platform version and configure the deployment target
PLATFORM=`echo $XGOOS | cut -d '-' -f 2`
if [ "$PLATFORM" == "" ] || [ "$PLATFORM" == "." ] || [ "$PLATFORM" == "ios" ]; then
PLATFORM=5.0 # first iPad and upwards
fi
export IPHONEOS_DEPLOYMENT_TARGET=$PLATFORM
# Strip symbol table below Go 1.6 to prevent DWARF issues
LDSTRIP=""
if [ "$GO_VERSION" -lt 160 ]; then
LDSTRIP="-s"
fi
# Build the requested darwin binaries
if [ $XGOARCH == "." ] || [ $XGOARCH == "arm" ]; then
echo "Bootstrapping ios-$PLATFORM/arm..."
GOOS=darwin GOARCH=arm GOARM=7 CGO_ENABLED=1 CC=arm-apple-darwin11-clang go install std
echo "Compiling for ios-$PLATFORM/arm..."
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ HOST=arm-apple-darwin11 PREFIX=/usr/local $BUILD_DEPS /deps ${DEPS_ARGS[@]}
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ GOOS=darwin GOARCH=arm GOARM=7 CGO_ENABLED=1 go get $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" -d ./$PACK
CC=arm-apple-darwin11-clang CXX=arm-apple-darwin11-clang++ GOOS=darwin GOARCH=arm GOARM=7 CGO_ENABLED=1 go build $V $X "${T[@]}" --ldflags="$LDSTRIP $V $LD" -o /build/$NAME-ios-$PLATFORM-arm ./$PACK
echo "Cleaning up Go runtime for ios-$PLATFORM/arm..."
rm -rf /usr/local/go/pkg/darwin_arm
fi
# Remove any automatically injected deployment target vars
unset IPHONEOS_DEPLOYMENT_TARGET
fi
done done

View File

@ -3,7 +3,7 @@
# Contains the a dependency builder to iterate over all installed dependencies # Contains the a dependency builder to iterate over all installed dependencies
# and cross compile them to the requested target platform. # and cross compile them to the requested target platform.
# #
# Usage: build_deps.sh <dependency folder> # Usage: build_deps.sh <dependency folder> <configure arguments>
# #
# Needed environment variables: # Needed environment variables:
# CC - C cross compiler to use for the build # CC - C cross compiler to use for the build
@ -17,7 +17,7 @@ rm -rf /deps-build && cp -r $1 /deps-build
# Build all the dependencies (no order for now) # Build all the dependencies (no order for now)
for dep in `ls /deps-build`; do for dep in `ls /deps-build`; do
echo "Configuring dependency $dep for $HOST..." echo "Configuring dependency $dep for $HOST..."
(cd /deps-build/$dep && ./configure --disable-shared --host=$HOST --prefix=$PREFIX --silent) (cd /deps-build/$dep && ./configure --disable-shared --host=$HOST --prefix=$PREFIX --silent ${@:2})
echo "Building dependency $dep for $HOST..." echo "Building dependency $dep for $HOST..."
(cd /deps-build/$dep && make --silent -j install) (cd /deps-build/$dep && make --silent -j install)

56
xgo.go
View File

@ -31,16 +31,29 @@ var dockerDist = "karalabe/xgo-"
// Command line arguments to fine tune the compilation // Command line arguments to fine tune the compilation
var ( var (
goVersion = flag.String("go", "latest", "Go release to use for cross compilation") goVersion = flag.String("go", "latest", "Go release to use for cross compilation")
inPackage = flag.String("pkg", "", "Sub-package to build if not root import") srcPackage = flag.String("pkg", "", "Sub-package to build if not root import")
outPrefix = flag.String("out", "", "Prefix to use for output naming (empty = package name)")
outFolder = flag.String("dest", "", "Destination folder to put binaries in (empty = current)")
srcRemote = flag.String("remote", "", "Version control remote repository to build") srcRemote = flag.String("remote", "", "Version control remote repository to build")
srcBranch = flag.String("branch", "", "Version control branch to build") srcBranch = flag.String("branch", "", "Version control branch to build")
outPrefix = flag.String("out", "", "Prefix to use for output naming (empty = package name)")
outFolder = flag.String("dest", "", "Destination folder to put binaries in (empty = current)")
crossDeps = flag.String("deps", "", "CGO dependencies (configure/make based archives)") crossDeps = flag.String("deps", "", "CGO dependencies (configure/make based archives)")
crossArgs = flag.String("depsargs", "", "CGO dependency configure arguments")
targets = flag.String("targets", "*/*", "Comma separated targets to build for") targets = flag.String("targets", "*/*", "Comma separated targets to build for")
dockerImage = flag.String("image", "", "Use custom docker image instead of official distribution") dockerImage = flag.String("image", "", "Use custom docker image instead of official distribution")
) )
// ConfigFlags is a simple set of flags to define the environment and dependencies.
type ConfigFlags struct {
Repository string // Root import path to build
Package string // Sub-package to build if not root import
Prefix string // Prefix to use for output naming
Remote string // Version control remote repository to build
Branch string // Version control branch to build
Dependencies string // CGO dependencies (configure/make based archives)
Arguments string // CGO dependency configure arguments
Targets []string // Targets to build for
}
// Command line arguments to pass to go build // Command line arguments to pass to go build
var ( var (
buildVerbose = flag.Bool("v", false, "Print the names of packages as they are compiled") buildVerbose = flag.Bool("v", false, "Print the names of packages as they are compiled")
@ -124,6 +137,16 @@ func main() {
} }
} }
// Cross compile the requested package into the local folder // Cross compile the requested package into the local folder
config := &ConfigFlags{
Repository: flag.Args()[0],
Package: *srcPackage,
Remote: *srcRemote,
Branch: *srcBranch,
Prefix: *outPrefix,
Dependencies: *crossDeps,
Arguments: *crossArgs,
Targets: strings.Split(*targets, ","),
}
flags := &BuildFlags{ flags := &BuildFlags{
Verbose: *buildVerbose, Verbose: *buildVerbose,
Steps: *buildSteps, Steps: *buildSteps,
@ -131,7 +154,7 @@ func main() {
Tags: *buildTags, Tags: *buildTags,
LdFlags: *buildLdFlags, LdFlags: *buildLdFlags,
} }
if err := compile(flag.Args()[0], image, *srcRemote, *srcBranch, *inPackage, *crossDeps, *outFolder, *outPrefix, flags, strings.Split(*targets, ",")); err != nil { if err := compile(image, config, flags, *outFolder); err != nil {
log.Fatalf("Failed to cross compile package: %v.", err) log.Fatalf("Failed to cross compile package: %v.", err)
} }
} }
@ -163,7 +186,7 @@ func pullDockerImage(image string) error {
} }
// Cross compiles a requested package into the current working directory. // Cross compiles a requested package into the current working directory.
func compile(repo string, image string, remote string, branch string, pack string, deps string, dest string, prefix string, flags *BuildFlags, targets []string) error { func compile(image string, config *ConfigFlags, flags *BuildFlags, dest string) error {
// Retrieve the current folder to store the binaries in // Retrieve the current folder to store the binaries in
folder, err := os.Getwd() folder, err := os.Getwd()
if err != nil { if err != nil {
@ -177,9 +200,9 @@ func compile(repo string, image string, remote string, branch string, pack strin
} }
// If a local build was requested, find the import path and mount all GOPATH sources // If a local build was requested, find the import path and mount all GOPATH sources
locals, mounts, paths := []string{}, []string{}, []string{} locals, mounts, paths := []string{}, []string{}, []string{}
if strings.HasPrefix(repo, string(filepath.Separator)) || strings.HasPrefix(repo, ".") { if strings.HasPrefix(config.Repository, string(filepath.Separator)) || strings.HasPrefix(config.Repository, ".") {
// Resolve the repository import path from the file path // Resolve the repository import path from the file path
path, err := filepath.Abs(repo) path, err := filepath.Abs(config.Repository)
if err != nil { if err != nil {
log.Fatalf("Failed to locate requested package: %v.", err) log.Fatalf("Failed to locate requested package: %v.", err)
} }
@ -191,7 +214,7 @@ func compile(repo string, image string, remote string, branch string, pack strin
if err != nil { if err != nil {
log.Fatalf("Failed to resolve import path: %v.", err) log.Fatalf("Failed to resolve import path: %v.", err)
} }
repo = pack.ImportPath config.Repository = pack.ImportPath
// Iterate over all the local libs and export the mount points // Iterate over all the local libs and export the mount points
if os.Getenv("GOPATH") == "" { if os.Getenv("GOPATH") == "" {
@ -235,30 +258,31 @@ func compile(repo string, image string, remote string, branch string, pack strin
} }
} }
// Assemble and run the cross compilation command // Assemble and run the cross compilation command
fmt.Printf("Cross compiling %s...\n", repo) fmt.Printf("Cross compiling %s...\n", config.Repository)
args := []string{ args := []string{
"run", "--rm", "run", "--rm",
"-v", folder + ":/build", "-v", folder + ":/build",
"-v", depsCache + ":/deps-cache:ro", "-v", depsCache + ":/deps-cache:ro",
"-e", "REPO_REMOTE=" + remote, "-e", "REPO_REMOTE=" + config.Remote,
"-e", "REPO_BRANCH=" + branch, "-e", "REPO_BRANCH=" + config.Branch,
"-e", "PACK=" + pack, "-e", "PACK=" + config.Package,
"-e", "DEPS=" + deps, "-e", "DEPS=" + config.Dependencies,
"-e", "OUT=" + prefix, "-e", "ARGS=" + config.Arguments,
"-e", "OUT=" + config.Prefix,
"-e", fmt.Sprintf("FLAG_V=%v", flags.Verbose), "-e", fmt.Sprintf("FLAG_V=%v", flags.Verbose),
"-e", fmt.Sprintf("FLAG_X=%v", flags.Steps), "-e", fmt.Sprintf("FLAG_X=%v", flags.Steps),
"-e", fmt.Sprintf("FLAG_RACE=%v", flags.Race), "-e", fmt.Sprintf("FLAG_RACE=%v", flags.Race),
"-e", fmt.Sprintf("FLAG_TAGS=%s", flags.Tags), "-e", fmt.Sprintf("FLAG_TAGS=%s", flags.Tags),
"-e", fmt.Sprintf("FLAG_LDFLAGS=%s", flags.LdFlags), "-e", fmt.Sprintf("FLAG_LDFLAGS=%s", flags.LdFlags),
"-e", "TARGETS=" + strings.Replace(strings.Join(targets, " "), "*", ".", -1), "-e", "TARGETS=" + strings.Replace(strings.Join(config.Targets, " "), "*", ".", -1),
} }
for i := 0; i < len(locals); i++ { 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{"-v", fmt.Sprintf("%s:%s:ro", locals[i], mounts[i])}...)
} }
args = append(args, []string{"-e", "EXT_GOPATH=" + strings.Join(paths, ":")}...) args = append(args, []string{"-e", "EXT_GOPATH=" + strings.Join(paths, ":")}...)
args = append(args, []string{image, repo}...) args = append(args, []string{image, config.Repository}...)
return run(exec.Command("docker", args...)) return run(exec.Command("docker", args...))
} }