| 1 | #!/bin/sh |
| 2 | |
| 3 | # Generate the cflags script, which is used to determine what cflags |
| 4 | # to pass to the compiler for compiling the core perl. |
| 5 | # |
| 6 | # This does NOT affect the XS compilation (ext, dist, cpan) |
| 7 | # since that uses %Config values directly. |
| 8 | # |
| 9 | # For example, since -Wall adds -Wunused-*, a bare -Wall (without |
| 10 | # amending that with -Wno-unused-..., or with the PERL_UNUSED_...) |
| 11 | # would be too much for XS code because there are too many generated |
| 12 | # but often unused things. |
| 13 | # |
| 14 | # We create a temporary test C program and repeatedly compile it with |
| 15 | # various candidate flags, and from the compiler output, determine what |
| 16 | # flags are supported. |
| 17 | # |
| 18 | # From this we initialise the following variables in the cflags script: |
| 19 | # |
| 20 | # $myccflags (possibly edited version of $Config{ccflags}) |
| 21 | # $warn |
| 22 | # $stdflags |
| 23 | # $extra |
| 24 | # $_exe |
| 25 | |
| 26 | case $PERL_CONFIG_SH in |
| 27 | '') |
| 28 | if test -f config.sh; then TOP=.; |
| 29 | elif test -f ../config.sh; then TOP=..; |
| 30 | elif test -f ../../config.sh; then TOP=../..; |
| 31 | elif test -f ../../../config.sh; then TOP=../../..; |
| 32 | elif test -f ../../../../config.sh; then TOP=../../../..; |
| 33 | else |
| 34 | echo "Can't find config.sh."; exit 1 |
| 35 | fi |
| 36 | . $TOP/config.sh |
| 37 | ;; |
| 38 | esac |
| 39 | # This forces SH files to create target in same directory as SH file. |
| 40 | # This is so that make depend always knows where to find SH derivatives. |
| 41 | case "$0" in |
| 42 | */*) cd `expr X$0 : 'X\(.*\)/'` ;; |
| 43 | esac |
| 44 | |
| 45 | if test -f config_h.SH -a ! -f config.h; then |
| 46 | . ./config_h.SH |
| 47 | CONFIG_H=already-done |
| 48 | fi |
| 49 | |
| 50 | warn='' |
| 51 | |
| 52 | # Add -Wall for the core modules iff gcc and not already -Wall |
| 53 | case "$gccversion" in |
| 54 | '') ;; |
| 55 | Intel*) ;; # The Intel C++ plays gcc on TV but is not really it. |
| 56 | *) case "$ccflags" in |
| 57 | *-Wall*) ;; |
| 58 | *) warn="$warn -Wall" ;; |
| 59 | esac |
| 60 | ;; |
| 61 | esac |
| 62 | |
| 63 | # Create a test source file for testing what options can be fed to |
| 64 | # gcc in this system; include a selection of most common and commonly |
| 65 | # hairy include files. |
| 66 | |
| 67 | cat >_cflags.c <<__EOT__ |
| 68 | #include "EXTERN.h" |
| 69 | #include "perl.h" |
| 70 | /* The stdio.h, errno.h, and setjmp.h should be there in any ANSI C89. */ |
| 71 | #include <stdio.h> |
| 72 | #include <errno.h> |
| 73 | #include <setjmp.h> |
| 74 | /* Just in case the inclusion of perl.h did not |
| 75 | * pull in enough system headers, let's try again. */ |
| 76 | #ifdef I_STDLIB |
| 77 | #include <stdlib.h> |
| 78 | #endif |
| 79 | #ifdef I_STDDEF |
| 80 | #include <stddef.h> |
| 81 | #endif |
| 82 | #ifdef I_STDARG |
| 83 | #include <stdarg.h> |
| 84 | #endif |
| 85 | #ifdef I_LIMITS |
| 86 | #include <limits.h> |
| 87 | #endif |
| 88 | #ifdef I_DIRENT |
| 89 | #include <dirent.h> |
| 90 | #endif |
| 91 | #ifdef I_UNISTD |
| 92 | #include <unistd.h> |
| 93 | #endif |
| 94 | #ifdef I_SYS_TYPES |
| 95 | #include <sys/types.h> |
| 96 | #endif |
| 97 | #ifdef I_SYS_PARAM |
| 98 | #include <sys/param.h> |
| 99 | #endif |
| 100 | #ifdef I_SYS_RESOURCE |
| 101 | #include <sys/resource.h> |
| 102 | #endif |
| 103 | #ifdef I_SYS_SELECT |
| 104 | #include <sys/select.h> |
| 105 | #endif |
| 106 | #if defined(HAS_SOCKET) && !defined(VMS) && !defined(WIN32) /* See perl.h. */ |
| 107 | #include <sys/socket.h> |
| 108 | #endif |
| 109 | #ifdef I_SYS_STAT |
| 110 | #include <sys/stat.h> |
| 111 | #endif |
| 112 | #ifdef I_SYS_TIME |
| 113 | #include <sys/time.h> |
| 114 | #endif |
| 115 | #ifdef I_SYS_TIMES |
| 116 | #include <sys/times.h> |
| 117 | #endif |
| 118 | #ifdef I_SYS_WAIT |
| 119 | #include <sys/wait.h> |
| 120 | #endif |
| 121 | /* The gcc -ansi can cause a lot of noise in Solaris because of: |
| 122 | /usr/include/sys/resource.h:148: warning: 'struct rlimit64' declared inside parameter list |
| 123 | */ |
| 124 | int main(int argc, char *argv[]) { |
| 125 | |
| 126 | /* Add here test code found to be problematic in some gcc platform. */ |
| 127 | |
| 128 | /* Off_t/off_t is a struct in Solaris with largefiles, and with gcc -ansi |
| 129 | * that struct cannot be compared in some gcc releases with a flat |
| 130 | * integer, such as a STRLEN. */ |
| 131 | |
| 132 | IV iv; |
| 133 | Off_t t0a = 2; |
| 134 | STRLEN t0b = 3; |
| 135 | int t0c = (STRLEN)t0a == t0b; |
| 136 | |
| 137 | printf("%s: %d\n", argv[0], argc); |
| 138 | |
| 139 | /* In FreeBSD 6.2 (and probably other releases too), with -Duse64bitint, |
| 140 | perl will use atoll(3). However, that declaration is hidden in <stdlib.h> |
| 141 | if we force the compiler to use -std=c89 mode. |
| 142 | */ |
| 143 | iv = Atol("42"); |
| 144 | |
| 145 | return (!t0c && (iv == 42)) ? 0 : -1; /* Try to avoid 'unused' warnings. */ |
| 146 | } |
| 147 | __EOT__ |
| 148 | |
| 149 | stdflags='' |
| 150 | |
| 151 | # Further gcc warning options. Build up a list of options that work. |
| 152 | # Note that some problems may only show up with combinations of options, |
| 153 | # e.g. a warning might show up only with -Wall -ansi, not with either |
| 154 | # one individually. |
| 155 | # TODO: Ponder whether to migrate this back to Configure so hints files can |
| 156 | # tweak it. Also, be paranoid about whether results we've deduced in Configure |
| 157 | # (especially about things like long long, which are not in C89) will still be |
| 158 | # valid if we now add flags like -std=c89. |
| 159 | |
| 160 | pedantic='' |
| 161 | case "$gccansipedantic" in |
| 162 | define) pedantic='-pedantic' ;; |
| 163 | esac |
| 164 | |
| 165 | case "$gccversion" in |
| 166 | '') ;; |
| 167 | [12]*) ;; # gcc versions 1 (gasp!) and 2 are not good for this. |
| 168 | Intel*) ;; # # Is that you, Intel C++? |
| 169 | # |
| 170 | # NOTE 1: the -std=c89 without -pedantic is a bit pointless. |
| 171 | # Just -std=c89 means "if there is room for interpretation, |
| 172 | # interpret the C89 way." It does NOT mean "strict C89" on its own. |
| 173 | # You need to add the -pedantic for that. To do this with Configure, |
| 174 | # do -Dgccansipedantic (note that the -ansi is included in any case, |
| 175 | # the option is a bit oddly named, for historical reasons.) |
| 176 | # |
| 177 | # NOTE 2: -pedantic necessitates adding a couple of flags: |
| 178 | # * -PERL_GCC_PEDANTIC so that the perl code can adapt: there's nothing |
| 179 | # added by gcc itself to indicate pedanticness. |
| 180 | # * -Wno-overlength-strings under -DDEBUGGING because quite many of |
| 181 | # the LEAVE_with_name() and assert() calls generate string literals |
| 182 | # longer then the ANSI minimum of 509 bytes. |
| 183 | # |
| 184 | # NOTE 3: the relative order of these options matters: |
| 185 | # -Wextra before -W |
| 186 | # -std=c89 before -ansi |
| 187 | # -pedantic* before -Werror=d-a-s |
| 188 | # |
| 189 | *) for opt in -std=c89 -ansi $pedantic \ |
| 190 | -Werror=declaration-after-statement \ |
| 191 | -Wextra -W \ |
| 192 | -Wc++-compat -Wwrite-strings |
| 193 | do |
| 194 | case " $ccflags " in |
| 195 | *" $opt "*) ;; # Skip if already there. |
| 196 | *) rm -f _cflags$_exe |
| 197 | flags="-DPERL_NO_INLINE_FUNCTIONS $ccflags $warn $stdflags $opt" |
| 198 | case "$opt" in |
| 199 | *-pedantic*) flags="$flags -DPERL_GCC_PEDANTIC" ;; |
| 200 | esac |
| 201 | # echo "opt = $opt, flags = $flags" |
| 202 | cmd="$cc $flags _cflags.c -o _cflags$_exe" |
| 203 | out="`$cmd 2>&1`" |
| 204 | # echo "$cmd --> $out" |
| 205 | case "$out" in |
| 206 | *"unrecognized"*) ;; |
| 207 | *"unknown"*) ;; |
| 208 | *"implicit declaration"*) ;; # Was something useful hidden? |
| 209 | *"Invalid"*) ;; |
| 210 | *"is valid for C"*) ;; |
| 211 | *) if test -x _cflags$_exe |
| 212 | then |
| 213 | case "$opt" in |
| 214 | -std*) |
| 215 | echo "cflags.SH: Adding $opt." |
| 216 | stdflags="$stdflags $opt" |
| 217 | ;; |
| 218 | -ansi) |
| 219 | # -std=c89 is the modern form of -ansi, so add |
| 220 | # -ansi only if -std=c89 is not there already. |
| 221 | case " $stdflags " in |
| 222 | *-std=c89*) ;; |
| 223 | *) |
| 224 | echo "cflags.SH: Adding $opt." |
| 225 | stdflags="$stdflags $opt" |
| 226 | ;; |
| 227 | esac |
| 228 | ;; |
| 229 | *) case "$opt" in |
| 230 | -W) |
| 231 | # -Wextra is the modern form of -W, so add |
| 232 | # -W only if -Wextra is not there already. |
| 233 | case " $warn " in |
| 234 | *-Wextra*) ;; |
| 235 | *) |
| 236 | echo "cflags.SH: Adding $opt." |
| 237 | warn="$warn $opt" |
| 238 | ;; |
| 239 | esac |
| 240 | ;; |
| 241 | -Werror=declaration-after-statement) |
| 242 | # -pedantic* (with -std=c89) covers -Werror=d-a-s. |
| 243 | case "$stdflags$warn" in |
| 244 | *-std=c89*-pedantic*|*-pedantic*-std=c89*) ;; |
| 245 | *) |
| 246 | echo "cflags.SH: Adding $opt." |
| 247 | warn="$warn $opt" |
| 248 | ;; |
| 249 | esac |
| 250 | ;; |
| 251 | *) |
| 252 | echo "cflags.SH: Adding $opt." |
| 253 | warn="$warn $opt" |
| 254 | ;; |
| 255 | esac |
| 256 | esac |
| 257 | fi |
| 258 | ;; |
| 259 | esac |
| 260 | ;; |
| 261 | esac |
| 262 | case "$ccflags$warn" in |
| 263 | *-pedantic*) |
| 264 | overlength='' |
| 265 | case "$ccflags$optimize" in |
| 266 | *-DDEBUGGING*) overlength='-Wno-overlength-strings' ;; |
| 267 | esac |
| 268 | for opt2 in -DPERL_GCC_PEDANTIC $overlength |
| 269 | do |
| 270 | case "$ccflags$warn" in |
| 271 | *"$opt2"*) ;; |
| 272 | *) echo "cflags.SH: Adding $opt2 because of -pedantic." |
| 273 | warn="$warn $opt2" ;; |
| 274 | esac |
| 275 | done |
| 276 | ;; |
| 277 | esac |
| 278 | done |
| 279 | ;; |
| 280 | esac |
| 281 | rm -f _cflags.c _cflags$_exe |
| 282 | |
| 283 | case "$gccversion" in |
| 284 | '') ;; |
| 285 | *) |
| 286 | case "$warn$ccflags" in |
| 287 | *-pedantic*) |
| 288 | # If we have -Duse64bitint (or equivalent) in effect and the quadtype |
| 289 | # has become 'long long', gcc -pedantic* becomes unbearable |
| 290 | # (moreso when combined with -Wall) because long long and LL and %lld|%Ld |
| 291 | # become warn-worthy. So let's drop the -pedantic in that case. |
| 292 | # |
| 293 | # Similarly, since 'long long' isn't part of C89, FreeBSD 6.2 headers |
| 294 | # don't declare atoll() under -std=c89, but we need it. In general, |
| 295 | # insisting on -std=c89 is inconsistent with insisting on using |
| 296 | # 'long long'. So drop -std=c89 and -ansi as well if we're using |
| 297 | # 'long long' as our main integral type. |
| 298 | # |
| 299 | # usedtrace (DTrace) uses unportable features (dollars in identifiers, |
| 300 | # and gcc statement expressions), it is just easier to turn off pedantic. |
| 301 | remove='' |
| 302 | case "$quadtype:$ivtype:$sPRId64:$usedtrace" in |
| 303 | *"long long"*|*lld*|*Ld*) remove='long long' ;; |
| 304 | *) case "$usedtrace" in |
| 305 | define) remove='usedtrace' ;; |
| 306 | esac |
| 307 | ;; |
| 308 | esac |
| 309 | case "$remove" in |
| 310 | '') ;; |
| 311 | *) echo "cflags.SH: Removing -pedantic*, -std=c89, and -ansi because of $remove." |
| 312 | ccflags=`echo $ccflags|sed -e 's/-pedantic-errors/ /' -e 's/-pedantic/ /' -e 's/-std=c89/ /' -e 's/-ansi/ /' -e 's/-DPERL_GCC_PEDANTIC/ /'` |
| 313 | warn=`echo $warn|sed -e 's/-pedantic-errors/ /' -e 's/-pedantic/ /' -e 's/-ansi/ /' -e 's/-DPERL_GCC_PEDANTIC/ /'` |
| 314 | stdflags=`echo $stdflags|sed -e 's/-std=c89/ /'` |
| 315 | ;; |
| 316 | esac |
| 317 | ;; |
| 318 | esac |
| 319 | ;; |
| 320 | esac |
| 321 | |
| 322 | # Older clang releases are not wise enough for -Wunused-value. |
| 323 | case "$gccversion" in |
| 324 | *"Apple LLVM "[34]*|*"Apple LLVM version "[34]*) |
| 325 | for f in -Wno-unused-value |
| 326 | do |
| 327 | echo "cflags.SH: Adding $f because clang version '$gccversion'" |
| 328 | warn="$warn $f" |
| 329 | done |
| 330 | ;; |
| 331 | esac |
| 332 | |
| 333 | # The quadmath Q format specifier will cause -Wformat to whine. |
| 334 | case "$gccversion" in |
| 335 | '') ;; |
| 336 | *) case "$usequadmath" in |
| 337 | define) |
| 338 | for f in -Wno-format |
| 339 | do |
| 340 | echo "cflags.SH: Adding $f because of usequadmath." |
| 341 | warn="$warn $f" |
| 342 | done |
| 343 | ;; |
| 344 | esac |
| 345 | ;; |
| 346 | esac |
| 347 | |
| 348 | case "$cc" in |
| 349 | *g++*) |
| 350 | # Extra paranoia in case people have bad canned ccflags: |
| 351 | # bad in the sense that the flags are accepted by g++, |
| 352 | # but then whined about. |
| 353 | # |
| 354 | # -Werror=d-a-s option is valid for g++, by definition, |
| 355 | # but we remove it just for cleanliness and shorter command lines. |
| 356 | for f in -Wdeclaration-after-statement \ |
| 357 | -Werror=declaration-after-statement \ |
| 358 | -Wc++-compat \ |
| 359 | -std=c89 |
| 360 | do |
| 361 | case "$ccflags$warn" in |
| 362 | *"$f"*) |
| 363 | echo "cflags.SH: Removing $f because of g++." |
| 364 | ccflags=`echo $ccflags|sed 's/$f/ /'` |
| 365 | warn=`echo $warn|sed 's/$f/ /'` |
| 366 | ;; |
| 367 | esac |
| 368 | done |
| 369 | ;; |
| 370 | esac |
| 371 | |
| 372 | for f in -Wdeclaration-after-statement -Werror=declaration-after-statement |
| 373 | do |
| 374 | case "$cppflags" in |
| 375 | *"$f"*) |
| 376 | echo "cflags.SH: Removing $f from cppflags." |
| 377 | cppflags=`echo $cppflags|sed 's/$f/ /'` ;; |
| 378 | esac |
| 379 | done |
| 380 | |
| 381 | # If usethreads and clang, add -Wthread-safety for clang 3.6 or later. |
| 382 | # gccversion is defined also for clang, because compat, use that for matching. |
| 383 | # Apple overwrites clang version with XCode version, see hints/darwin.sh |
| 384 | # for the gory details. Aggressively forward-proofing. |
| 385 | case "$usethreads" in |
| 386 | define) |
| 387 | case "$gccversion" in |
| 388 | *" Clang 3."[56789]*|*" Clang "[456]*|*"Apple LLVM 6.1"*|*"Apple LLVM "[789]*) |
| 389 | for f in -Wthread-safety |
| 390 | do |
| 391 | case " $warn " in |
| 392 | *" $f "*) ;; # Skip if already there. |
| 393 | *) |
| 394 | echo "cflags.SH: Adding $f because usethreads and clang and gccversion '$gccversion'" |
| 395 | warn="$warn $f" |
| 396 | ;; |
| 397 | esac |
| 398 | done |
| 399 | ;; |
| 400 | esac |
| 401 | ;; |
| 402 | esac |
| 403 | |
| 404 | echo "cflags.SH: cc = $cc" |
| 405 | echo "cflags.SH: ccflags = $ccflags" |
| 406 | echo "cflags.SH: stdflags = $stdflags" |
| 407 | echo "cflags.SH: optimize = $optimize" |
| 408 | echo "cflags.SH: warn = $warn" |
| 409 | |
| 410 | # Code to set any extra flags here. |
| 411 | extra='' |
| 412 | |
| 413 | # Protect double or single quotes for better restoring of ccflags. |
| 414 | myccflags=`echo $ccflags | sed -e 's/"/\\\"/g' -e "s/'/\\\'/g"` |
| 415 | |
| 416 | echo "Extracting cflags (with variable substitutions)" |
| 417 | # This section of the file will have variable substitutions done on it. |
| 418 | # Move anything that needs config subs from !NO!SUBS! section to !GROK!THIS!. |
| 419 | # Protect any dollar signs and backticks that you do not want interpreted |
| 420 | # by putting a backslash in front. You may delete these comments. |
| 421 | rm -f cflags |
| 422 | $spitshell >cflags <<!GROK!THIS! |
| 423 | $startsh |
| 424 | |
| 425 | # !!!!!!! DO NOT EDIT THIS FILE !!!!!!! |
| 426 | |
| 427 | # This file is generated by cflags.SH |
| 428 | |
| 429 | # Used to restore possible edits by cflags.SH. |
| 430 | myccflags="$myccflags" |
| 431 | |
| 432 | # Extra warnings, used e.g. for gcc. |
| 433 | warn="$warn" |
| 434 | # Extra standardness. |
| 435 | stdflags="$stdflags" |
| 436 | # Extra extra. |
| 437 | extra="$extra" |
| 438 | # what do executables look like? |
| 439 | _exe="$_exe" |
| 440 | |
| 441 | !GROK!THIS! |
| 442 | |
| 443 | # In the following dollars and backticks do not need the extra backslash. |
| 444 | $spitshell >>cflags <<'!NO!SUBS!' |
| 445 | case $PERL_CONFIG_SH in |
| 446 | '') |
| 447 | if test -f config.sh; then TOP=.; |
| 448 | elif test -f ../config.sh; then TOP=..; |
| 449 | elif test -f ../../config.sh; then TOP=../..; |
| 450 | elif test -f ../../../config.sh; then TOP=../../..; |
| 451 | elif test -f ../../../../config.sh; then TOP=../../../..; |
| 452 | else |
| 453 | echo "Can't find config.sh."; exit 1 |
| 454 | fi |
| 455 | . $TOP/config.sh |
| 456 | ccflags="$myccflags" # Restore possible edits by cflags.SH. |
| 457 | ;; |
| 458 | esac |
| 459 | |
| 460 | # syntax: cflags [optimize=XXX] [file[.suffix]] ... |
| 461 | # displays the proposed compiler command line for each 'file' |
| 462 | # |
| 463 | # with no file, dispalys it for all *.c files. |
| 464 | # The optimise=XXX arg (if present) is evalled, setting the default |
| 465 | # value of the $optimise variable, which is output on the command line |
| 466 | # (but which may be overridden for specific files below) |
| 467 | |
| 468 | case "X$1" in |
| 469 | Xoptimize=*|X"optimize=*") |
| 470 | eval "$1" |
| 471 | shift |
| 472 | ;; |
| 473 | esac |
| 474 | |
| 475 | case $# in |
| 476 | 0) set *.c; echo "The current C flags are:" ;; |
| 477 | esac |
| 478 | |
| 479 | set `echo "$* " | sed -e 's/\.[oc] / /g' -e 's/\.obj / /g' -e "s/\\$obj_ext / /g"` |
| 480 | |
| 481 | for file do |
| 482 | |
| 483 | case "$#" in |
| 484 | 1) ;; |
| 485 | *) echo $n " $file.c $c" ;; |
| 486 | esac |
| 487 | |
| 488 | # allow variables like toke_cflags to be evaluated |
| 489 | |
| 490 | if echo $file | grep -v / >/dev/null |
| 491 | then |
| 492 | eval 'eval ${'"${file}_cflags"'-""}' |
| 493 | fi |
| 494 | |
| 495 | # or customize here |
| 496 | |
| 497 | case "$file" in |
| 498 | regcomp) : work around http://bugs.debian.org/754054 |
| 499 | case $archname in |
| 500 | mips-*|mipsel-*) |
| 501 | optimize="$optimize -fno-tree-vrp";; |
| 502 | esac;; |
| 503 | *) ;; |
| 504 | |
| 505 | # Customization examples follow. |
| 506 | # |
| 507 | # The examples are intentionally unreachable as the '*)' case above always |
| 508 | # matches. To use them, move before the '*)' and edit as appropriate. |
| 509 | # It is not a good idea to set ccflags to an absolute value here, as it |
| 510 | # often contains general -D defines which are needed for correct |
| 511 | # compilation. It is better to edit ccflags as shown, using interpolation |
| 512 | # to add flags, or sed to remove flags. |
| 513 | |
| 514 | av) ccflags=`echo $ccflags | sed -e s/-pipe//` ;; |
| 515 | deb) ccflags="$ccflags -fno-jump-tables" ;; |
| 516 | hv) warn=`echo $warn | sed -e s/-Wextra//` ;; |
| 517 | toke) optimize=-O0 ;; |
| 518 | esac |
| 519 | |
| 520 | # Can we perhaps use $ansi2knr here |
| 521 | echo "$cc -c -DPERL_CORE $ccflags $stdflags $optimize $warn $extra" |
| 522 | |
| 523 | . $TOP/config.sh |
| 524 | |
| 525 | # end per file behaviour |
| 526 | done |
| 527 | !NO!SUBS! |
| 528 | chmod 755 cflags |
| 529 | $eunicefix cflags |