diff options
author | Edgar Aroutiounian <edgar.factorial@gmail.com> | 2016-02-16 08:09:53 +0000 |
---|---|---|
committer | Edgar Aroutiounian <edgar.factorial@gmail.com> | 2016-02-22 11:16:11 -0800 |
commit | 058c768892e5b7687528f612040e6e850642de4b (patch) | |
tree | 29477f4407917c313db6f1d8a7d9835e250bd27d /pkgs/development/compilers/ios-cross-compile | |
parent | 06424612e680cfd526f9d515aaa58586c255a2c2 (diff) |
ios-cross-compile: init at 9.2
Diffstat (limited to 'pkgs/development/compilers/ios-cross-compile')
3 files changed, 429 insertions, 0 deletions
diff --git a/pkgs/development/compilers/ios-cross-compile/9.2.nix b/pkgs/development/compilers/ios-cross-compile/9.2.nix new file mode 100644 index 0000000000000..5ec24e01617af --- /dev/null +++ b/pkgs/development/compilers/ios-cross-compile/9.2.nix @@ -0,0 +1,64 @@ +{ stdenv, git, clang, + fetchFromGitHub, requireFile, + openssl, xz, gnutar, gcc, + automake, autoconf, libtool, clangStdenv } : + +clangStdenv.mkDerivation rec { + name = "ios-cross-compile-${version}"; + version = "9.2"; + sdk = "iPhoneOS9.2.sdk"; + cctools_port = fetchFromGitHub { + owner = "tpoechtrager"; + repo = "cctools-port"; + rev = "7d405492b09fa27546caaa989b8493829365deab"; + sha256 = "0nj1q5bqdx5jm68dispybxc7wnkb6p8p2igpnap9q6qyv2r9p07w"; + }; + ldid = fetchFromGitHub { + owner = "tpoechtrager"; + repo = "ldid"; + rev = "3064ed628108da4b9a52cfbe5d4c1a5817811400"; + sha256 = "1a6zaz8fgbi239l5zqx9xi3hsrv3jmfh8dkiy5gmnjs6v4gcf6sf"; + }; + src = requireFile rec { + name = "iPhoneOS9.2.sdk.tar.xz"; + sha256 = "1l2h3cic9psrq3nmfv9aaxkdk8y2pvr0iq6apj87mb3ms9a4cqrq"; + message = '' + You need to do the following steps to get a prepared + ios tarball. + + 1) Download an XCode dmg, specifically XCode_7.2.dmg + 2) Install darling-dmg, available via: nix-env -i darling-dmg + 3) Follow this shell history: + + $ cd ~/ + $ mkdir xcode + $ darling-dmg Xcode_7.2dmg xcode + $ cd xcode/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs + $ mktemp -d + /tmp/gar/tmp.4ZZ8kqyfqp/ + $ mkdir /tmp/gar/tmp.4ZZ8kqyfqp/iPhoneOS9.2.sdk + $ cp -r iPhoneOS.sdk/* /tmp/gar/tmp.4ZZ8kqyfqp/iPhoneOS9.2.sdk + $ cp -r ../../../../Toolchains/XcodeDefault.xctoolchain/usr/include/c++/* \ + /tmp/gar/tmp.4ZZ8kqyfqp/iPhoneOS9.2.sdk/usr/include/c++ + $ tar -cf - * | xz -9 -c - > iPhoneOS9.2.sdk.tar.xz + $ cd ~/ + $ fusermount -u xcode + + Then do: + + nix-prefetch-url file:///path/to/${name} + + and run this installation again. + ''; + }; + buildInputs = [ git xz gnutar openssl automake autoconf libtool clang ]; + alt_wrapper = ./alt_wrapper.c; + builder = ./9.2_builder.sh; + meta = { + description = + "Provides an iOS cross compiler from 7.1 up to iOS-${version} and ldid"; + platforms = stdenv.lib.platforms.linux; + maintainers = with stdenv.lib.maintainers; [ fxfactorial ]; + license = stdenv.lib.licenses.gpl2; + }; +} diff --git a/pkgs/development/compilers/ios-cross-compile/9.2_builder.sh b/pkgs/development/compilers/ios-cross-compile/9.2_builder.sh new file mode 100644 index 0000000000000..4604b1fdea727 --- /dev/null +++ b/pkgs/development/compilers/ios-cross-compile/9.2_builder.sh @@ -0,0 +1,153 @@ +# -*- shell-script -*- +source $stdenv/setup + +function extract +{ + printf "extracting $(basename $1) ...\n" + local tarflags="xf" + + case "$1" in + *.tar.xz) + xz -dc $1 | tar "$tarflags" - ;; + *) + printf "Make sure you give a iPhoneOS9.2.sdk.tar.xz file \n" ;; + esac +} + +function verify_arch { + case "$1" in + # Our good arches. + armv7|arm64) ;; + *) + local + acc="armv7 | arm64" + error_message=$( + printf '%s is not an acceptable arch. Try one of %s' "$1" "$acc" + ) + printf "$error_message\n" + exit + esac +} + +function verify_sdk_version { + sdk_version=$(basename "$1" | grep -P -o "[0-9].[0-9]+") + case "$sdk_version" in + # Make sure the SDK is correct. + [5-9].[0-9]) ;; + *) + printf 'No iPhone SDK version in file name\n' + esac +} + +function do_build { + + if [ $# -lt 2 ]; then + printf "usage: $0 iPhoneOS.sdk.tar* <target cpu>\n" 1>&2 + printf "i.e. $0 /path/to/iPhoneOS.sdk.tar.xz armv7\n" 1>&2 + exit 1 + fi + + mkdir -p $out + + chmod -R 755 "$cctools_port" + + pushd "$cctools_port"/usage_examples/ios_toolchain &> /dev/null + + export LC_ALL=C + + local + triple='%s-apple-darwin11' + target_dir="$PWD/target" + sdk_dir="$target_dir/SDK" + platform="$(uname -s)" + # Will be mutated by verify_sdk_version + sdk_version= + + mkdir -p "$target_dir" + mkdir -p "$target_dir/bin" + mkdir -p "$sdk_dir" + + verify_arch "$2" + verify_sdk_version "$1" + + triple="$(printf "$triple" "$2")" + pushd "$sdk_dir" &>/dev/null + extract "$1" + + local sys_lib=$( + find $sdk_dir -name libSystem.dylib -o -name libSystem.tbd | head -n1 + ) + + if [ -z "$sys_lib" ]; then + printf "SDK should contain libSystem{.dylib,.tbd}\n" 1>&2 + exit 1 + fi + + local sys_root=$(readlink -f "$(dirname $sys_lib)/../..") + + local sdk_unboxed=$(basename $sys_root) + + mv -f "$sys_root"/* "$sdk_dir" || true + + popd &>/dev/null + + printf "\nbuilding wrapper\n" + + printf "int main(){return 0;}" | clang -xc -O2 -o "$target_dir"/bin/dsymutil - + + clang -O2 -std=c99 $alt_wrapper \ + -DTARGET_CPU=$(printf '"%s"' "$2") \ + -DNIX_APPLE_HDRS=$( + printf '"%s"' "-I$out/$sdk/usr/include" + ) \ + -DNIX_APPLE_FRAMEWORKS=$( + printf '"%s"' "$out/$sdk/System/Library/Frameworks" + ) \ + -DNIX_APPLE_PRIV_FRAMEWORKS=$( + printf '"%s"' "$out/$sdk/System/Library/PrivateFrameworks" + ) \ + -DOS_VER_MIN=$(printf '"%s"' "7.1") \ + -o "$target_dir/bin/$triple-clang" + + pushd "$target_dir"/bin &>/dev/null + + cp "$triple"-clang "$triple"-clang++ + + popd &>/dev/null + + printf "\nbuilding ldid\n" + + mkdir -p tmp + pushd tmp &>/dev/null + pushd "$ldid" &>/dev/null + + chmod -R 755 "$ldid" + + make INSTALLPREFIX="$target_dir" -j4 install + popd &>/dev/null + popd &>/dev/null + + printf "\nbuilding cctools / ld64\n" + + pushd ../../cctools &>/dev/null + git clean -fdx . &>/dev/null || true + ./autogen.sh + ./configure --target="$triple" --prefix="$target_dir" + make -j4 + make install &>/dev/null + + popd &>/dev/null + + local me=`whoami` + + for d in bin libexec SDK; do + chown -R $me:$me target/$d + cp -R target/$d $out + done + + # Crucial piece + rm -rf $out/$sdk + mv $out/SDK $out/$sdk +} + +do_build $src armv7 diff --git a/pkgs/development/compilers/ios-cross-compile/alt_wrapper.c b/pkgs/development/compilers/ios-cross-compile/alt_wrapper.c new file mode 100644 index 0000000000000..928b64e6fd9d5 --- /dev/null +++ b/pkgs/development/compilers/ios-cross-compile/alt_wrapper.c @@ -0,0 +1,212 @@ +/* + This and the shell builder was originally written by + https://github.com/tpoechtrager but I had to modify both so that + they played nicely and were reproducible with nixpkgs. Much thanks + to MixRank for letting me work on this. + Edgar Aroutiounian <edgar.factorial@gmail.com> + */ + +#ifndef TARGET_CPU +#define TARGET_CPU "armv7" +#endif + +#ifndef OS_VER_MIN +#define OS_VER_MIN "4.2" +#endif + +#ifndef NIX_APPLE_HDRS +#define NIX_APPLE_HDRS "" +#endif + +#ifndef NIX_APPLE_FRAMEWORKS +#define NIX_APPLE_FRAMEWORKS "" +#endif + +#ifndef NIX_APPLE_PRIV_FRAMEWORKS +#define NIX_APPLE_PRIV_FRAMEWORKS "" +#endif + +#define _GNU_SOURCE + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <stddef.h> +#include <unistd.h> +#include <limits.h> + +#ifdef __APPLE__ +#include <mach-o/dyld.h> +#endif + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#include <sys/sysctl.h> +#endif + +#ifdef __OpenBSD__ +#include <sys/types.h> +#include <sys/user.h> +#include <sys/stat.h> +#endif + +char *get_executable_path(char *epath, size_t buflen) +{ + char *p; +#ifdef __APPLE__ + unsigned int l = buflen; + if (_NSGetExecutablePath(epath, &l) != 0) return NULL; +#elif defined(__FreeBSD__) || defined(__DragonFly__) + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; + size_t l = buflen; + if (sysctl(mib, 4, epath, &l, NULL, 0) != 0) return NULL; +#elif defined(__OpenBSD__) + int mib[4]; + char **argv; + size_t len; + size_t l; + const char *comm; + int ok = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC_ARGS; + mib[2] = getpid(); + mib[3] = KERN_PROC_ARGV; + if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) + abort(); + if (!(argv = malloc(len))) + abort(); + if (sysctl(mib, 4, argv, &len, NULL, 0) < 0) + abort(); + comm = argv[0]; + if (*comm == '/' || *comm == '.') { + char *rpath; + if ((rpath = realpath(comm, NULL))) { + strlcpy(epath, rpath, buflen); + free(rpath); + ok = 1; + } + } else { + char *sp; + char *xpath = strdup(getenv("PATH")); + char *path = strtok_r(xpath, ":", &sp); + struct stat st; + if (!xpath) + abort(); + while (path) { + snprintf(epath, buflen, "%s/%s", path, comm); + if (!stat(epath, &st) && (st.st_mode & S_IXUSR)) { + ok = 1; + break; + } + path = strtok_r(NULL, ":", &sp); + } + free(xpath); + } + free(argv); + if (!ok) return NULL; + l = strlen(epath); +#else + ssize_t l = readlink("/proc/self/exe", epath, buflen); +#endif + if (l <= 0) return NULL; + epath[buflen - 1] = '\0'; + p = strrchr(epath, '/'); + if (p) *p = '\0'; + return epath; +} + +char *get_filename(char *str) +{ + char *p = strrchr(str, '/'); + return p ? &p[1] : str; +} + +void target_info(char *argv[], char **triple, char **compiler) +{ + char *p = get_filename(argv[0]); + char *x = strrchr(p, '-'); + if (!x) abort(); + *compiler = &x[1]; + *x = '\0'; + *triple = p; +} + +void env(char **p, const char *name, char *fallback) +{ + char *ev = getenv(name); + if (ev) { *p = ev; return; } + *p = fallback; +} + +int main(int argc, char *argv[]) +{ + char **args = alloca(sizeof(char*) * (argc + 17)); + int i, j; + + char execpath[PATH_MAX+1]; + char sdkpath[PATH_MAX+1]; + char codesign_allocate[64]; + char osvermin[64]; + + char *compiler, *target, *sdk, *cpu, *osmin; + + target_info(argv, &target, &compiler); + + if (!get_executable_path(execpath, sizeof(execpath))) abort(); + snprintf(sdkpath, sizeof(sdkpath), "%s/../SDK", execpath); + + snprintf(codesign_allocate, sizeof(codesign_allocate), + "%s-codesign_allocate", target); + + setenv("CODESIGN_ALLOCATE", codesign_allocate, 1); + setenv("IOS_FAKE_CODE_SIGN", "1", 1); + + env(&sdk, "IOS_SDK_SYSROOT", sdkpath); + env(&cpu, "IOS_TARGET_CPU", TARGET_CPU); + + env(&osmin, "IPHONEOS_DEPLOYMENT_TARGET", OS_VER_MIN); + unsetenv("IPHONEOS_DEPLOYMENT_TARGET"); + + snprintf(osvermin, sizeof(osvermin), "-miphoneos-version-min=%s", osmin); + + for (i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "-arch")) { + cpu = NULL; + break; + } + } + + i = 0; + + args[i++] = compiler; + args[i++] = "-target"; + args[i++] = target; + args[i++] = "-isysroot"; + args[i++] = sdk; + args[i++] = NIX_APPLE_HDRS; + args[i++] = "-F"; + args[i++] = NIX_APPLE_FRAMEWORKS; + args[i++] = "-F"; + args[i++] = NIX_APPLE_PRIV_FRAMEWORKS; + + if (cpu) { + args[i++] = "-arch"; + args[i++] = cpu; + } + + args[i++] = osvermin; + args[i++] = "-mlinker-version=253.3"; + + for (j = 1; j < argc; ++i, ++j) args[i] = argv[j]; + + args[i] = NULL; + + setenv("COMPILER_PATH", execpath, 1); + /* int k; */ + /* for (k = 0; k < i; k++) */ + /* printf("Compiler option: %s\n", args[k]); */ + /* printf("End of Compiler args\n"); */ + execvp(compiler, args); + + fprintf(stderr, "cannot invoke compiler, this is a serious bug\n"); + return 1; +} |