213 lines
4.6 KiB
C
213 lines
4.6 KiB
C
|
/*
|
||
|
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;
|
||
|
}
|