diff options
author | 2024-04-04 22:27:06 +0200 | |
---|---|---|
committer | 2024-04-04 22:29:39 +0200 | |
commit | e3536efbe87342ead017157e0cc359dead73d9dd (patch) | |
tree | 1203b105ebad2a0b3cbab509b4bb257d37fdf5d4 | |
parent | scripts/auto-bootstraps/process_uploads: allow processing of temp files too (diff) | |
download | prefix-e3536efbe87342ead017157e0cc359dead73d9dd.tar.gz prefix-e3536efbe87342ead017157e0cc359dead73d9dd.tar.bz2 prefix-e3536efbe87342ead017157e0cc359dead73d9dd.zip |
sys-devel/binutils-config: remove duplicate -L and -rpath entries
Ever since CLT15.3 duplicate -L or -rpath entries result in warnings.
These warnings, albeit just ugly, make that some packages croak or
worse: abort, claiming the linker is broken (such as Ruby). This is
nonsense, but cater for this by removing any duplicate paths, and not
adding any paths that are already added.
Signed-off-by: Fabian Groffen <grobian@gentoo.org>
-rw-r--r-- | sys-devel/binutils-config/binutils-config-5.1-r11.ebuild (renamed from sys-devel/binutils-config/binutils-config-5.1-r10.ebuild) | 0 | ||||
-rw-r--r-- | sys-devel/binutils-config/files/ldwrapper.c | 198 |
2 files changed, 150 insertions, 48 deletions
diff --git a/sys-devel/binutils-config/binutils-config-5.1-r10.ebuild b/sys-devel/binutils-config/binutils-config-5.1-r11.ebuild index 38f82d40b5..38f82d40b5 100644 --- a/sys-devel/binutils-config/binutils-config-5.1-r10.ebuild +++ b/sys-devel/binutils-config/binutils-config-5.1-r11.ebuild diff --git a/sys-devel/binutils-config/files/ldwrapper.c b/sys-devel/binutils-config/files/ldwrapper.c index c799b4cdd9..22fbf9aba8 100644 --- a/sys-devel/binutils-config/files/ldwrapper.c +++ b/sys-devel/binutils-config/files/ldwrapper.c @@ -197,7 +197,10 @@ int main(int argc, char *argv[]) { int newargc = 0; + int rpathcnt = 0; char **newargv = NULL; + char **rpaths = NULL; + char **lpaths = NULL; char *wrapper = argv[0]; char *wrapperctarget = NULL; char verbose = getenv("BINUTILS_CONFIG_VERBOSE") != NULL; @@ -214,7 +217,6 @@ main(int argc, char *argv[]) size_t len; int i; int j; - int k; DIR *dirp; struct dirent *dp; @@ -287,10 +289,12 @@ main(int argc, char *argv[]) /* walk over the arguments to see if there's anything interesting * for us and calculate the final number of arguments */ for (i = 1; i < argc; i++) { - /* -L: account space for the matching -R */ if (argv[i][0] == '-') { + /* -L: account space for the matching -R */ if (argv[i][1] == 'L') newargc++; + if (argv[i][1] == 'R' || strcmp(argv[i], "-rpath") == 0) + rpathcnt++; if (argv[i][1] == 'v' || argv[i][1] == 'V') verbose = 1; if ((strcmp(argv[i], "-macosx_version_min") == 0 || @@ -316,8 +320,6 @@ main(int argc, char *argv[]) darwin_dt_ver += (int)strtol(p + 1, &p, 10); } - /* Note: Code below assumes that newargc is the count of -L arguments. */ - /* If a package being cross-compiled injects standard directories, it's * non-cross-compilable on any platform, prefix or no prefix. So no * need to add PREFIX- or CTARGET-aware libdirs. */ @@ -341,13 +343,15 @@ main(int argc, char *argv[]) * -rpath and the path itself */ newargc *= 2; - /* and we will be adding two for the each of - * the two system paths as well */ - newargc += 4; + /* PREFIX rpaths */ + newargc += 2 * 2; } - /* add the 2 prefix paths (-L) and -search_paths_first */ - newargc += 2 + 1; + /* PREFIX paths */ + newargc += 3; + + /* add -search_paths_first */ + newargc += 1; /* add -syslibroot <path> -platform_version macos <ver> 0.0 */ newargc += 6; @@ -357,6 +361,27 @@ main(int argc, char *argv[]) } } + /* Note: Code below assumes that newargc is the count of -L arguments. */ + + /* allocate space for -L lookups/uniqueifying */ + lpaths = malloc(sizeof(lpaths[0]) * (newargc + 1)); + if (lpaths == NULL) { + fprintf(stderr, "%s: failed to allocate memory for new arguments\n", + wrapper); + exit(1); + } + lpaths[0] = NULL; + + if (!is_darwin || darwin_use_rpath) { + rpaths = malloc(sizeof(rpaths[0]) * (rpathcnt + 1)); + if (rpaths == NULL) { + fprintf(stderr, "%s: failed to allocate memory for new arguments\n", + wrapper); + exit(1); + } + rpaths[0] = NULL; + } + /* account the original arguments */ newargc += argc; /* we always add a sentinel */ @@ -476,8 +501,6 @@ main(int argc, char *argv[]) newargv[j++] = "-search_paths_first"; } - /* position k right after the original arguments */ - k = j - 1 + argc; for (i = 1; i < argc; i++, j++) { if (is_darwin) { /* skip platform version stuff, we already pushed it out */ @@ -486,7 +509,6 @@ main(int argc, char *argv[]) { i++; j--; - k -= 2; continue; } if (strcmp(argv[i], "-platform_version") == 0 && @@ -494,7 +516,6 @@ main(int argc, char *argv[]) { i += 3; j--; - k -= 4; continue; } } @@ -504,10 +525,12 @@ main(int argc, char *argv[]) if (is_cross || (is_darwin && !darwin_use_rpath)) continue; - /* on ELF targets we add runpaths for all found search paths */ - if (argv[i][0] == '-' && argv[i][1] == 'L') { + /* on ELF/Mach-O targets we add runpaths for all found search paths */ + if (argv[i][0] == '-' && (argv[i][1] == 'L' || argv[i][1] == 'R')) { char *path; - size_t sze; + int pth; + char duplicate; + int before = j - 1; /* arguments can be in many ways here: * -L<path> @@ -533,50 +556,129 @@ main(int argc, char *argv[]) if (builddir != NULL && strncmp(builddir, path, len) == 0) continue; - if (is_darwin) { - newargv[k] = "-rpath"; - newargv[++k] = path; - } else { - sze = 2 + strlen(path) + 1; - newargv[k] = malloc(sizeof(char) * sze); - if (newargv[k] == NULL) { - fprintf(stderr, "%s: failed to allocate memory for " - "'%s' -R argument\n", wrapper, argv[i]); - exit(1); + /* loop-search for this path, if it was emitted already, + * suppress it -- this is not just some fancy beautification! + * CLT15.3 on macOS warns about duplicate paths, and + * any project that triggers on these warnings causes + * problems, such as Ruby claiming the linker is broken */ + duplicate = 0; + if (argv[i][1] == 'L') { + for (pth = 0; lpaths[pth] != NULL; pth++) { + if (strcmp(lpaths[pth], path) == 0) { + duplicate = 1; + break; + } } - - snprintf(newargv[k], sze, "-R%s", path); + if (duplicate) { + j = before; + continue; + } + /* record path */ + lpaths[pth++] = path; + lpaths[pth] = NULL; + } else if (!is_darwin || darwin_use_rpath) { + for (pth = 0; rpaths[pth] != NULL; pth++) { + if (strcmp(rpaths[pth], path) == 0) { + duplicate = 1; + break; + } + } + if (duplicate) { + j = before; + continue; + } + /* record path */ + rpaths[pth++] = path; + rpaths[pth] = NULL; } + } else if ((!is_darwin || darwin_use_rpath) && + strcmp(argv[i], "-rpath") == 0) + { + char *path; + int pth; + char duplicate; - k++; + path = argv[i + 1]; + while (*path != '\0' && isspace(*path)) + path++; + /* not absolute (or empty)?!? skip */ + if (*path != '/') + continue; + + /* does it refer to the build directory? skip */ + if (builddir != NULL && strncmp(builddir, path, len) == 0) + continue; + + duplicate = 0; + for (pth = 0; rpaths[pth] != NULL; pth++) { + if (strcmp(rpaths[pth], path) == 0) { + duplicate = 1; + break; + } + } + if (duplicate) { + j -= 2; + continue; + } + /* record path */ + rpaths[pth++] = path; + rpaths[pth] = NULL; } } /* add the custom paths */ if (!is_cross) { + int pth; +#define path_not_exists(W,P) \ + for (pth = 0; W[pth] != NULL; pth++) { \ + if (strcmp(W[pth], P) == 0) \ + break; \ + } \ + if (W[pth] == NULL) +#define add_path(P) \ + path_not_exists(lpaths, P) newargv[j++] = "-L" P +#define add_path_rpath(P) \ + path_not_exists(lpaths, P) { \ + lpaths[pth++] = P; \ + lpaths[pth] = NULL; \ + newargv[j++] = "-L" P; \ + } + if (is_darwin) { /* FIXME: no support for cross-compiling *to* Darwin */ - newargv[k++] = "-L" EPREFIX "/usr/" CHOST "/lib/gcc"; - newargv[k++] = "-L" EPREFIX "/usr/lib"; - newargv[k++] = "-L" EPREFIX "/lib"; - - if (darwin_use_rpath) { - newargv[k++] = "-rpath"; - newargv[k++] = EPREFIX "/usr/lib"; - newargv[k++] = "-rpath"; - newargv[k++] = EPREFIX "/lib"; - } + add_path(EPREFIX "/usr/" CHOST "/lib/gcc"); + add_path_rpath(EPREFIX "/usr/lib"); + add_path_rpath(EPREFIX "/lib"); } else { - newargv[k++] = "-L" EPREFIX "/usr/" CHOST "/lib/gcc"; - newargv[k++] = "-R" EPREFIX "/usr/" CHOST "/lib/gcc"; - newargv[k++] = "-L" EPREFIX "/usr/" CHOST "/lib"; - newargv[k++] = "-R" EPREFIX "/usr/" CHOST "/lib"; - newargv[k++] = "-L" EPREFIX "/usr/lib"; - newargv[k++] = "-R" EPREFIX "/usr/lib"; - newargv[k++] = "-L" EPREFIX "/lib"; - newargv[k++] = "-R" EPREFIX "/lib"; + add_path_rpath(EPREFIX "/usr/" CHOST "/lib/gcc"); + add_path_rpath(EPREFIX "/usr/" CHOST "/lib"); + add_path_rpath(EPREFIX "/usr/lib"); + add_path_rpath(EPREFIX "/lib"); + } + } + /* add rpaths for -L entries */ + if (!is_darwin || darwin_use_rpath) { + for (i = 0; lpaths[i] != NULL; i++) { + int pth; + path_not_exists(rpaths, lpaths[i]) { + size_t sze; + if (is_darwin && darwin_use_rpath) { + newargv[j++] = "-rpath"; + newargv[j++] = lpaths[i]; + } else if (!is_darwin) { + sze = 2 + strlen(lpaths[i]) + 1; + newargv[j] = malloc(sizeof(char) * sze); + if (newargv[j] == NULL) { + fprintf(stderr, "%s: failed to allocate memory for " + "'%s' -R argument\n", wrapper, argv[i]); + exit(1); + } + + snprintf(newargv[j++], sze, "-R%s", lpaths[i]); + } + } } } - newargv[k] = NULL; + newargv[j] = NULL; if (verbose) { fprintf(stderr, "%s: invoking %s with arguments:\n", wrapper, ld); |