Commit | Line | Data |
---|---|---|
8b2f0590 MJ |
1 | # =========================================================================== |
2 | # https://www.gnu.org/software/autoconf-archive/ax_sys_weak_alias.html | |
3 | # =========================================================================== | |
4 | # | |
5 | # SYNOPSIS | |
6 | # | |
7 | # AX_SYS_WEAK_ALIAS | |
8 | # | |
9 | # DESCRIPTION | |
10 | # | |
11 | # Determines whether weak aliases are supported on the system, and if so, | |
12 | # what scheme is used to declare them. Also checks to see if aliases can | |
13 | # cross object file boundaries, as some systems don't permit them to. | |
14 | # | |
15 | # Most systems permit something called a "weak alias" or "weak symbol." | |
16 | # These aliases permit a library to provide a stub form of a routine | |
17 | # defined in another library, thus allowing the first library to operate | |
18 | # even if the other library is not linked. This macro will check for | |
19 | # support of weak aliases, figure out what schemes are available, and | |
20 | # determine some characteristics of the weak alias support -- primarily, | |
21 | # whether a weak alias declared in one object file may be referenced from | |
22 | # another object file. | |
23 | # | |
24 | # There are four known schemes of declaring weak symbols; each scheme is | |
25 | # checked in turn, and the first one found is preferred. Note that only | |
26 | # one of the mentioned preprocessor macros will be defined! | |
27 | # | |
28 | # 1. Function attributes | |
29 | # | |
30 | # This scheme was first introduced by the GNU C compiler, and attaches | |
31 | # attributes to particular functions. It is among the easiest to use, and | |
32 | # so is the first one checked. If this scheme is detected, the | |
33 | # preprocessor macro HAVE_SYS_WEAK_ALIAS_ATTRIBUTE will be defined to 1. | |
34 | # This scheme is used as in the following code fragment: | |
35 | # | |
36 | # void __weakf(int c) | |
37 | # { | |
38 | # /* Function definition... */ | |
39 | # } | |
40 | # | |
41 | # void weakf(int c) __attribute__((weak, alias("__weakf"))); | |
42 | # | |
43 | # 2. #pragma weak | |
44 | # | |
45 | # This scheme is in use by many compilers other than the GNU C compiler. | |
46 | # It is also particularly easy to use, and fairly portable -- well, as | |
47 | # portable as these things get. If this scheme is detected first, the | |
48 | # preprocessor macro HAVE_SYS_WEAK_ALIAS_PRAGMA will be defined to 1. This | |
49 | # scheme is used as in the following code fragment: | |
50 | # | |
51 | # extern void weakf(int c); | |
52 | # #pragma weak weakf = __weakf | |
53 | # void __weakf(int c) | |
54 | # { | |
55 | # /* Function definition... */ | |
56 | # } | |
57 | # | |
58 | # 3. #pragma _HP_SECONDARY_DEF | |
59 | # | |
60 | # This scheme appears to be in use by the HP compiler. As it is rather | |
61 | # specialized, this is one of the last schemes checked. If it is the first | |
62 | # one detected, the preprocessor macro HAVE_SYS_WEAK_ALIAS_HPSECONDARY | |
63 | # will be defined to 1. This scheme is used as in the following code | |
64 | # fragment: | |
65 | # | |
66 | # extern void weakf(int c); | |
67 | # #pragma _HP_SECONDARY_DEF __weakf weakf | |
68 | # void __weakf(int c) | |
69 | # { | |
70 | # /* Function definition... */ | |
71 | # } | |
72 | # | |
73 | # 4. #pragma _CRI duplicate | |
74 | # | |
75 | # This scheme appears to be in use by the Cray compiler. As it is rather | |
76 | # specialized, it too is one of the last schemes checked. If it is the | |
77 | # first one detected, the preprocessor macro | |
78 | # HAVE_SYS_WEAK_ALIAS_CRIDUPLICATE will be defined to 1. This scheme is | |
79 | # used as in the following code fragment: | |
80 | # | |
81 | # extern void weakf(int c); | |
82 | # #pragma _CRI duplicate weakf as __weakf | |
83 | # void __weakf(int c) | |
84 | # { | |
85 | # /* Function definition... */ | |
86 | # } | |
87 | # | |
88 | # In addition to the preprocessor macros listed above, if any scheme is | |
89 | # found, the preprocessor macro HAVE_SYS_WEAK_ALIAS will also be defined | |
90 | # to 1. | |
91 | # | |
92 | # Once a weak aliasing scheme has been found, a check will be performed to | |
93 | # see if weak aliases are honored across object file boundaries. If they | |
94 | # are, the HAVE_SYS_WEAK_ALIAS_CROSSFILE preprocessor macro is defined to | |
95 | # 1. | |
96 | # | |
97 | # This Autoconf macro also makes two substitutions. The first, WEAK_ALIAS, | |
98 | # contains the name of the scheme found (one of "attribute", "pragma", | |
99 | # "hpsecondary", or "criduplicate"), or "no" if no weak aliasing scheme | |
100 | # was found. The second, WEAK_ALIAS_CROSSFILE, is set to "yes" or "no" | |
101 | # depending on whether or not weak aliases may cross object file | |
102 | # boundaries. | |
103 | # | |
104 | # LICENSE | |
105 | # | |
106 | # Copyright (c) 2008 Kevin L. Mitchell <klmitch@mit.edu> | |
107 | # | |
108 | # Copying and distribution of this file, with or without modification, are | |
109 | # permitted in any medium without royalty provided the copyright notice | |
110 | # and this notice are preserved. This file is offered as-is, without any | |
111 | # warranty. | |
112 | ||
113 | #serial 8 | |
114 | ||
115 | AU_ALIAS([KLM_SYS_WEAK_ALIAS], [AX_SYS_WEAK_ALIAS]) | |
116 | AC_DEFUN([AX_SYS_WEAK_ALIAS], [ | |
117 | # starting point: no aliasing scheme yet... | |
118 | ax_sys_weak_alias=no | |
119 | ||
120 | # Figure out what kind of aliasing may be supported... | |
121 | _AX_SYS_WEAK_ALIAS_ATTRIBUTE | |
122 | _AX_SYS_WEAK_ALIAS_PRAGMA | |
123 | _AX_SYS_WEAK_ALIAS_HPSECONDARY | |
124 | _AX_SYS_WEAK_ALIAS_CRIDUPLICATE | |
125 | ||
126 | # Do we actually support aliasing? | |
127 | AC_CACHE_CHECK([how to create weak aliases with $CC], | |
128 | [ax_cv_sys_weak_alias], | |
129 | [ax_cv_sys_weak_alias=$ax_sys_weak_alias]) | |
130 | ||
131 | # OK, set a #define | |
132 | AS_IF([test $ax_cv_sys_weak_alias != no], [ | |
133 | AC_DEFINE([HAVE_SYS_WEAK_ALIAS], 1, | |
134 | [Define this if your system can create weak aliases]) | |
135 | ]) | |
136 | ||
137 | # Can aliases cross object file boundaries? | |
138 | _AX_SYS_WEAK_ALIAS_CROSSFILE | |
139 | ||
140 | # OK, remember the results | |
141 | AC_SUBST([WEAK_ALIAS], [$ax_cv_sys_weak_alias]) | |
142 | AC_SUBST([WEAK_ALIAS_CROSSFILE], [$ax_cv_sys_weak_alias_crossfile]) | |
143 | ]) | |
144 | ||
145 | AC_DEFUN([_AX_SYS_WEAK_ALIAS_ATTRIBUTE], | |
146 | [ # Test whether compiler accepts __attribute__ form of weak aliasing | |
147 | AC_CACHE_CHECK([whether $CC accepts function __attribute__((weak,alias()))], | |
148 | [ax_cv_sys_weak_alias_attribute], [ | |
149 | # We add -Werror if it's gcc to force an error exit if the weak attribute | |
150 | # isn't understood | |
151 | AS_IF([test $GCC = yes], [ | |
152 | save_CFLAGS=$CFLAGS | |
153 | CFLAGS=-Werror]) | |
154 | ||
155 | # Try linking with a weak alias... | |
156 | AC_LINK_IFELSE([ | |
157 | AC_LANG_PROGRAM([ | |
158 | void __weakf(int c) {} | |
159 | void weakf(int c) __attribute__((weak, alias("__weakf")));], | |
160 | [weakf(0)])], | |
161 | [ax_cv_sys_weak_alias_attribute=yes], | |
162 | [ax_cv_sys_weak_alias_attribute=no]) | |
163 | ||
164 | # Restore original CFLAGS | |
165 | AS_IF([test $GCC = yes], [ | |
166 | CFLAGS=$save_CFLAGS]) | |
167 | ]) | |
168 | ||
169 | # What was the result of the test? | |
170 | AS_IF([test $ax_sys_weak_alias = no && | |
171 | test $ax_cv_sys_weak_alias_attribute = yes], [ | |
172 | ax_sys_weak_alias=attribute | |
173 | AC_DEFINE([HAVE_SYS_WEAK_ALIAS_ATTRIBUTE], 1, | |
174 | [Define this if weak aliases may be created with __attribute__]) | |
175 | ]) | |
176 | ]) | |
177 | ||
178 | AC_DEFUN([_AX_SYS_WEAK_ALIAS_PRAGMA], | |
179 | [ # Test whether compiler accepts #pragma form of weak aliasing | |
180 | AC_CACHE_CHECK([whether $CC supports @%:@pragma weak], | |
181 | [ax_cv_sys_weak_alias_pragma], [ | |
182 | ||
183 | # Try linking with a weak alias... | |
184 | AC_LINK_IFELSE([ | |
185 | AC_LANG_PROGRAM([ | |
186 | extern void weakf(int c); | |
187 | @%:@pragma weak weakf = __weakf | |
188 | void __weakf(int c) {}], | |
189 | [weakf(0)])], | |
190 | [ax_cv_sys_weak_alias_pragma=yes], | |
191 | [ax_cv_sys_weak_alias_pragma=no]) | |
192 | ]) | |
193 | ||
194 | # What was the result of the test? | |
195 | AS_IF([test $ax_sys_weak_alias = no && | |
196 | test $ax_cv_sys_weak_alias_pragma = yes], [ | |
197 | ax_sys_weak_alias=pragma | |
198 | AC_DEFINE([HAVE_SYS_WEAK_ALIAS_PRAGMA], 1, | |
199 | [Define this if weak aliases may be created with @%:@pragma weak]) | |
200 | ]) | |
201 | ]) | |
202 | ||
203 | AC_DEFUN([_AX_SYS_WEAK_ALIAS_HPSECONDARY], | |
204 | [ # Test whether compiler accepts _HP_SECONDARY_DEF pragma from HP... | |
205 | AC_CACHE_CHECK([whether $CC supports @%:@pragma _HP_SECONDARY_DEF], | |
206 | [ax_cv_sys_weak_alias_hpsecondary], [ | |
207 | ||
208 | # Try linking with a weak alias... | |
209 | AC_LINK_IFELSE([ | |
210 | AC_LANG_PROGRAM([ | |
211 | extern void weakf(int c); | |
212 | @%:@pragma _HP_SECONDARY_DEF __weakf weakf | |
213 | void __weakf(int c) {}], | |
214 | [weakf(0)])], | |
215 | [ax_cv_sys_weak_alias_hpsecondary=yes], | |
216 | [ax_cv_sys_weak_alias_hpsecondary=no]) | |
217 | ]) | |
218 | ||
219 | # What was the result of the test? | |
220 | AS_IF([test $ax_sys_weak_alias = no && | |
221 | test $ax_cv_sys_weak_alias_hpsecondary = yes], [ | |
222 | ax_sys_weak_alias=hpsecondary | |
223 | AC_DEFINE([HAVE_SYS_WEAK_ALIAS_HPSECONDARY], 1, | |
224 | [Define this if weak aliases may be created with @%:@pragma _HP_SECONDARY_DEF]) | |
225 | ]) | |
226 | ]) | |
227 | ||
228 | AC_DEFUN([_AX_SYS_WEAK_ALIAS_CRIDUPLICATE], | |
229 | [ # Test whether compiler accepts "_CRI duplicate" pragma from Cray | |
230 | AC_CACHE_CHECK([whether $CC supports @%:@pragma _CRI duplicate], | |
231 | [ax_cv_sys_weak_alias_criduplicate], [ | |
232 | ||
233 | # Try linking with a weak alias... | |
234 | AC_LINK_IFELSE([ | |
235 | AC_LANG_PROGRAM([ | |
236 | extern void weakf(int c); | |
237 | @%:@pragma _CRI duplicate weakf as __weakf | |
238 | void __weakf(int c) {}], | |
239 | [weakf(0)])], | |
240 | [ax_cv_sys_weak_alias_criduplicate=yes], | |
241 | [ax_cv_sys_weak_alias_criduplicate=no]) | |
242 | ]) | |
243 | ||
244 | # What was the result of the test? | |
245 | AS_IF([test $ax_sys_weak_alias = no && | |
246 | test $ax_cv_sys_weak_alias_criduplicate = yes], [ | |
247 | ax_sys_weak_alias=criduplicate | |
248 | AC_DEFINE([HAVE_SYS_WEAK_ALIAS_CRIDUPLICATE], 1, | |
249 | [Define this if weak aliases may be created with @%:@pragma _CRI duplicate]) | |
250 | ]) | |
251 | ]) | |
252 | ||
253 | dnl Note: This macro is modeled closely on AC_LINK_IFELSE, and in fact | |
254 | dnl depends on some implementation details of that macro, particularly | |
255 | dnl its use of _AC_MSG_LOG_CONFTEST to log the failed test program and | |
256 | dnl its use of ac_link for running the linker. | |
257 | AC_DEFUN([_AX_SYS_WEAK_ALIAS_CROSSFILE], | |
258 | [ # Check to see if weak aliases can cross object file boundaries | |
259 | AC_CACHE_CHECK([whether $CC supports weak aliases across object file boundaries], | |
260 | [ax_cv_sys_weak_alias_crossfile], [ | |
261 | AS_IF([test $ax_cv_sys_weak_alias = no], | |
262 | [ax_cv_sys_weak_alias_crossfile=no], [ | |
263 | dnl Must build our own test files... | |
264 | # conftest1 contains our weak alias definition... | |
265 | cat >conftest1.$ac_ext <<_ACEOF | |
266 | /* confdefs.h. */ | |
267 | _ACEOF | |
268 | cat confdefs.h >>conftest1.$ac_ext | |
269 | cat >>conftest1.$ac_ext <<_ACEOF | |
270 | /* end confdefs.h. */ | |
271 | ||
272 | @%:@ifndef HAVE_SYS_WEAK_ALIAS_ATTRIBUTE | |
273 | extern void weakf(int c); | |
274 | @%:@endif | |
275 | @%:@if defined(HAVE_SYS_WEAK_ALIAS_PRAGMA) | |
276 | @%:@pragma weak weakf = __weakf | |
277 | @%:@elif defined(HAVE_SYS_WEAK_ALIAS_HPSECONDARY) | |
278 | @%:@pragma _HP_SECONDARY_DEF __weakf weakf | |
279 | @%:@elif defined(HAVE_SYS_WEAK_ALIAS_CRIDUPLICATE) | |
280 | @%:@pragma _CRI duplicate weakf as __weakf | |
281 | @%:@endif | |
282 | void __weakf(int c) {} | |
283 | @%:@ifdef HAVE_SYS_WEAK_ALIAS_ATTRIBUTE | |
284 | void weakf(int c) __attribute((weak, alias("__weakf"))); | |
285 | @%:@endif | |
286 | _ACEOF | |
287 | # And conftest2 contains our main routine that calls it | |
288 | cat >conftest2.$ac_ext <<_ACEOF | |
289 | /* confdefs.h. */ | |
290 | _ACEOF | |
291 | cat confdefs.h >> conftest2.$ac_ext | |
292 | cat >>conftest2.$ac_ext <<_ACEOF | |
293 | /* end confdefs.h. */ | |
294 | ||
295 | extern void weakf(int c); | |
296 | int | |
297 | main () | |
298 | { | |
299 | weakf(0); | |
300 | return 0; | |
301 | } | |
302 | _ACEOF | |
303 | # We must remove the object files (if any) ourselves... | |
304 | rm -f conftest2.$ac_objext conftest$ac_exeext | |
305 | ||
306 | # Change ac_link to compile *2* files together | |
307 | save_aclink=$ac_link | |
308 | ac_link=`echo "$ac_link" | \ | |
309 | sed -e 's/conftest\(\.\$ac_ext\)/conftest1\1 conftest2\1/'` | |
310 | dnl Substitute our own routine for logging the conftest | |
311 | m4_pushdef([_AC_MSG_LOG_CONFTEST], | |
312 | [echo "$as_me: failed program was:" >&AS_MESSAGE_LOG_FD | |
313 | echo ">>> conftest1.$ac_ext" >&AS_MESSAGE_LOG_FD | |
314 | sed "s/^/| /" conftest1.$ac_ext >&AS_MESSAGE_LOG_FD | |
315 | echo ">>> conftest2.$ac_ext" >&AS_MESSAGE_LOG_FD | |
316 | sed "s/^/| /" conftest2.$ac_ext >&AS_MESSAGE_LOG_FD | |
317 | ])dnl | |
318 | # Since we created the files ourselves, don't use SOURCE argument | |
319 | AC_LINK_IFELSE(, [ax_cv_sys_weak_alias_crossfile=yes], | |
320 | [ax_cv_sys_weak_alias_crossfile=no]) | |
321 | dnl Restore _AC_MSG_LOG_CONFTEST | |
322 | m4_popdef([_AC_MSG_LOG_CONFTEST])dnl | |
323 | # Restore ac_link | |
324 | ac_link=$save_aclink | |
325 | ||
326 | # We must remove the object files (if any) and C files ourselves... | |
327 | rm -f conftest1.$ac_ext conftest2.$ac_ext \ | |
328 | conftest1.$ac_objext conftest2.$ac_objext | |
329 | ]) | |
330 | ]) | |
331 | ||
332 | # What were the results of the test? | |
333 | AS_IF([test $ax_cv_sys_weak_alias_crossfile = yes], [ | |
334 | AC_DEFINE([HAVE_SYS_WEAK_ALIAS_CROSSFILE], 1, | |
335 | [Define this if weak aliases in other files are honored]) | |
336 | ]) | |
337 | ]) |