1 |
commit: b93602ba2a0f76a9a85cb36a1740a4522e45ce36 |
2 |
Author: Michael Weiser <michael.weiser <AT> gmx <DOT> de> |
3 |
AuthorDate: Wed Dec 27 21:36:35 2017 +0000 |
4 |
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri Dec 29 14:54:50 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/proj/prefix.git/commit/?id=b93602ba |
7 |
|
8 |
sys-devel/binutils-config: Use -rpath on Darwin |
9 |
|
10 |
Extend ldwrapper to inject -rpath options into the linker command line |
11 |
on darwin as well. Only do so if ld64 would not refuse to accept them. |
12 |
This can happen if the output type doesn't support it (static, kext, |
13 |
...) or the deployment target is unspecified or did not support -rpath |
14 |
yet (< 10.5). The latter is not usually a problem since portage |
15 |
(MACOSX_DEPLOYMENT_TARGET) and clang (-macosx_version_min) always set |
16 |
the deployment target explicitly. |
17 |
|
18 |
Signed-off-by: Michael Weiser <michael.weiser <AT> gmx.de> |
19 |
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org> |
20 |
|
21 |
sys-devel/binutils-config/files/ldwrapper.c | 79 ++++++++++++++++++++++++----- |
22 |
1 file changed, 67 insertions(+), 12 deletions(-) |
23 |
|
24 |
diff --git a/sys-devel/binutils-config/files/ldwrapper.c b/sys-devel/binutils-config/files/ldwrapper.c |
25 |
index a8f140be27..1ed11ce42d 100644 |
26 |
--- a/sys-devel/binutils-config/files/ldwrapper.c |
27 |
+++ b/sys-devel/binutils-config/files/ldwrapper.c |
28 |
@@ -205,8 +205,10 @@ main(int argc, char *argv[]) |
29 |
char ldbuf[ESIZ]; |
30 |
char *ld = ldbuf; |
31 |
char ctarget[128]; |
32 |
+ char *darwin_dt = getenv("MACOSX_DEPLOYMENT_TARGET"); |
33 |
char is_cross = 0; |
34 |
char is_darwin = 0; |
35 |
+ char darwin_use_rpath = 1; |
36 |
char is_aix = 0; |
37 |
char *p; |
38 |
size_t len; |
39 |
@@ -287,18 +289,52 @@ main(int argc, char *argv[]) |
40 |
newargc++; |
41 |
if (argv[i][1] == 'v' || argv[i][1] == 'V') |
42 |
verbose = 1; |
43 |
+ if (strcmp(argv[i], "-macosx_version_min") == 0 && i < argc - 1) |
44 |
+ darwin_dt = argv[i + 1]; |
45 |
+ /* ld64 will refuse to accept -rpath if any of the |
46 |
+ * following options are given */ |
47 |
+ if (strcmp(argv[i], "-static") == 0 || |
48 |
+ strcmp(argv[i], "-dylinker") == 0 || |
49 |
+ strcmp(argv[i], "-preload") == 0 || |
50 |
+ strcmp(argv[i], "-r") == 0 || |
51 |
+ strcmp(argv[i], "-kext") == 0) |
52 |
+ darwin_use_rpath = 0; |
53 |
} |
54 |
} |
55 |
- /* account the original arguments */ |
56 |
- newargc += argc; |
57 |
- /* we always add a sentinel */ |
58 |
- newargc++; |
59 |
+ |
60 |
+ /* Note: Code below assumes that newargc is the count of -L arguments. */ |
61 |
|
62 |
/* If a package being cross-compiled injects standard directories, it's |
63 |
* non-cross-compilable on any platform, prefix or no prefix. So no |
64 |
* need to add PREFIX- or CTARGET-aware libdirs. */ |
65 |
if (!is_cross) { |
66 |
if (is_darwin) { |
67 |
+ /* check deployment target if nothing prevents us from |
68 |
+ * using -rpath as of yet |
69 |
+ * # ld64 -rpath foo |
70 |
+ * ld: -rpath can only be used when targeting Mac OS X |
71 |
+ * 10.5 or later */ |
72 |
+ if (darwin_use_rpath) { |
73 |
+ /* version format is x.y.z. atoi will stop |
74 |
+ * parsing at dots. darwin_dt != NULL isn't |
75 |
+ * just for safety: ld64 also refuses -rpath |
76 |
+ * when not given a deployment target at all */ |
77 |
+ darwin_use_rpath = darwin_dt != NULL && |
78 |
+ (atoi(darwin_dt) > 10 || |
79 |
+ (strncmp(darwin_dt, "10.", 3) == 0 && |
80 |
+ atoi(darwin_dt + 3) >= 5)); |
81 |
+ } |
82 |
+ |
83 |
+ if (darwin_use_rpath) { |
84 |
+ /* We need two additional arguments for each: |
85 |
+ * -rpath and the path itself */ |
86 |
+ newargc *= 2; |
87 |
+ |
88 |
+ /* and we will be adding two for the each of |
89 |
+ * the two system paths as well */ |
90 |
+ newargc += 4; |
91 |
+ } |
92 |
+ |
93 |
/* add the 2 prefix paths (-L) and -search_paths_first */ |
94 |
newargc += 2 + 1; |
95 |
} else { |
96 |
@@ -312,6 +348,11 @@ main(int argc, char *argv[]) |
97 |
} |
98 |
} |
99 |
|
100 |
+ /* account the original arguments */ |
101 |
+ newargc += argc; |
102 |
+ /* we always add a sentinel */ |
103 |
+ newargc++; |
104 |
+ |
105 |
/* let's first try to find the real ld */ |
106 |
if (find_real_ld(&ld, sizeof(ldbuf), verbose, is_cross, |
107 |
wrapper, ctarget) != 0) |
108 |
@@ -358,7 +399,7 @@ main(int argc, char *argv[]) |
109 |
|
110 |
newargv[j] = argv[i]; |
111 |
|
112 |
- if (is_cross || is_darwin) |
113 |
+ if (is_cross || (is_darwin && !darwin_use_rpath)) |
114 |
continue; |
115 |
|
116 |
/* on ELF targets we add runpaths for all found search paths */ |
117 |
@@ -390,14 +431,21 @@ main(int argc, char *argv[]) |
118 |
if (builddir != NULL && strncmp(builddir, path, len) != 0) |
119 |
continue; |
120 |
|
121 |
- sze = 2 + strlen(path) + 1; |
122 |
- newargv[k] = malloc(sizeof(char) * sze); |
123 |
- if (newargv[k] == NULL) { |
124 |
- fprintf(stderr, "%s: failed to allocate memory for " |
125 |
- "'%s' -R argument\n", wrapper, argv[i]); |
126 |
- exit(1); |
127 |
+ if (is_darwin) { |
128 |
+ newargv[k] = "-rpath"; |
129 |
+ newargv[++k] = path; |
130 |
+ } else { |
131 |
+ sze = 2 + strlen(path) + 1; |
132 |
+ newargv[k] = malloc(sizeof(char) * sze); |
133 |
+ if (newargv[k] == NULL) { |
134 |
+ fprintf(stderr, "%s: failed to allocate memory for " |
135 |
+ "'%s' -R argument\n", wrapper, argv[i]); |
136 |
+ exit(1); |
137 |
+ } |
138 |
+ |
139 |
+ snprintf(newargv[k], sze, "-R%s", path); |
140 |
} |
141 |
- snprintf(newargv[k], sze, "-R%s", path); |
142 |
+ |
143 |
k++; |
144 |
} |
145 |
} |
146 |
@@ -407,6 +455,13 @@ main(int argc, char *argv[]) |
147 |
/* FIXME: no support for cross-compiling *to* Darwin */ |
148 |
newargv[k++] = "-L" EPREFIX "/usr/lib"; |
149 |
newargv[k++] = "-L" EPREFIX "/lib"; |
150 |
+ |
151 |
+ if (darwin_use_rpath) { |
152 |
+ newargv[k++] = "-rpath"; |
153 |
+ newargv[k++] = EPREFIX "/usr/lib"; |
154 |
+ newargv[k++] = "-rpath"; |
155 |
+ newargv[k++] = EPREFIX "/lib"; |
156 |
+ } |
157 |
} else { |
158 |
newargv[k++] = "-L" EPREFIX "/usr/" CHOST "/lib/gcc"; |
159 |
newargv[k++] = "-R" EPREFIX "/usr/" CHOST "/lib/gcc"; |