parent
06424612e6
commit
058c768892
@ -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; |
||||
}; |
||||
} |
@ -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 |
@ -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; |
||||
} |
Loading…
Reference in new issue