at master 4.7 kB view raw
1/* 2 This and the shell builder was originally written by 3 https://github.com/tpoechtrager but I had to modify both so that 4 they played nicely and were reproducible with nixpkgs. Much thanks 5 to MixRank for letting me work on this. 6 Edgar Aroutiounian <edgar.factorial@gmail.com> 7 */ 8 9#ifndef TARGET_CPU 10#define TARGET_CPU "armv7" 11#endif 12 13#ifndef OS_VER_MIN 14#define OS_VER_MIN "4.2" 15#endif 16 17#ifndef NIX_APPLE_HDRS 18#define NIX_APPLE_HDRS "" 19#endif 20 21#ifndef NIX_APPLE_FRAMEWORKS 22#define NIX_APPLE_FRAMEWORKS "" 23#endif 24 25#ifndef NIX_APPLE_PRIV_FRAMEWORKS 26#define NIX_APPLE_PRIV_FRAMEWORKS "" 27#endif 28 29#define _GNU_SOURCE 30 31#include <stdlib.h> 32#include <string.h> 33#include <stdio.h> 34#include <stddef.h> 35#include <unistd.h> 36#include <limits.h> 37 38#ifdef __APPLE__ 39#include <mach-o/dyld.h> 40#endif 41 42#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) 43#include <sys/sysctl.h> 44#endif 45 46#ifdef __OpenBSD__ 47#include <sys/types.h> 48#include <sys/user.h> 49#include <sys/stat.h> 50#endif 51 52char *get_executable_path(char *epath, size_t buflen) 53{ 54 char *p; 55#ifdef __APPLE__ 56 unsigned int l = buflen; 57 if (_NSGetExecutablePath(epath, &l) != 0) return NULL; 58#elif defined(__FreeBSD__) || defined(__DragonFly__) 59 int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; 60 size_t l = buflen; 61 if (sysctl(mib, 4, epath, &l, NULL, 0) != 0) return NULL; 62#elif defined(__OpenBSD__) 63 int mib[4]; 64 char **argv; 65 size_t len; 66 size_t l; 67 const char *comm; 68 int ok = 0; 69 mib[0] = CTL_KERN; 70 mib[1] = KERN_PROC_ARGS; 71 mib[2] = getpid(); 72 mib[3] = KERN_PROC_ARGV; 73 if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) 74 abort(); 75 if (!(argv = malloc(len))) 76 abort(); 77 if (sysctl(mib, 4, argv, &len, NULL, 0) < 0) 78 abort(); 79 comm = argv[0]; 80 if (*comm == '/' || *comm == '.') { 81 char *rpath; 82 if ((rpath = realpath(comm, NULL))) { 83 strlcpy(epath, rpath, buflen); 84 free(rpath); 85 ok = 1; 86 } 87 } else { 88 char *sp; 89 char *xpath = strdup(getenv("PATH")); 90 char *path = strtok_r(xpath, ":", &sp); 91 struct stat st; 92 if (!xpath) 93 abort(); 94 while (path) { 95 snprintf(epath, buflen, "%s/%s", path, comm); 96 if (!stat(epath, &st) && (st.st_mode & S_IXUSR)) { 97 ok = 1; 98 break; 99 } 100 path = strtok_r(NULL, ":", &sp); 101 } 102 free(xpath); 103 } 104 free(argv); 105 if (!ok) return NULL; 106 l = strlen(epath); 107#else 108 ssize_t l = readlink("/proc/self/exe", epath, buflen); 109#endif 110 if (l <= 0) return NULL; 111 epath[buflen - 1] = '\0'; 112 p = strrchr(epath, '/'); 113 if (p) *p = '\0'; 114 return epath; 115} 116 117char *get_filename(char *str) 118{ 119 char *p = strrchr(str, '/'); 120 return p ? &p[1] : str; 121} 122 123void target_info(char *argv[], char **triple, char **compiler) 124{ 125 char *p = get_filename(argv[0]); 126 char *x = strrchr(p, '-'); 127 if (!x) abort(); 128 *compiler = &x[1]; 129 *x = '\0'; 130 *triple = p; 131} 132 133void env(char **p, const char *name, char *fallback) 134{ 135 char *ev = getenv(name); 136 if (ev) { *p = ev; return; } 137 *p = fallback; 138} 139 140int main(int argc, char *argv[]) 141{ 142 char **args = alloca(sizeof(char*) * (argc + 17)); 143 int i, j; 144 145 char execpath[PATH_MAX+1]; 146 char sdkpath[PATH_MAX+1]; 147 char codesign_allocate[64]; 148 char osvermin[64]; 149 150 char *compiler, *target, *sdk, *cpu, *osmin; 151 152 target_info(argv, &target, &compiler); 153 154 if (!get_executable_path(execpath, sizeof(execpath))) abort(); 155 snprintf(sdkpath, sizeof(sdkpath), "%s/../SDK", execpath); 156 157 snprintf(codesign_allocate, sizeof(codesign_allocate), 158 "%s-codesign_allocate", target); 159 160 setenv("CODESIGN_ALLOCATE", codesign_allocate, 1); 161 setenv("IOS_FAKE_CODE_SIGN", "1", 1); 162 163 env(&sdk, "IOS_SDK_SYSROOT", sdkpath); 164 env(&cpu, "IOS_TARGET_CPU", TARGET_CPU); 165 166 env(&osmin, "IPHONEOS_DEPLOYMENT_TARGET", OS_VER_MIN); 167 unsetenv("IPHONEOS_DEPLOYMENT_TARGET"); 168 169 snprintf(osvermin, sizeof(osvermin), "-miphoneos-version-min=%s", osmin); 170 171 for (i = 1; i < argc; ++i) { 172 if (!strcmp(argv[i], "-arch")) { 173 cpu = NULL; 174 break; 175 } 176 } 177 178 i = 0; 179 180 args[i++] = compiler; 181 args[i++] = "-target"; 182 args[i++] = target; 183 args[i++] = "-isysroot"; 184 args[i++] = sdk; 185 args[i++] = NIX_APPLE_HDRS; 186 args[i++] = "-F"; 187 args[i++] = NIX_APPLE_FRAMEWORKS; 188 args[i++] = "-F"; 189 args[i++] = NIX_APPLE_PRIV_FRAMEWORKS; 190 191 if (cpu) { 192 args[i++] = "-arch"; 193 args[i++] = cpu; 194 } 195 196 args[i++] = osvermin; 197 args[i++] = "-mlinker-version=253.3"; 198 199 for (j = 1; j < argc; ++i, ++j) args[i] = argv[j]; 200 201 args[i] = NULL; 202 203 setenv("COMPILER_PATH", execpath, 1); 204 /* int k; */ 205 /* for (k = 0; k < i; k++) */ 206 /* printf("Compiler option: %s\n", args[k]); */ 207 /* printf("End of Compiler args\n"); */ 208 execvp(compiler, args); 209 210 fprintf(stderr, "cannot invoke compiler, this is a serious bug\n"); 211 return 1; 212}