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;
 | 
						|
}
 |