cross/crossdirect: use qemu when linking (!318)
Cross linker (e.g. ld from binutils-armhf) does not support any method of setting additional link paths, and this causes problems when building various packages. Work around this problem by calling the qemu binary instead of the cross binary from the native chroot, whenever we are linking. I have tested that this allows successfully building hello-world, coreinfo, libhybris for armhf. So this fixes #227 and fixes #228. Regarding performance, this is the same way as distcc does it. We would get a performance gain if we were able to use the cross-linker. But so far I could not figure out how to patch the binutils source to make it work like we want to have it. Maybe I'll ask on some binutils mailing list for advice. In the meantime, this workaround should make crossdirect work for all use-cases, and it is still faster than the previous distcc setup, because we can avoid the overhead of setting up and running a ssh server locally to work around missing authentication in distcc (see pmbootstrap!1649). Let's test this for some more time, and then make a pmbootstrap release that rolls out crossdirect for everyone.
This commit is contained in:
parent
6b9ef9fda0
commit
2c07f28419
2 changed files with 26 additions and 18 deletions
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue