From e7b643d9bd40bc0ca91a3315d1cebd2085da8ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20P=C3=B6chtrager?= Date: Sat, 27 Sep 2014 14:35:42 +0200 Subject: [PATCH] adjustments to allow extracting the sdk on linux (xcode 4.2 only) --- README.md | 38 ++++++++++++++----- tools/gen_sdk_package.sh | 76 +++++++++++++++++++++++++------------- tools/mount_xcode_image.sh | 68 ++++++++++++++++++++++++++++++++++ wrapper/target.cpp | 4 +- 4 files changed, 149 insertions(+), 37 deletions(-) create mode 100755 tools/mount_xcode_image.sh diff --git a/README.md b/README.md index 864f680..7fc0d02 100755 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Basically everything you can build on OS X with clang/gcc should build with this Move your packaged SDK to the tarballs/ directory. -Then ensure you have the following installed on your Linux/FreeBSD box: +Then ensure you have the following installed on your Linux/BSD box: `Clang 3.2+`, `llvm-devel`, `automake`, `autogen`, `libtool`, `patch`, `libxml2-devel` (<=10.5 only), `uuid-devel`, `openssl-devel` and the `bash shell`. @@ -51,15 +51,35 @@ to install them. ### PACKAGING THE SDK: ### -1. Boot into OS X -2. [Download [Xcode](https://developer.apple.com/downloads/index.action?name=Xcode) (used 5.1)] -3. [Mount Xcode.dmg (Open With -> DiskImageMounter)] -4. Run: ./tools/gen_sdk_package.sh (from the OSXCross package) -5. Copy the packaged SDK (\*.tar.\* or \*.pkg) on a USB Stick -6. Reboot back into Linux -7. Copy or move the SDK into the tarball/ directory of OSXCross +If you need a recent SDK, then you must do the SDK packaging on OS X. +Recent Xcode images are compressed, but the Linux kernel does not +support HFS+ compression. -Step 2. and 3. can be skipped if you have Xcode installed. +##### Packaging the SDK on an OS X machine: ##### + +1. [Download [Xcode](https://developer.apple.com/downloads/index.action?name=Xcode%205.1.1) \*\*] +2. [Mount Xcode.dmg (Open With -> DiskImageMounter) \*\*\*] +3. Run: ./tools/gen\_sdk\_package.sh (from the OSXCross package) +4. Copy the packaged SDK (\*.tar.\* or \*.pkg) on a USB Stick +5. (On Linux/BSD) Copy or move the SDK into the tarballs/ directory of OSXCross + +\*\* Xcode 4.6, 5.0+, 6.0, and the 6.1 Betas are known to work. +\*\*\* If you get a dialog with a crossed circle, ignore it, you don't need to install Xcode. + +Step 1. and 2. can be skipped if you have Xcode installed. + +##### Packing the SDK on a Linux machine (does *NOT* work with Xcode 4.3 or later!): ##### + +1. Download + [Xcode 4.2](https://startpage.com/do/search?q=stackoverflow+xcode+4.2+download+snow+leopard) + for Snow Leopard \*\* +2. Ensure you are downloading the "Snow Leopard" version +3. Install `dmg2img` +4. Run (as root): ./tools/mount\_xcode\_image.sh /path/to/xcode.dmg +5. Follow the instructions printed by ./tools/mount\_xcode\_image.sh +6. Copy or move the SDK into the tarballs/ directory + +\*\* SHA1 Sum: 1a06882638996dfbff65ea6b4c6625842903ead3. ### USAGE EXAMPLES: ### diff --git a/tools/gen_sdk_package.sh b/tools/gen_sdk_package.sh index a7c609c..c54157e 100755 --- a/tools/gen_sdk_package.sh +++ b/tools/gen_sdk_package.sh @@ -1,17 +1,21 @@ #!/usr/bin/env bash -# # OS X SDK packaging script -# This script must be run on OS X -# -if [ -z "$XCODEDIR" -a $(uname -s) != "Darwin" ]; then - echo "This script must be run on OS X" - exit 1 -elif [ -z "$XCODEDIR" ]; then - XCODEDIR=$(ls /Volumes | grep Xcode | head -n1) +export LC_ALL=C + +if [ $(uname -s) != "Darwin" ]; then + if [ -z "$XCODEDIR" ]; then + echo "This script must be run on OS X" + echo "... Or with XCODEDIR=... on Linux" + exit 1 + else + XCODEDIR+="/$(ls "$XCODEDIR" | grep "^Xcode.*" | head -n1)" + fi +else + XCODEDIR=$(ls /Volumes | grep "^Xcode.*" | head -n1) if [ -z "$XCODEDIR" ]; then - if [ -d "/Applications/Xcode.app" ]; then + if [ -d /Applications/Xcode*.app ]; then XCODEDIR="/Applications/Xcode*.app" else echo "please mount Xcode.dmg" @@ -22,7 +26,11 @@ elif [ -z "$XCODEDIR" ]; then fi fi -[ ! -d $XCODEDIR ] && exit 1 +if [ ! -d "$XCODEDIR" ]; then + echo "cannot find Xcode (XCODEDIR=$XCODEDIR)" + exit 1 +fi + echo -e "found Xcode: $XCODEDIR" WDIR=$(pwd) @@ -48,31 +56,45 @@ fi set -e pushd $XCODEDIR &>/dev/null -pushd "Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs" &>/dev/null || { - echo "Xcode (or this script) is out of date" - echo "trying some magic to find the SDKs anyway ..." - SDKDIR=$(find . -name SDKs -type d | grep MacOSX | head -n1) +if [ -d "Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs" ]; then + pushd "Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs" &>/dev/null +else + if [ -d "../Packages" ]; then + pushd "../Packages" &>/dev/null + else + if [ $? -ne 0 ]; then + echo "Xcode (or this script) is out of date" + echo "trying some magic to find the SDKs anyway ..." - if [ -z "$SDKDIR" ]; then - echo "cannot find SDKs!" - exit 1 + SDKDIR=$(find . -name SDKs -type d | grep MacOSX | head -n1) + + if [ -z "$SDKDIR" ]; then + echo "cannot find SDKs!" + exit 1 + fi + + pushd $SDKDIR &>/dev/null + fi fi +fi - pushd $SDKDIR &>/dev/null -} - -SDKS=$(ls | grep MacOSX) +SDKS=$(ls | grep "^MacOSX10.*" | grep -v "Patch") if [ -z "$SDKS" ]; then echo "No SDK found" exit 1 fi -LIBCXXDIR="Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1" +# Xcode 5 +LIBCXXDIR1="Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1" + +# Xcode 6 +LIBCXXDIR2="Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1" for SDK in $SDKS; do - echo "packaging ${SDK/.sdk/} SDK (this may take several minutes) ..." + echo -n "packaging $(echo "$SDK" | sed -E "s/(.sdk|.pkg)//g") SDK " + echo "(this may take several minutes) ..." if [[ $SDK == *.pkg ]]; then cp $SDK $WDIR @@ -85,8 +107,10 @@ for SDK in $SDKS; do pushd $XCODEDIR &>/dev/null # libc++ headers for C++11/C++14 - if [ -d $LIBCXXDIR ]; then - cp -rf $LIBCXXDIR "$TMP/$SDK/usr/include/c++" + if [ -d $LIBCXXDIR1 ]; then + cp -rf $LIBCXXDIR1 "$TMP/$SDK/usr/include/c++" + elif [ -d $LIBCXXDIR2 ]; then + cp -rf $LIBCXXDIR2 "$TMP/$SDK/usr/include/c++" fi popd &>/dev/null @@ -102,4 +126,4 @@ popd &>/dev/null popd &>/dev/null echo "" -ls -l | grep MacOSX +ls -lh | grep MacOSX diff --git a/tools/mount_xcode_image.sh b/tools/mount_xcode_image.sh new file mode 100755 index 0000000..f063070 --- /dev/null +++ b/tools/mount_xcode_image.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +if [ $(uname -s) != "Linux" ]; then + echo "This script must be run on Linux" + exit 1 +fi + +if [ "$EUID" -ne 0 ]; then + echo "This script must be run as root" + exit 1 +fi + +if [ $# -lt 1 ]; then + echo "usage: $0 /path/to/xcode.dmg" + exit 1 +fi + +case $1 in + /*) XCODEDMG="$1" ;; + *) XCODEDMG="$PWD/$1" ;; +esac + +if [ ! -e "$XCODEDMG" ]; then + echo "$1 does not exist" + exit 1 +fi + +pushd "${0%/*}/.." &>/dev/null +source tools/tools.sh +popd &>/dev/null + +require dmg2img +verbose_cmd "modprobe hfsplus" + +TMP=$(mktemp -d /tmp/XXXXXXXXX) +echo "tmp dir: $TMP" + +verbose_cmd "chmod 777 $TMP" + +pushd $TMP &>/dev/null + +PARTITION=$(dmg2img -l $XCODEDMG | grep 'disk image (Apple_HFS ' | \ + awk '{printf "%d", $2}') + +case $PARTITION in + ''|*[!0-9]*) + echo "$XCODEDMG: cannot determine HFS partition" + exit 1 ;; +esac + +echo "HFS partition: $PARTITION" + +verbose_cmd "dmg2img -p $PARTITION -i $XCODEDMG -o xcode.img &>dmg2img.log" +verbose_cmd "mkdir -m 777 mnt" +verbose_cmd "cd mnt" +verbose_cmd "mount -o loop -t hfsplus ../xcode.img $TMP/mnt" + +echo "" +echo "mounted the xcode image to: $TMP/mnt" +echo "" +echo "now run (not as root):" +echo "XCODEDIR=$TMP/mnt ./tools/gen_sdk_package.sh" +echo "" +echo "once you are done with gen_sdk_package.sh, run:" +echo "umount -l $TMP/mnt && rm -rf $TMP" +echo "" + +popd &>/dev/null diff --git a/wrapper/target.cpp b/wrapper/target.cpp index d70d507..dc3fc94 100644 --- a/wrapper/target.cpp +++ b/wrapper/target.cpp @@ -383,8 +383,8 @@ bool Target::setup() { if (haveArch(Arch::x86_64h)) { OSNum = OSVersion(10, 9); // Default to 10.9 for x86_64h if (SDKOSNum < OSNum) { - std::cerr << getArchName(arch) << "requires the SDK from " - << OSNum.Str() << " (or later)"; + std::cerr << getArchName(arch) << " requires the SDK from " + << OSNum.Str() << " (or later)" << std::endl; return false; } } else if (stdlib == StdLib::libcxx) {