Merge pull request #268619 from tweag/lib-descriptions
[NixPkgs.git] / pkgs / development / compilers / ios-cross-compile / alt_wrapper.c
blob928b64e6fd9d518068288fd39b5385aa505c466f
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 */
9 #ifndef TARGET_CPU
10 #define TARGET_CPU "armv7"
11 #endif
13 #ifndef OS_VER_MIN
14 #define OS_VER_MIN "4.2"
15 #endif
17 #ifndef NIX_APPLE_HDRS
18 #define NIX_APPLE_HDRS ""
19 #endif
21 #ifndef NIX_APPLE_FRAMEWORKS
22 #define NIX_APPLE_FRAMEWORKS ""
23 #endif
25 #ifndef NIX_APPLE_PRIV_FRAMEWORKS
26 #define NIX_APPLE_PRIV_FRAMEWORKS ""
27 #endif
29 #define _GNU_SOURCE
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <stddef.h>
35 #include <unistd.h>
36 #include <limits.h>
38 #ifdef __APPLE__
39 #include <mach-o/dyld.h>
40 #endif
42 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
43 #include <sys/sysctl.h>
44 #endif
46 #ifdef __OpenBSD__
47 #include <sys/types.h>
48 #include <sys/user.h>
49 #include <sys/stat.h>
50 #endif
52 char *get_executable_path(char *epath, size_t buflen)
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;
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;
100 path = strtok_r(NULL, ":", &sp);
102 free(xpath);
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;
117 char *get_filename(char *str)
119 char *p = strrchr(str, '/');
120 return p ? &p[1] : str;
123 void target_info(char *argv[], char **triple, char **compiler)
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;
133 void env(char **p, const char *name, char *fallback)
135 char *ev = getenv(name);
136 if (ev) { *p = ev; return; }
137 *p = fallback;
140 int main(int argc, char *argv[])
142 char **args = alloca(sizeof(char*) * (argc + 17));
143 int i, j;
145 char execpath[PATH_MAX+1];
146 char sdkpath[PATH_MAX+1];
147 char codesign_allocate[64];
148 char osvermin[64];
150 char *compiler, *target, *sdk, *cpu, *osmin;
152 target_info(argv, &target, &compiler);
154 if (!get_executable_path(execpath, sizeof(execpath))) abort();
155 snprintf(sdkpath, sizeof(sdkpath), "%s/../SDK", execpath);
157 snprintf(codesign_allocate, sizeof(codesign_allocate),
158 "%s-codesign_allocate", target);
160 setenv("CODESIGN_ALLOCATE", codesign_allocate, 1);
161 setenv("IOS_FAKE_CODE_SIGN", "1", 1);
163 env(&sdk, "IOS_SDK_SYSROOT", sdkpath);
164 env(&cpu, "IOS_TARGET_CPU", TARGET_CPU);
166 env(&osmin, "IPHONEOS_DEPLOYMENT_TARGET", OS_VER_MIN);
167 unsetenv("IPHONEOS_DEPLOYMENT_TARGET");
169 snprintf(osvermin, sizeof(osvermin), "-miphoneos-version-min=%s", osmin);
171 for (i = 1; i < argc; ++i) {
172 if (!strcmp(argv[i], "-arch")) {
173 cpu = NULL;
174 break;
178 i = 0;
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;
191 if (cpu) {
192 args[i++] = "-arch";
193 args[i++] = cpu;
196 args[i++] = osvermin;
197 args[i++] = "-mlinker-version=253.3";
199 for (j = 1; j < argc; ++i, ++j) args[i] = argv[j];
201 args[i] = NULL;
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);
210 fprintf(stderr, "cannot invoke compiler, this is a serious bug\n");
211 return 1;