]>
Commit | Line | Data |
---|---|---|
c0c3707f CB |
1 | # Prefer GNU C11 and C++11 to earlier versions. -*- coding: utf-8 -*- |
2 | ||
3 | # This implementation is taken from GNU Autoconf lib/autoconf/c.m4 | |
4 | # commit 017d5ddd82854911f0119691d91ea8a1438824d6 | |
5 | # dated Sun Apr 3 13:57:17 2016 -0700 | |
6 | # This implementation will be obsolete once we can assume Autoconf 2.70 | |
7 | # or later is installed everywhere a Gnulib program might be developed. | |
8 | ||
9 | ||
10 | # Copyright (C) 2001-2019 Free Software Foundation, Inc. | |
11 | ||
12 | # This program is free software; you can redistribute it and/or modify | |
13 | # it under the terms of the GNU General Public License as published by | |
14 | # the Free Software Foundation, either version 3 of the License, or | |
15 | # (at your option) any later version. | |
16 | # | |
17 | # This program is distributed in the hope that it will be useful, | |
18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | # GNU General Public License for more details. | |
21 | # | |
22 | # You should have received a copy of the GNU General Public License | |
23 | # along with this program. If not, see <https://www.gnu.org/licenses/>. | |
24 | ||
25 | # Written by David MacKenzie, with help from | |
26 | # Akim Demaille, Paul Eggert, | |
27 | # François Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor, | |
28 | # Roland McGrath, Noah Friedman, david d zuhn, and many others. | |
29 | ||
30 | ||
31 | # AC_PROG_CC([COMPILER ...]) | |
32 | # -------------------------- | |
33 | # COMPILER ... is a space separated list of C compilers to search for. | |
34 | # This just gives the user an opportunity to specify an alternative | |
35 | # search list for the C compiler. | |
36 | AC_DEFUN_ONCE([AC_PROG_CC], | |
37 | [AC_LANG_PUSH(C)dnl | |
38 | AC_ARG_VAR([CC], [C compiler command])dnl | |
39 | AC_ARG_VAR([CFLAGS], [C compiler flags])dnl | |
40 | _AC_ARG_VAR_LDFLAGS()dnl | |
41 | _AC_ARG_VAR_LIBS()dnl | |
42 | _AC_ARG_VAR_CPPFLAGS()dnl | |
43 | m4_ifval([$1], | |
44 | [AC_CHECK_TOOLS(CC, [$1])], | |
45 | [AC_CHECK_TOOL(CC, gcc) | |
46 | if test -z "$CC"; then | |
47 | dnl Here we want: | |
48 | dnl AC_CHECK_TOOL(CC, cc) | |
49 | dnl but without the check for a tool without the prefix. | |
50 | dnl Until the check is removed from there, copy the code: | |
51 | if test -n "$ac_tool_prefix"; then | |
52 | AC_CHECK_PROG(CC, [${ac_tool_prefix}cc], [${ac_tool_prefix}cc]) | |
53 | fi | |
54 | fi | |
55 | if test -z "$CC"; then | |
56 | AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc) | |
57 | fi | |
58 | if test -z "$CC"; then | |
59 | AC_CHECK_TOOLS(CC, cl.exe) | |
60 | fi | |
61 | if test -z "$CC"; then | |
62 | AC_CHECK_TOOL(CC, clang) | |
63 | fi | |
64 | ]) | |
65 | ||
66 | test -z "$CC" && AC_MSG_FAILURE([no acceptable C compiler found in \$PATH]) | |
67 | ||
68 | # Provide some information about the compiler. | |
69 | _AS_ECHO_LOG([checking for _AC_LANG compiler version]) | |
70 | set X $ac_compile | |
71 | ac_compiler=$[2] | |
72 | for ac_option in --version -v -V -qversion -version; do | |
73 | m4_ifdef([_AC_DO_LIMIT],[_AC_DO_LIMIT],[_AC_DO])([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD]) | |
74 | done | |
75 | ||
76 | m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl | |
77 | m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl | |
78 | _AC_LANG_COMPILER_GNU | |
79 | if test $ac_compiler_gnu = yes; then | |
80 | GCC=yes | |
81 | else | |
82 | GCC= | |
83 | fi | |
84 | _AC_PROG_CC_G | |
85 | dnl | |
86 | dnl Set ac_prog_cc_stdc to the supported C version. | |
87 | dnl Also set the documented variable ac_cv_prog_cc_stdc; | |
88 | dnl its name was chosen when it was cached, but it is no longer cached. | |
89 | _AC_PROG_CC_C11([ac_prog_cc_stdc=c11 | |
90 | ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11], | |
91 | [_AC_PROG_CC_C99([ac_prog_cc_stdc=c99 | |
92 | ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99], | |
93 | [_AC_PROG_CC_C89([ac_prog_cc_stdc=c89 | |
94 | ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89], | |
95 | [ac_prog_cc_stdc=no | |
96 | ac_cv_prog_cc_stdc=no])])]) | |
97 | dnl | |
98 | AC_LANG_POP(C)dnl | |
99 | ])# AC_PROG_CC | |
100 | ||
101 | ||
102 | ||
103 | # AC_PROG_CXX([LIST-OF-COMPILERS]) | |
104 | # -------------------------------- | |
105 | # LIST-OF-COMPILERS is a space separated list of C++ compilers to search | |
106 | # for (if not specified, a default list is used). This just gives the | |
107 | # user an opportunity to specify an alternative search list for the C++ | |
108 | # compiler. | |
109 | # aCC HP-UX C++ compiler much better than `CC', so test before. | |
110 | # FCC Fujitsu C++ compiler | |
111 | # KCC KAI C++ compiler | |
112 | # RCC Rational C++ | |
113 | # xlC_r AIX C Set++ (with support for reentrant code) | |
114 | # xlC AIX C Set++ | |
115 | AC_DEFUN([AC_PROG_CXX], | |
116 | [AC_LANG_PUSH(C++)dnl | |
117 | AC_ARG_VAR([CXX], [C++ compiler command])dnl | |
118 | AC_ARG_VAR([CXXFLAGS], [C++ compiler flags])dnl | |
119 | _AC_ARG_VAR_LDFLAGS()dnl | |
120 | _AC_ARG_VAR_LIBS()dnl | |
121 | _AC_ARG_VAR_CPPFLAGS()dnl | |
122 | _AC_ARG_VAR_PRECIOUS([CCC])dnl | |
123 | if test -z "$CXX"; then | |
124 | if test -n "$CCC"; then | |
125 | CXX=$CCC | |
126 | else | |
127 | AC_CHECK_TOOLS(CXX, | |
128 | [m4_default([$1], | |
129 | [g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++])], | |
130 | g++) | |
131 | fi | |
132 | fi | |
133 | # Provide some information about the compiler. | |
134 | _AS_ECHO_LOG([checking for _AC_LANG compiler version]) | |
135 | set X $ac_compile | |
136 | ac_compiler=$[2] | |
137 | for ac_option in --version -v -V -qversion; do | |
138 | m4_ifdef([_AC_DO_LIMIT],[_AC_DO_LIMIT],[_AC_DO])([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD]) | |
139 | done | |
140 | ||
141 | m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl | |
142 | m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl | |
143 | _AC_LANG_COMPILER_GNU | |
144 | if test $ac_compiler_gnu = yes; then | |
145 | GXX=yes | |
146 | else | |
147 | GXX= | |
148 | fi | |
149 | _AC_PROG_CXX_G | |
150 | _AC_PROG_CXX_CXX11([ac_prog_cxx_stdcxx=cxx11 | |
151 | ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 | |
152 | ac_cv_prog_cxx_cxx98=$ac_cv_prog_cxx_cxx11], | |
153 | [_AC_PROG_CXX_CXX98([ac_prog_cxx_stdcxx=cxx98 | |
154 | ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98], | |
155 | [ac_prog_cxx_stdcxx=no | |
156 | ac_cv_prog_cxx_stdcxx=no])]) | |
157 | AC_LANG_POP(C++)dnl | |
158 | ])# AC_PROG_CXX | |
159 | ||
160 | ||
161 | # _AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST, | |
162 | # ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE) | |
163 | # -------------------------------------------------------------- | |
164 | # Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99') | |
165 | # by trying to compile a program of TEST-PROLOGUE and TEST-BODY. If this fails, | |
166 | # try again with each compiler option in the space-separated OPTION-LIST; if one | |
167 | # helps, append it to CC. If eventually successful, run ACTION-IF-AVAILABLE, | |
168 | # else ACTION-IF-UNAVAILABLE. | |
169 | AC_DEFUN([_AC_C_STD_TRY], | |
170 | [AC_MSG_CHECKING([for $CC option to enable ]m4_translit($1, [c], [C])[ features]) | |
171 | AC_CACHE_VAL(ac_cv_prog_cc_$1, | |
172 | [ac_cv_prog_cc_$1=no | |
173 | ac_save_CC=$CC | |
174 | AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])]) | |
175 | for ac_arg in '' $4 | |
176 | do | |
177 | CC="$ac_save_CC $ac_arg" | |
178 | _AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg]) | |
179 | test "x$ac_cv_prog_cc_$1" != "xno" && break | |
180 | done | |
181 | rm -f conftest.$ac_ext | |
182 | CC=$ac_save_CC | |
183 | ])# AC_CACHE_VAL | |
184 | ac_prog_cc_stdc_options= | |
185 | case "x$ac_cv_prog_cc_$1" in | |
186 | x) | |
187 | AC_MSG_RESULT([none needed]) ;; | |
188 | xno) | |
189 | AC_MSG_RESULT([unsupported]) ;; | |
190 | *) | |
191 | ac_prog_cc_stdc_options=" $ac_cv_prog_cc_$1" | |
192 | CC=$CC$ac_prog_cc_stdc_options | |
193 | AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;; | |
194 | esac | |
195 | AS_IF([test "x$ac_cv_prog_cc_$1" != xno], [$5], [$6]) | |
196 | ])# _AC_C_STD_TRY | |
197 | ||
198 | # _AC_C_C99_TEST_HEADER | |
199 | # --------------------- | |
200 | # A C header suitable for testing for C99. | |
201 | AC_DEFUN([_AC_C_C99_TEST_HEADER], | |
202 | [[#include <stdarg.h> | |
203 | #include <stdbool.h> | |
204 | #include <stddef.h> | |
205 | #include <stdlib.h> | |
206 | #include <wchar.h> | |
207 | #include <stdio.h> | |
208 | ||
209 | // Check varargs macros. These examples are taken from C99 6.10.3.5. | |
210 | #define debug(...) fprintf (stderr, __VA_ARGS__) | |
211 | #define showlist(...) puts (#__VA_ARGS__) | |
212 | #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) | |
213 | static void | |
214 | test_varargs_macros (void) | |
215 | { | |
216 | int x = 1234; | |
217 | int y = 5678; | |
218 | debug ("Flag"); | |
219 | debug ("X = %d\n", x); | |
220 | showlist (The first, second, and third items.); | |
221 | report (x>y, "x is %d but y is %d", x, y); | |
222 | } | |
223 | ||
224 | // Check long long types. | |
225 | #define BIG64 18446744073709551615ull | |
226 | #define BIG32 4294967295ul | |
227 | #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) | |
228 | #if !BIG_OK | |
229 | your preprocessor is broken; | |
230 | #endif | |
231 | #if BIG_OK | |
232 | #else | |
233 | your preprocessor is broken; | |
234 | #endif | |
235 | static long long int bignum = -9223372036854775807LL; | |
236 | static unsigned long long int ubignum = BIG64; | |
237 | ||
238 | struct incomplete_array | |
239 | { | |
240 | int datasize; | |
241 | double data[]; | |
242 | }; | |
243 | ||
244 | struct named_init { | |
245 | int number; | |
246 | const wchar_t *name; | |
247 | double average; | |
248 | }; | |
249 | ||
250 | typedef const char *ccp; | |
251 | ||
252 | static inline int | |
253 | test_restrict (ccp restrict text) | |
254 | { | |
255 | // See if C++-style comments work. | |
256 | // Iterate through items via the restricted pointer. | |
257 | // Also check for declarations in for loops. | |
258 | for (unsigned int i = 0; *(text+i) != '\0'; ++i) | |
259 | continue; | |
260 | return 0; | |
261 | } | |
262 | ||
263 | // Check varargs and va_copy. | |
264 | static bool | |
265 | test_varargs (const char *format, ...) | |
266 | { | |
267 | va_list args; | |
268 | va_start (args, format); | |
269 | va_list args_copy; | |
270 | va_copy (args_copy, args); | |
271 | ||
272 | const char *str = ""; | |
273 | int number = 0; | |
274 | float fnumber = 0; | |
275 | ||
276 | while (*format) | |
277 | { | |
278 | switch (*format++) | |
279 | { | |
280 | case 's': // string | |
281 | str = va_arg (args_copy, const char *); | |
282 | break; | |
283 | case 'd': // int | |
284 | number = va_arg (args_copy, int); | |
285 | break; | |
286 | case 'f': // float | |
287 | fnumber = va_arg (args_copy, double); | |
288 | break; | |
289 | default: | |
290 | break; | |
291 | } | |
292 | } | |
293 | va_end (args_copy); | |
294 | va_end (args); | |
295 | ||
296 | return *str && number && fnumber; | |
297 | }]])# _AC_C_C99_TEST_HEADER | |
298 | ||
299 | # _AC_C_C99_TEST_BODY | |
300 | # ------------------- | |
301 | # A C body suitable for testing for C99, assuming the corresponding header. | |
302 | AC_DEFUN([_AC_C_C99_TEST_BODY], | |
303 | [[ | |
304 | // Check bool. | |
305 | _Bool success = false; | |
306 | ||
307 | // Check restrict. | |
308 | if (test_restrict ("String literal") == 0) | |
309 | success = true; | |
310 | char *restrict newvar = "Another string"; | |
311 | ||
312 | // Check varargs. | |
313 | success &= test_varargs ("s, d' f .", "string", 65, 34.234); | |
314 | test_varargs_macros (); | |
315 | ||
316 | // Check flexible array members. | |
317 | struct incomplete_array *ia = | |
318 | malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); | |
319 | ia->datasize = 10; | |
320 | for (int i = 0; i < ia->datasize; ++i) | |
321 | ia->data[i] = i * 1.234; | |
322 | ||
323 | // Check named initializers. | |
324 | struct named_init ni = { | |
325 | .number = 34, | |
326 | .name = L"Test wide string", | |
327 | .average = 543.34343, | |
328 | }; | |
329 | ||
330 | ni.number = 58; | |
331 | ||
332 | int dynamic_array[ni.number]; | |
333 | dynamic_array[ni.number - 1] = 543; | |
334 | ||
335 | // work around unused variable warnings | |
336 | return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' | |
337 | || dynamic_array[ni.number - 1] != 543); | |
338 | ]]) | |
339 | ||
340 | # _AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) | |
341 | # ---------------------------------------------------------------- | |
342 | # If the C compiler is not in ISO C99 mode by default, try to add an | |
343 | # option to output variable CC to make it so. This macro tries | |
344 | # various options that select ISO C99 on some system or another. It | |
345 | # considers the compiler to be in ISO C99 mode if it handles _Bool, | |
346 | # // comments, flexible array members, inline, long long int, mixed | |
347 | # code and declarations, named initialization of structs, restrict, | |
348 | # va_copy, varargs macros, variable declarations in for loops and | |
349 | # variable length arrays. | |
350 | AC_DEFUN([_AC_PROG_CC_C99], | |
351 | [_AC_C_STD_TRY([c99], | |
352 | [_AC_C_C99_TEST_HEADER], | |
353 | [_AC_C_C99_TEST_BODY], | |
354 | dnl Try | |
355 | dnl GCC -std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999) | |
356 | dnl IBM XL C -qlanglvl=extc1x (V12.1; does not pass C11 test) | |
357 | dnl IBM XL C -qlanglvl=extc99 | |
358 | dnl (pre-V12.1; unused restrictive mode: -qlanglvl=stdc99) | |
359 | dnl HP cc -AC99 | |
360 | dnl Intel ICC -std=c99, -c99 (deprecated) | |
361 | dnl IRIX -c99 | |
362 | dnl Solaris -D_STDC_C99= | |
363 | dnl cc's -xc99 option uses linker magic to define the external | |
364 | dnl symbol __xpg4 as if by "int __xpg4 = 1;", which enables C99 | |
365 | dnl behavior for C library functions. This is not wanted here, | |
366 | dnl because it means that a single module compiled with -xc99 | |
367 | dnl alters C runtime behavior for the entire program, not for | |
368 | dnl just the module. Instead, define the (private) symbol | |
369 | dnl _STDC_C99, which suppresses a bogus failure in <stdbool.h>. | |
370 | dnl The resulting compiler passes the test case here, and that's | |
371 | dnl good enough. For more, please see the thread starting at: | |
372 | dnl https://lists.gnu.org/r/autoconf/2010-12/msg00059.html | |
373 | dnl Tru64 -c99 | |
374 | dnl with extended modes being tried first. | |
375 | [[-std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc1x -qlanglvl=extc99]], [$1], [$2])[]dnl | |
376 | ])# _AC_PROG_CC_C99 | |
377 | ||
378 | ||
379 | # _AC_PROG_CC_C11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) | |
380 | # ---------------------------------------------------------------- | |
381 | # If the C compiler is not in ISO C11 mode by default, try to add an | |
382 | # option to output variable CC to make it so. This macro tries | |
383 | # various options that select ISO C11 on some system or another. It | |
384 | # considers the compiler to be in ISO C11 mode if it handles _Alignas, | |
385 | # _Alignof, _Noreturn, _Static_assert, UTF-8 string literals, | |
386 | # duplicate typedefs, and anonymous structures and unions. | |
387 | AC_DEFUN([_AC_PROG_CC_C11], | |
388 | [_AC_C_STD_TRY([c11], | |
389 | [_AC_C_C99_TEST_HEADER[ | |
390 | // Check _Alignas. | |
391 | char _Alignas (double) aligned_as_double; | |
392 | char _Alignas (0) no_special_alignment; | |
393 | extern char aligned_as_int; | |
394 | char _Alignas (0) _Alignas (int) aligned_as_int; | |
395 | ||
396 | // Check _Alignof. | |
397 | enum | |
398 | { | |
399 | int_alignment = _Alignof (int), | |
400 | int_array_alignment = _Alignof (int[100]), | |
401 | char_alignment = _Alignof (char) | |
402 | }; | |
403 | _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); | |
404 | ||
405 | // Check _Noreturn. | |
406 | int _Noreturn does_not_return (void) { for (;;) continue; } | |
407 | ||
408 | // Check _Static_assert. | |
409 | struct test_static_assert | |
410 | { | |
411 | int x; | |
412 | _Static_assert (sizeof (int) <= sizeof (long int), | |
413 | "_Static_assert does not work in struct"); | |
414 | long int y; | |
415 | }; | |
416 | ||
417 | // Check UTF-8 literals. | |
418 | #define u8 syntax error! | |
419 | char const utf8_literal[] = u8"happens to be ASCII" "another string"; | |
420 | ||
421 | // Check duplicate typedefs. | |
422 | typedef long *long_ptr; | |
423 | typedef long int *long_ptr; | |
424 | typedef long_ptr long_ptr; | |
425 | ||
426 | // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. | |
427 | struct anonymous | |
428 | { | |
429 | union { | |
430 | struct { int i; int j; }; | |
431 | struct { int k; long int l; } w; | |
432 | }; | |
433 | int m; | |
434 | } v1; | |
435 | ]], | |
436 | [_AC_C_C99_TEST_BODY[ | |
437 | v1.i = 2; | |
438 | v1.w.k = 5; | |
439 | _Static_assert ((offsetof (struct anonymous, i) | |
440 | == offsetof (struct anonymous, w.k)), | |
441 | "Anonymous union alignment botch"); | |
442 | ]], | |
443 | dnl Try | |
444 | dnl GCC -std=gnu11 (unused restrictive mode: -std=c11) | |
445 | dnl with extended modes being tried first. | |
446 | dnl | |
447 | dnl Do not try -qlanglvl=extc1x, because IBM XL C V12.1 (the latest version as | |
448 | dnl of September 2012) does not pass the C11 test. For now, try extc1x when | |
449 | dnl compiling the C99 test instead, since it enables _Static_assert and | |
450 | dnl _Noreturn, which is a win. If -qlanglvl=extc11 or -qlanglvl=extc1x passes | |
451 | dnl the C11 test in some future version of IBM XL C, we'll add it here, | |
452 | dnl preferably extc11. | |
453 | [[-std=gnu11]], [$1], [$2])[]dnl | |
454 | ])# _AC_PROG_CC_C11 | |
455 | ||
456 | ||
457 | # AC_PROG_CC_C89 | |
458 | # -------------- | |
459 | # Do not use AU_ALIAS here and in AC_PROG_CC_C99 and AC_PROG_CC_STDC, | |
460 | # as that'd be incompatible with how Automake redefines AC_PROG_CC. See | |
461 | # <https://lists.gnu.org/r/autoconf/2012-10/msg00048.html>. | |
462 | AU_DEFUN([AC_PROG_CC_C89], | |
463 | [AC_REQUIRE([AC_PROG_CC])], | |
464 | [$0 is obsolete; use AC_PROG_CC] | |
465 | ) | |
466 | ||
467 | # AC_PROG_CC_C99 | |
468 | # -------------- | |
469 | AU_DEFUN([AC_PROG_CC_C99], | |
470 | [AC_REQUIRE([AC_PROG_CC])], | |
471 | [$0 is obsolete; use AC_PROG_CC] | |
472 | ) | |
473 | ||
474 | # AC_PROG_CC_STDC | |
475 | # --------------- | |
476 | AU_DEFUN([AC_PROG_CC_STDC], | |
477 | [AC_REQUIRE([AC_PROG_CC])], | |
478 | [$0 is obsolete; use AC_PROG_CC] | |
479 | ) | |
480 | ||
481 | ||
482 | # AC_C_PROTOTYPES | |
483 | # --------------- | |
484 | # Check if the C compiler supports prototypes, included if it needs | |
485 | # options. | |
486 | AC_DEFUN([AC_C_PROTOTYPES], | |
487 | [AC_REQUIRE([AC_PROG_CC])dnl | |
488 | if test "$ac_prog_cc_stdc" != no; then | |
489 | AC_DEFINE(PROTOTYPES, 1, | |
490 | [Define to 1 if the C compiler supports function prototypes.]) | |
491 | AC_DEFINE(__PROTOTYPES, 1, | |
492 | [Define like PROTOTYPES; this can be used by system headers.]) | |
493 | fi | |
494 | ])# AC_C_PROTOTYPES | |
495 | ||
496 | ||
497 | # _AC_CXX_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST, | |
498 | # ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE) | |
499 | # ---------------------------------------------------------------- | |
500 | # Check whether the C++ compiler accepts features of STANDARD (e.g | |
501 | # `cxx98', `cxx11') by trying to compile a program of TEST-PROLOGUE | |
502 | # and TEST-BODY. If this fails, try again with each compiler option | |
503 | # in the space-separated OPTION-LIST; if one helps, append it to CXX. | |
504 | # If eventually successful, run ACTION-IF-AVAILABLE, else | |
505 | # ACTION-IF-UNAVAILABLE. | |
506 | AC_DEFUN([_AC_CXX_STD_TRY], | |
507 | [AC_MSG_CHECKING([for $CXX option to enable ]m4_translit(m4_translit($1, [x], [+]), [a-z], [A-Z])[ features]) | |
508 | AC_LANG_PUSH(C++)dnl | |
509 | AC_CACHE_VAL(ac_cv_prog_cxx_$1, | |
510 | [ac_cv_prog_cxx_$1=no | |
511 | ac_save_CXX=$CXX | |
512 | AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])]) | |
513 | for ac_arg in '' $4 | |
514 | do | |
515 | CXX="$ac_save_CXX $ac_arg" | |
516 | _AC_COMPILE_IFELSE([], [ac_cv_prog_cxx_$1=$ac_arg]) | |
517 | test "x$ac_cv_prog_cxx_$1" != "xno" && break | |
518 | done | |
519 | rm -f conftest.$ac_ext | |
520 | CXX=$ac_save_CXX | |
521 | ])# AC_CACHE_VAL | |
522 | ac_prog_cxx_stdcxx_options= | |
523 | case "x$ac_cv_prog_cxx_$1" in | |
524 | x) | |
525 | AC_MSG_RESULT([none needed]) ;; | |
526 | xno) | |
527 | AC_MSG_RESULT([unsupported]) ;; | |
528 | *) | |
529 | ac_prog_cxx_stdcxx_options=" $ac_cv_prog_cxx_$1" | |
530 | CXX=$CXX$ac_prog_cxx_stdcxx_options | |
531 | AC_MSG_RESULT([$ac_cv_prog_cxx_$1]) ;; | |
532 | esac | |
533 | AC_LANG_POP(C++)dnl | |
534 | AS_IF([test "x$ac_cv_prog_cxx_$1" != xno], [$5], [$6]) | |
535 | ])# _AC_CXX_STD_TRY | |
536 | ||
537 | # _AC_CXX_CXX98_TEST_HEADER | |
538 | # ------------------------- | |
539 | # A C++ header suitable for testing for CXX98. | |
540 | AC_DEFUN([_AC_CXX_CXX98_TEST_HEADER], | |
541 | [[ | |
542 | #include <algorithm> | |
543 | #include <cstdlib> | |
544 | #include <fstream> | |
545 | #include <iomanip> | |
546 | #include <iostream> | |
547 | #include <list> | |
548 | #include <map> | |
549 | #include <set> | |
550 | #include <sstream> | |
551 | #include <stdexcept> | |
552 | #include <string> | |
553 | #include <utility> | |
554 | #include <vector> | |
555 | ||
556 | namespace test { | |
557 | typedef std::vector<std::string> string_vec; | |
558 | typedef std::pair<int,bool> map_value; | |
559 | typedef std::map<std::string,map_value> map_type; | |
560 | typedef std::set<int> set_type; | |
561 | ||
562 | template<typename T> | |
563 | class printer { | |
564 | public: | |
565 | printer(std::ostringstream& os): os(os) {} | |
566 | void operator() (T elem) { os << elem << std::endl; } | |
567 | private: | |
568 | std::ostringstream& os; | |
569 | }; | |
570 | } | |
571 | ]])# _AC_CXX_CXX98_TEST_HEADER | |
572 | ||
573 | # _AC_CXX_CXX98_TEST_BODY | |
574 | # ----------------------- | |
575 | # A C++ body suitable for testing for CXX98, assuming the corresponding header. | |
576 | AC_DEFUN([_AC_CXX_CXX98_TEST_BODY], | |
577 | [[ | |
578 | ||
579 | try { | |
580 | // Basic string. | |
581 | std::string teststr("ASCII text"); | |
582 | teststr += " string"; | |
583 | ||
584 | // Simple vector. | |
585 | test::string_vec testvec; | |
586 | testvec.push_back(teststr); | |
587 | testvec.push_back("foo"); | |
588 | testvec.push_back("bar"); | |
589 | if (testvec.size() != 3) { | |
590 | throw std::runtime_error("vector size is not 1"); | |
591 | } | |
592 | ||
593 | // Dump vector into stringstream and obtain string. | |
594 | std::ostringstream os; | |
595 | for (test::string_vec::const_iterator i = testvec.begin(); | |
596 | i != testvec.end(); ++i) { | |
597 | if (i + 1 != testvec.end()) { | |
598 | os << teststr << '\n'; | |
599 | } | |
600 | } | |
601 | // Check algorithms work. | |
602 | std::for_each(testvec.begin(), testvec.end(), test::printer<std::string>(os)); | |
603 | std::string os_out = os.str(); | |
604 | ||
605 | // Test pair and map. | |
606 | test::map_type testmap; | |
607 | testmap.insert(std::make_pair(std::string("key"), | |
608 | std::make_pair(53,false))); | |
609 | ||
610 | // Test set. | |
611 | int values[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; | |
612 | test::set_type testset(values, values + sizeof(values)/sizeof(values[0])); | |
613 | std::list<int> testlist(testset.begin(), testset.end()); | |
614 | std::copy(testset.begin(), testset.end(), std::back_inserter(testlist)); | |
615 | } catch (const std::exception& e) { | |
616 | std::cerr << "Caught exception: " << e.what() << std::endl; | |
617 | ||
618 | // Test fstream | |
619 | std::ofstream of("test.txt"); | |
620 | of << "Test ASCII text\n" << std::flush; | |
621 | of << "N= " << std::hex << std::setw(8) << std::left << 534 << std::endl; | |
622 | of.close(); | |
623 | } | |
624 | std::exit(0); | |
625 | ]]) | |
626 | ||
627 | # _AC_CXX_CXX11_TEST_HEADER | |
628 | # ------------------------- | |
629 | # A C++ header suitable for testing for CXX11. | |
630 | AC_DEFUN([_AC_CXX_CXX11_TEST_HEADER], | |
631 | [[ | |
632 | #include <deque> | |
633 | #include <functional> | |
634 | #include <memory> | |
635 | #include <tuple> | |
636 | #include <array> | |
637 | #include <regex> | |
638 | #include <iostream> | |
639 | ||
640 | namespace cxx11test | |
641 | { | |
642 | typedef std::shared_ptr<std::string> sptr; | |
643 | typedef std::weak_ptr<std::string> wptr; | |
644 | ||
645 | typedef std::tuple<std::string,int,double> tp; | |
646 | typedef std::array<int, 20> int_array; | |
647 | ||
648 | constexpr int get_val() { return 20; } | |
649 | ||
650 | struct testinit | |
651 | { | |
652 | int i; | |
653 | double d; | |
654 | }; | |
655 | ||
656 | class delegate { | |
657 | public: | |
658 | delegate(int n) : n(n) {} | |
659 | delegate(): delegate(2354) {} | |
660 | ||
661 | virtual int getval() { return this->n; }; | |
662 | protected: | |
663 | int n; | |
664 | }; | |
665 | ||
666 | class overridden : public delegate { | |
667 | public: | |
668 | overridden(int n): delegate(n) {} | |
669 | virtual int getval() override final { return this->n * 2; } | |
670 | }; | |
671 | ||
672 | class nocopy { | |
673 | public: | |
674 | nocopy(int i): i(i) {} | |
675 | nocopy() = default; | |
676 | nocopy(const nocopy&) = delete; | |
677 | nocopy & operator=(const nocopy&) = delete; | |
678 | private: | |
679 | int i; | |
680 | }; | |
681 | } | |
682 | ]])# _AC_CXX_CXX11_TEST_HEADER | |
683 | ||
684 | # _AC_CXX_CXX11_TEST_BODY | |
685 | # ----------------------- | |
686 | # A C++ body suitable for testing for CXX11, assuming the corresponding header. | |
687 | AC_DEFUN([_AC_CXX_CXX11_TEST_BODY], | |
688 | [[ | |
689 | { | |
690 | // Test auto and decltype | |
691 | std::deque<int> d; | |
692 | d.push_front(43); | |
693 | d.push_front(484); | |
694 | d.push_front(3); | |
695 | d.push_front(844); | |
696 | int total = 0; | |
697 | for (auto i = d.begin(); i != d.end(); ++i) { total += *i; } | |
698 | ||
699 | auto a1 = 6538; | |
700 | auto a2 = 48573953.4; | |
701 | auto a3 = "String literal"; | |
702 | ||
703 | decltype(a2) a4 = 34895.034; | |
704 | } | |
705 | { | |
706 | // Test constexpr | |
707 | short sa[cxx11test::get_val()] = { 0 }; | |
708 | } | |
709 | { | |
710 | // Test initializer lists | |
711 | cxx11test::testinit il = { 4323, 435234.23544 }; | |
712 | } | |
713 | { | |
714 | // Test range-based for and lambda | |
715 | cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; | |
716 | for (int &x : array) { x += 23; } | |
717 | std::for_each(array.begin(), array.end(), [](int v1){ std::cout << v1; }); | |
718 | } | |
719 | { | |
720 | using cxx11test::sptr; | |
721 | using cxx11test::wptr; | |
722 | ||
723 | sptr sp(new std::string("ASCII string")); | |
724 | wptr wp(sp); | |
725 | sptr sp2(wp); | |
726 | } | |
727 | { | |
728 | cxx11test::tp tuple("test", 54, 45.53434); | |
729 | double d = std::get<2>(tuple); | |
730 | std::string s; | |
731 | int i; | |
732 | std::tie(s,i,d) = tuple; | |
733 | } | |
734 | { | |
735 | static std::regex filename_regex("^_?([a-z0-9_.]+-)+[a-z0-9]+$"); | |
736 | std::string testmatch("Test if this string matches"); | |
737 | bool match = std::regex_search(testmatch, filename_regex); | |
738 | } | |
739 | { | |
740 | cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; | |
741 | cxx11test::int_array::size_type size = array.size(); | |
742 | } | |
743 | { | |
744 | // Test constructor delegation | |
745 | cxx11test::delegate d1; | |
746 | cxx11test::delegate d2(); | |
747 | cxx11test::delegate d3(45); | |
748 | } | |
749 | { | |
750 | // Test override and final | |
751 | cxx11test::overridden o1(55464); | |
752 | } | |
753 | { | |
754 | // Test nullptr | |
755 | char *c = nullptr; | |
756 | } | |
757 | { | |
758 | // Test template brackets | |
759 | std::vector<std::pair<int,char*>> v1; | |
760 | } | |
761 | { | |
762 | // Unicode literals | |
763 | char const *utf8 = u8"UTF-8 string \u2500"; | |
764 | char16_t const *utf16 = u"UTF-8 string \u2500"; | |
765 | char32_t const *utf32 = U"UTF-32 string \u2500"; | |
766 | } | |
767 | ]]) | |
768 | ||
769 | # _AC_PROG_CXX_CXX98 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) | |
770 | # ------------------------------------------------------------------- | |
771 | ||
772 | # If the C++ compiler is not in ISO C++98 mode by default, try to add | |
773 | # an option to output variable CXX to make it so. This macro tries | |
774 | # various options that select ISO C++98 on some system or another. It | |
775 | # considers the compiler to be in ISO C++98 mode if it handles basic | |
776 | # features of the std namespace including: string, containers (list, | |
777 | # map, set, vector), streams (fstreams, iostreams, stringstreams, | |
778 | # iomanip), pair, exceptions and algorithms. | |
779 | ||
780 | ||
781 | AC_DEFUN([_AC_PROG_CXX_CXX98], | |
782 | [_AC_CXX_STD_TRY([cxx98], | |
783 | [_AC_CXX_CXX98_TEST_HEADER], | |
784 | [_AC_CXX_CXX98_TEST_BODY], | |
785 | dnl Try | |
786 | dnl GCC -std=gnu++98 (unused restrictive mode: -std=c++98) | |
787 | dnl IBM XL C -qlanglvl=extended | |
788 | dnl HP aC++ -AA | |
789 | dnl Intel ICC -std=gnu++98 | |
790 | dnl Solaris N/A (default) | |
791 | dnl Tru64 N/A (default, but -std gnu could be used) | |
792 | dnl with extended modes being tried first. | |
793 | [[-std=gnu++98 -std=c++98 -qlanglvl=extended -AA]], [$1], [$2])[]dnl | |
794 | ])# _AC_PROG_CXX_CXX98 | |
795 | ||
796 | # _AC_PROG_CXX_CXX11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) | |
797 | # ------------------------------------------------------------------- | |
798 | # If the C++ compiler is not in ISO CXX11 mode by default, try to add | |
799 | # an option to output variable CXX to make it so. This macro tries | |
800 | # various options that select ISO C++11 on some system or another. It | |
801 | # considers the compiler to be in ISO C++11 mode if it handles all the | |
802 | # tests from the C++98 checks, plus the following: Language features | |
803 | # (auto, constexpr, decltype, default/deleted constructors, delegate | |
804 | # constructors, final, initializer lists, lambda functions, nullptr, | |
805 | # override, range-based for loops, template brackets without spaces, | |
806 | # unicode literals) and library features (array, memory (shared_ptr, | |
807 | # weak_ptr), regex and tuple types). | |
808 | AC_DEFUN([_AC_PROG_CXX_CXX11], | |
809 | [_AC_CXX_STD_TRY([cxx11], | |
810 | [_AC_CXX_CXX11_TEST_HEADER | |
811 | _AC_CXX_CXX98_TEST_HEADER], | |
812 | [_AC_CXX_CXX11_TEST_BODY | |
813 | _AC_CXX_CXX98_TEST_BODY], | |
814 | dnl Try | |
815 | dnl GCC -std=gnu++11 (unused restrictive mode: -std=c++11) [and 0x variants] | |
816 | dnl IBM XL C -qlanglvl=extended0x | |
817 | dnl (pre-V12.1; unused restrictive mode: -qlanglvl=stdcxx11) | |
818 | dnl HP aC++ -AA | |
819 | dnl Intel ICC -std=c++11 -std=c++0x | |
820 | dnl Solaris N/A (no support) | |
821 | dnl Tru64 N/A (no support) | |
822 | dnl with extended modes being tried first. | |
823 | [[-std=gnu++11 -std=c++11 -std=gnu++0x -std=c++0x -qlanglvl=extended0x -AA]], [$1], [$2])[]dnl | |
824 | ])# _AC_PROG_CXX_CXX11 |