diff options
Diffstat (limited to 'nixpkgs/pkgs/development/compilers/ios-cross-compile/alt_wrapper.c')
-rw-r--r-- | nixpkgs/pkgs/development/compilers/ios-cross-compile/alt_wrapper.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/development/compilers/ios-cross-compile/alt_wrapper.c b/nixpkgs/pkgs/development/compilers/ios-cross-compile/alt_wrapper.c new file mode 100644 index 000000000000..928b64e6fd9d --- /dev/null +++ b/nixpkgs/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; +} |