diff --git a/cross/crossdirect/APKBUILD b/cross/crossdirect/APKBUILD index a0d4cf4ff..a0bec9364 100644 --- a/cross/crossdirect/APKBUILD +++ b/cross/crossdirect/APKBUILD @@ -13,7 +13,7 @@ # implementation details (llvm, fakeroot, rpath). pkgname=crossdirect -pkgver=2 +pkgver=3 pkgrel=0 pkgdesc="Wrappers to launch native cross compilers in foreign chroots" url="https://postmarketOS.org" @@ -63,4 +63,4 @@ package() { done done } -sha512sums="6a94a2e0842c95b8ca862b71a7b54f280d0fe9da40fe40691628ef6089a995159c1b53513fb006589af064110a9d2592b24c772264c02d27e7bac9871428f757 crossdirect.c" +sha512sums="f8366add6ba2ac6d9f8af89f389c69914009b12b21e6608121a78d1cd9afe287e24eafb0c21d80d096df9eee9a23cc2e6a5408f6355e27be05203186a0bf9814 crossdirect.c" diff --git a/cross/crossdirect/crossdirect.c b/cross/crossdirect/crossdirect.c index 319e11fca..4a7d4cd49 100644 --- a/cross/crossdirect/crossdirect.c +++ b/cross/crossdirect/crossdirect.c @@ -18,6 +18,19 @@ void exit_userfriendly() { exit(1); } +bool argv_has_arg(int argc, char** argv, const char* arg) { + size_t arg_len = strlen(arg); + + for (int i=1; i < argc; i++) { + if (strlen(argv[i]) < arg_len) + continue; + + if (!memcmp(argv[i], arg, arg_len)) + return true; + } + return false; +} + int main(int argc, char** argv) { // we have a max of four extra args ("-target", "HOSTSPEC", "--sysroot=/", "-Wl,-rpath-link=/lib:/usr/lib"), plus one ending null char* newargv[argc + 5]; @@ -26,6 +39,16 @@ int main(int argc, char** argv) { bool isClang = (strcmp(executableName, "clang") == 0 || strcmp(executableName, "clang++") == 0); bool startsWithHostSpec = (strncmp(HOSTSPEC, executableName, sizeof(HOSTSPEC) -1) == 0); + // linker is involved: just use qemu binary (to avoid broken cross-ld, pmaports#227) + if (!argv_has_arg(argc, argv, "-c")) { + snprintf(newExecutable, sizeof(newExecutable), "/usr/bin/%s", executableName); + if (execv(newExecutable, argv) == -1) { + fprintf(stderr, "ERROR: crossdirect: failed to execute %s: %s\n", newExecutable, strerror(errno)); + fprintf(stderr, "NOTE: this is a foreign arch binary that would run with qemu (linker is involved).\n"); + exit_userfriendly(); + } + } + if (isClang || startsWithHostSpec) { snprintf(newExecutable, sizeof(newExecutable), NATIVE_BIN_DIR "/%s", executableName); } else { @@ -39,22 +62,7 @@ int main(int argc, char** argv) { *newArgsPtr++ = HOSTSPEC; } *newArgsPtr++ = "--sysroot=/"; - bool addrpath = true; - if (isClang) { - // clang gives a warning if the rpath parameter is passed when linker isn't invoked. - // to avoid this warning, only add if we're actually linking at least one library. - addrpath = false; - for (int i = 1; i < argc; i++) { - char* arg = argv[i]; - if (strlen(arg) >= 2 && arg[0] == '-' && arg[1] == 'l') { - addrpath = true; - break; - } - } - } - if (addrpath) { - *newArgsPtr++ = "-Wl,-rpath-link=/lib:/usr/lib"; - } + memcpy(newArgsPtr, argv + 1, sizeof(char*)*(argc - 1)); newArgsPtr += (argc - 1); *newArgsPtr = NULL;