c-conf (19232B)
1 #!/usr/bin/env perl 2 3 use strict; 4 use Getopt::Std; 5 6 # Globals 7 my $VER = "1.18"; 8 # 1.18 [KK 2013-04-05] Added /usr/lib/arm-linux-gnueabihf for Raspberry Pi 9 # 1.17 [KK 2013-03-15] /lib/x86_64-linux-gnu added for Ubuntu 10 # 1.16 [KK 2011-10-10] /usr/lib/x86_64-linux-gnu added to the libdirs for 11 # Ubuntu 11 64-bits. 12 # 1.15 [KK 2008-10-12] Option "optflags" implemented. 13 # 1.14 [KK 2008-08-22] c-compiler and c++-compiler attempt to find by 14 # version, eg. '/opt/local/bin/g++-mp-4.2' is better 15 # than '/usr/bin/g++' 16 # 1.13 [KK 2008-07-15] Opimized subfiles() - way faster when nonrecursive now 17 # 1.12 [KK 2008-04-15] Messaging improved upon -v flag 18 # 1.11 [KK 2008-01-14] Added /opt/local/{lib,include} to the standard libs. 19 # Also added /sw 20 # 1.10 [KK 2007-08-29] Added libvariable01 and flag -l. Flags -l/L get 21 # used upon libfunction/libvariable checks. 22 # 1.09 [KK 2007-06-13] Added 'lib64' variants to libdirs, for 64bit Linux 23 # 1.08 [KK 2007-05-22] -L{dir} shown only once for identical dirs during 'lib' 24 # 1.07 [KK 2007-05-18] Flag -c for caching implemented 25 # 1.06 [KK 2007-04-27] Added ifheader01 and libfunction01 26 # 1.05 [KK 2006-09-28] Flag -s (silent) implemented. Usage text updated. 27 # 1.04 [KK 2006-09-05] C-compilers: gcc/g++ get selected first, instead of 28 # cc/c++. Helps HP-UX ports. [Thanks, Bernd Krumboeck.] 29 # 1.03 [KK 2006-07-19] 'subfiles' keeps track of visited dirs incase of 30 # recursion. Testing is now by inode, used to be by name. 31 # 1.02 [KK 2006-06-01] 'findbin' searches for .exe too now, for Cygwin support 32 # 1.01 [KK 2005-09-29] Implemented context-sensitive help via -h. 33 # Action 'header' implemented. 34 # 1.00 [KK 2005-09-28] First version 35 36 # Configuration 37 my @def_headerdirs = ('/usr/include', 38 '/usr/local/include', 39 '/opt/local/include', 40 '/sw/include', 41 "$ENV{HOME}/include", 42 ); 43 my @def_libdirs = ('/usr/lib', 44 '/usr/lib64', 45 '/lib/x86_64-linux-gnu', 46 '/usr/lib/x86_64-linux-gnu', 47 '/usr/lib/arm-linux-gnueabihf', 48 '/usr/local/lib', 49 '/usr/local/lib64', 50 '/opt/local/lib', 51 '/opt/local/lib64', 52 '/usr/ucblib', 53 '/sw/lib', 54 '/sw/lib64', 55 "$ENV{HOME}/lib", 56 ); 57 my @c_compilers = ('gcc', 'cc'); 58 my @cpp_compilers = ('g++', 'c++'); 59 60 # Globals 61 my %opts; 62 my $base; 63 my @warnings; 64 my $printed; 65 my @headerdirs; 66 my @libdirs; 67 my @libs; 68 my $cachekey; 69 my $cacheval; 70 71 # Show usage and croak 72 sub usage { 73 die <<"ENDUSAGE" 74 75 This is c-conf, the C compilation configuration helper V$VER 76 Copyright (c) e-tunity. Contact <info\@e-tunity.com> for information. 77 78 Usage: 79 $base [flags] header FILE.H [FILE.H...] Searches for directories 80 containing the named header(s), returns appropriate -I flags. 81 $base [flags] headerdir DIR [DIR...]: Searches for directory 82 containing headers, returns appropriate -I flags. 83 $base [flags] ifheader FILE.H DEFINE Searches for the named header. 84 If found, a compilation flag -DDEFINE is returned, indicating that 85 the header is found. 86 $base [flags] ifheader01 FILE.H DEFINE Similar to ifheader, but the 87 returned define is either DEFINE=0 or DEFINE=1 88 $base [flags] lib NAME [NAME...]: Searches for libNAME.{a,so,...}, 89 returns appropriate -L and -l flags. 90 $base [flags] libfunction FUNC DEFINE Creates a small program that 91 tries to use FUNC. If this succeeds, a -DDEFINE=1 flag is returned. 92 $base [flags] libfunction01 FUNC DEFINE Similar to libfunction, but 93 the returned define is DEFINE=0 or DEFINE=1 94 $base [flags] libvariable01 VAR DEFINE Creates a small program that 95 accesses variable VAR. If this succeeds, -DDEFINE=1 is returned. 96 $base [flags] so-name NAME: Returns filename of a shared-object for NAME, 97 e.g. libNAME.so 98 $base [flags] so-cflags: Returns compilation flags to build shared 99 objects 100 $base [flags] so-lflags: Returns linkage flags to produce a shared-object 101 library 102 $base [flags] c-compiler: Returns name of C compiler 103 $base [flags] c++-compiler: Returns name of C++ compiler 104 $base [flags] optflags: Returns fast-code optimization flags. 105 106 Optional flags: 107 -c CACHE: settings will be dynamically determined unless present in 108 CACHE; new settings will be added to CACHE 109 -h: to show short help for an action, e.g. try '$base -h so-name' 110 -s: to suppress showing of warnings 111 -v: to show verbose messages 112 -I DIR[,DIR..]: to add DIR(s) to the searchpath for headers, default 113 searchpath is @headerdirs 114 -L DIR[,DIR..]: to add DIR(s) to the searchpath for libraries, default 115 searchpath is @libdirs 116 -l LIB[,LIB..]: to add LIB(s) to C compiler invocations, when checking 117 for lib functions or variables 118 119 Meaningful output is returned on stdout. Verbose messages, warnings and 120 errors go to stderr. 121 122 ENDUSAGE 123 } 124 125 # Issue a warning 126 sub warning { 127 push (@warnings, "@_"); 128 } 129 130 # Show a message 131 sub msg { 132 return unless ($opts{v}); 133 print STDERR ("$base: ", @_); 134 } 135 136 # Show help info if -h was given 137 sub checkhelp { 138 return unless ($opts{h}); 139 print STDERR (@_); 140 exit (1); 141 } 142 143 # Basename / dirname of a file. 144 sub basename ($) { 145 my $name = shift; 146 $name =~ s{.*/}{}; 147 return ($name); 148 } 149 sub dirname ($) { 150 my $name = shift; 151 return (undef) unless ($name =~ /\//); 152 $name =~ s{/[^/]$}{}; 153 return ($name); 154 } 155 156 # Get the uname. 157 sub uname() { 158 my $ret = `uname`; 159 chomp ($ret); 160 return ($ret); 161 } 162 163 # Find a binary along the path. 164 sub findbin($) { 165 my $bin = shift; 166 my $bestx = undef; 167 my $bestver = -1; 168 foreach my $d (split (/:/, $ENV{PATH})) { 169 my @cand = (glob("$d/$bin"), glob("$d/$bin.exe"), 170 glob("$d/$bin-*"), glob("$d/$bin-*.exe")); 171 msg ("Candidates for '$bin' in '$d': [@cand]\n"); 172 for my $x (@cand) { 173 if (-x $x) { 174 my $ver = $x; 175 $ver =~ s{^.*/[^\d]*}{}; 176 $ver = sprintf("%g", $ver); 177 msg ("Version of $x: $ver\n"); 178 if ($bestver < $ver or !$bestx) { 179 $bestver = $ver; 180 $bestx = $x; 181 msg (" .. best so far\n"); 182 } 183 } 184 } 185 } 186 msg ("Failed to locate executable '$bin'!\n") unless ($bestx); 187 return ($bestx); 188 } 189 190 # Recursively determine the files under a given dir. 191 my %_dir_visited; 192 sub subfiles ($$$) { 193 my ($dir, $mask, $recursive) = @_; 194 195 %_dir_visited = (); 196 my ($dev, $ino) = stat($dir) 197 or return (undef); 198 my $tag = sprintf ("%d-%d", $dev, $ino); 199 return (undef) if ($_dir_visited{$tag}); 200 $_dir_visited{$tag} = $dir; 201 return (undef) unless (-d $dir); 202 203 my @ret = (); 204 foreach my $f (glob ("$dir/$mask")) { 205 push (@ret, $f) if (-f $f); 206 } 207 208 if ($recursive) { 209 foreach my $d (glob ("$dir/*")) { 210 next unless (-d $d); 211 my @subret = subfiles ("$d", $mask, 1); 212 my $added = 0; 213 foreach my $f (@subret) { 214 if (-f $f) { 215 push (@ret, $f); 216 $added++; 217 } 218 } 219 } 220 } 221 222 if ($#ret > -1) { 223 return (@ret); 224 } else { 225 return (undef); 226 } 227 } 228 229 # Output stuff, update $cacheval incase we'll add it to the cache later. 230 sub output { 231 if ($printed++) { 232 print (' '); 233 $cacheval .= ' '; 234 } 235 print (@_); 236 for my $a (@_) { 237 $cacheval .= $a; 238 } 239 } 240 241 # Find a header, output a define if found. 242 sub if_header { 243 checkhelp <<"ENDHELP"; 244 'ifheader' tries to find a header file in the 'include' directories. 245 When found, a define-flag for the C compiler is returned. 246 E.g.: $base ifheader malloc.h HAVE_MALLOC_H (may return -DHAVE_MALLOC_H) 247 Use in a Makefile as in: 248 CFLAGS = \$(CFLAGS) \$(shell c-conf ifheader malloc.h HAVE_MALLOC_H) 249 Then in a C source as: 250 #ifdef HAVE_MALLOC_H 251 #include <malloc.h> 252 #endif 253 ENDHELP 254 255 usage() if ($#_ != 1); 256 257 my ($h, $def) = @_; 258 259 foreach my $d (@headerdirs) { 260 if (-f "$d/$h") { 261 msg ("Header '$h' found as '$d/$h'\n"); 262 output ("-D$def"); 263 return; 264 } 265 } 266 } 267 268 # Find a header, output define=0 or define=1 269 sub if_header01 { 270 checkhelp <<"ENDHELP"; 271 'ifheader01' tries to find a header in the 'include' directories. When 272 found, a define for the C compiler is returned having value 1. When not 273 found, the value is 0. Use in a Makefile as follows: 274 CFLAGS = \$(shell c-conf ifheader01 malloc.h HAVE_MALLOC_H) 275 Then in a C source as: 276 #if HAVE_MALLOC_H == 1 277 #include <malloc.h> 278 #endif 279 ENDHELP 280 281 usage() if ($#_ != 1); 282 my ($h, $def) = @_; 283 foreach my $d (@headerdirs) { 284 if (-f "$d/$h") { 285 output ("-D$def=1"); 286 return; 287 } 288 } 289 output ("-D$def=0"); 290 return; 291 } 292 293 # Find a header 294 sub header { 295 checkhelp <<"ENDHELP"; 296 'header' locates one or more C headers in the 'include' directories. 297 E.g.: $base header e-lib.h stdio.h (may return -I/usr/include -I/usr/e/include) 298 Use in a Makefile as in: 299 CFLAGS = -C -Wall \$(shell c-conf header e-lib.h) 300 Then in a C source as: 301 #include <e-lib.h> 302 ENDHELP 303 304 usage() if ($#_ == -1); 305 foreach my $h (@_) { 306 my $found = 0; 307 foreach my $d (@headerdirs) { 308 if (-f "$d/$h") { 309 $found++; 310 msg ("Header '$h' found as '$d/$h\n"); 311 output ("-I$d"); 312 last; 313 } 314 } 315 warning ("Failed to locate header '$h' in @headerdirs\n") 316 unless ($found); 317 } 318 } 319 320 # Find a header directory 321 sub headerdir { 322 checkhelp <<"ENDHELP"; 323 'headerdir' locates directories under which (in steps) C headers are 324 E.g.: $base headerdir libxml2 (may return '-I/usr/include/libxml2') 325 Use in a Makefile as in: 326 CFLAGS = -C -Wall \$(shell c-conf headerdir libxml2) 327 Then in a C source as: 328 #include <libxml/xpath.h> 329 ENDHELP 330 331 usage() if ($#_ == -1); 332 foreach my $headerdir (@_) { 333 my $found = 0; 334 foreach my $d (@headerdirs) { 335 my $target = "$d/$headerdir"; 336 if (subfiles ($target, '*.h', 0)) { 337 msg ("Header directory '$headerdir' found as '$target'\n"); 338 output ("-I$target"); 339 $found++; 340 } 341 } 342 warning ("Header dir '$headerdir' not found\n") 343 unless ($found); 344 } 345 } 346 347 # Find a library 348 sub lib { 349 checkhelp <<"ENDHELP"; 350 'lib' generates the linkage flags for a given library name. The name 351 is bare, without 'lib' and '.so' and the like. 352 E.g.: $base lib xml2 (may return '-L/usr/lib -lxml2') 353 Use in a Makefile as in: 354 LDFLAGS = \$(shell c-conf lib xml2) 355 ENDHELP 356 357 usage() if ($#_ == -1); 358 359 my %dirshown; 360 foreach my $lib (@_) { 361 my $found = 0; 362 foreach my $d (@libdirs) { 363 my $hit = (subfiles ($d, "lib$lib.*", 0))[0]; 364 if ($hit) { 365 msg ("Library '$lib' found as '$hit'\n"); 366 $found++; 367 $hit =~ s{/[^/]*$}{}; 368 if (! $dirshown{$hit}) { 369 output ("-L$hit"); 370 $dirshown{$hit} = 1; 371 } 372 output ("-l$lib"); 373 } 374 } 375 #warning ("Library '$lib' not found\n") 376 # unless ($found); 377 } 378 } 379 380 # Compilation flags to make a so-ready object. 381 sub so_cflags { 382 checkhelp <<"ENDHELP"; 383 'so-cflags' returns the compilation flags that are necessary when 384 building objects for a shared library. 385 E.g.: $base so-cflags (may return '-fPIC') 386 Use in a Makefile as in: 387 CFLAGS = -c -g -Wall \$(shell c-conf so-cflags) 388 ENDHELP 389 390 usage() if ($#_ > -1); 391 my $flags; 392 if (uname() eq 'Darwin') { 393 $flags = '-fPIC'; 394 } elsif (uname() eq 'Linux') { 395 $flags = '-fpic'; 396 } 397 msg ("Shared object compilation flags: '$flags'\n"); 398 output ($flags); 399 } 400 401 # Linkage flags to make an so. 402 sub so_lflags { 403 checkhelp << "ENDHELP"; 404 'so-lflags' returns the linkage flags that are necessary when 405 combining objects into a shared library. 406 E.g.: $base so-lflags (may return '-dynamiclib -Wl,-single_module') 407 Use in a Makefile as in: 408 MY_SO = \$(shell c-conf so-name my) 409 \$(MY_SO): *.o 410 \$(CC) -o \$(MY_SO) \$(shell c-conf so-lflags) *.o 411 ENDHELP 412 413 usage() if ($#_ > -1); 414 my $lib = shift; 415 416 my $flags; 417 if (uname() eq 'Darwin') { 418 $flags = "-dynamiclib -Wl,-single_module"; 419 } else { 420 $flags = "-shared"; 421 } 422 msg ("Shared library linkage flags: '$flags'\n"); 423 output ($flags); 424 } 425 426 # Find the C compiler and return it, or die trying. 427 sub find_c_compiler { 428 foreach my $c (@c_compilers) { 429 my $full = findbin($c); 430 return ($full) if ($full); 431 } 432 die ("No C compiler found\n"); 433 } 434 435 # Get the C compiler 436 sub c_compiler { 437 checkhelp <<"ENDHELP"; 438 'c-compiler' tries to find a C compiler and returns its (bare) name. 439 E.g.: $base c-compiler 440 -> gcc 441 ENDHELP 442 443 usage() if ($#_ > -1); 444 my $cc; 445 eval { $cc = find_c_compiler(); }; 446 if ($@) { 447 warning ($@); 448 } else { 449 msg ("C compiler: '$cc'\n"); 450 output ($cc); 451 } 452 } 453 454 # Get the C++ compiler 455 sub cpp_compiler { 456 checkhelp <<"ENDHELP"; 457 'c++-compiler' tries to find a C++ compiler and returns its (bare) name. 458 E.g.: $base c++-compiler 459 -> g++ 460 ENDHELP 461 462 usage() if ($#_ > -1); 463 foreach my $c (@cpp_compilers) { 464 my $full = findbin($c); 465 if ($full) { 466 msg ("C++ compiler: '$full'\n"); 467 output ($full); 468 return; 469 } 470 } 471 warning ("No C++ compiler found\n"); 472 } 473 474 # Get fast code optimization flags. 475 sub optflags { 476 checkhelp <<"ENDHELP"; 477 'optflags' tries to determine optimization flags. 478 E.g.: $base optflags 479 -> -O3 480 ENDHELP 481 usage() if ($#_ > -1); 482 for my $optflag ('-fast', '-O3', '-O2') { 483 if (test_compile ("int main() {}\n", $optflag)) { 484 output ($optflag); 485 return; 486 } 487 } 488 warning ("No optimization flag found."); 489 } 490 491 492 # Get the name for an SO. 493 sub so_name { 494 checkhelp <<"ENDHELP"; 495 'so-name' returns the filename of a shared library, based on the LIB 496 argument. 497 E.g.: $base so-name test 498 -> libtest.so 499 ENDHELP 500 501 usage() if ($#_ != 0); 502 my $name = shift; 503 504 my $dir = dirname ($name); 505 my $base = basename ($name); 506 507 my $dest; 508 if (uname() eq 'Darwin') { 509 $dest = "lib$base.dylib"; 510 } else { 511 $dest = "lib$base.so"; 512 } 513 514 if ($dir ne '') { 515 msg ("Shared library name for '$name': '$dir/$dest'\n"); 516 output ("$dir/$dest"); 517 } else { 518 msg ("Shared library name for '$name': '$dest'\n"); 519 output ("$dest"); 520 } 521 } 522 523 # Check that a libfunction is present. 524 sub libfunction { 525 checkhelp <<"ENDHELP"; 526 'libfunction' checks whether a library function is present. There are 527 two arguments: the function to check, and a define to output when the 528 function is found. The output is a -D flag for the compiler commandline. 529 E.g.: $base libfunction printf HAVE_PRINTF 530 -> -DHAVE_PRINTF=1 531 $base libfunction foo_bar HAVE_FOOBAR 532 -> (nothing) 533 ENDHELP 534 535 if (test_libfunction (@_)) { 536 msg ("Library function '$_[0]' present\n"); 537 output ("-D$_[1]=1"); 538 } else { 539 msg ("Library function '$_[0]' absent\n"); 540 } 541 } 542 543 # Check that a lib variable is present, 01 version 544 sub libvariable01 { 545 checkhelp <<"ENDHELP"; 546 'libvariable01' checks whether a library variable is present. There are 547 two arguments: a variable name, and a define to output with value 0 or 1. 548 E.g.: $base libvariable01 errno HAVE_ERRNO 549 -> -DHAVE_ERRNO=1 550 ENDHELP 551 552 if (test_libvariable(@_)) { 553 msg ("Library variable '$_[1]' present\n"); 554 output ("-D$_[1]=1"); 555 } else { 556 msg ("Library variable '$_[1]' absent\n"); 557 output ("-D$_[1]=0"); 558 } 559 } 560 561 # Check that a libfunction is present, 01-version 562 sub libfunction01 { 563 checkhelp <<"ENDHELP"; 564 'libfunction01' checks whether a library function is present. There are 565 two arguments: the function to check, and a define to output when the 566 function is found. When the lib function is found, then the define is 567 returned with a value 1, else with a value 0. 568 E.g.: $base libfunction01 printf HAVE_PRINTF 569 -> -DHAVE_PRINTF=1 570 $base libfunction foo_bar HAVE_FOOBAR 571 -> -DHAVE_FOOBAR=0 572 ENDHELP 573 574 if (test_libfunction (@_)) { 575 msg ("Library function '$_[1]' present\n"); 576 output ("-D$_[1]=1"); 577 } else { 578 msg ("Library function '$_[1]' absent\n"); 579 output ("-D$_[1]=0"); 580 } 581 } 582 583 sub test_compile { 584 my $sourcecode = shift; 585 my $cc = find_c_compiler(); 586 587 # Create a temp .c file. 588 my $src = "/tmp/$$.c"; 589 my $dst = "/tmp/$$.out"; 590 open (my $of, ">$src") 591 or die ("Cannot write $src: $!\n"); 592 print $of ($sourcecode); 593 close ($of); 594 595 my $cmd = "$cc "; 596 for my $flag (@_) { 597 $cmd .= "$flag "; 598 } 599 $cmd .= "$src -o $dst " . 600 cc_inc_flags() . ' ' . cc_libdir_flags() . ' ' . cc_lib_flags(); 601 # print ($cmd, "\n"); 602 my $ret = system ("$cmd >/dev/null 2>&1"); 603 unlink ($src, $dst); 604 605 return ($ret == 0 ? 1 : 0); 606 } 607 608 # Return @headerdirs as C flags 609 sub cc_inc_flags() { 610 my $ret = ''; 611 for my $h (@headerdirs) { 612 $ret .= " -I$h"; 613 } 614 msg ("C compilation include flags: '$ret'\n"); 615 return ($ret); 616 } 617 618 # Return @libdirs as C flags 619 sub cc_libdir_flags() { 620 my $ret = ''; 621 for my $l (@libdirs) { 622 $ret .= " -L$l" if (-d $l); 623 } 624 msg ("C library directory flags: '$ret'\n"); 625 return ($ret); 626 } 627 628 # Return @libs as C flags 629 sub cc_lib_flags() { 630 my $ret = ''; 631 for my $l (@libs) { 632 $ret .= " -l$l"; 633 } 634 msg ("C library flags: '$ret'\n"); 635 return ($ret); 636 } 637 638 # Test whether a lib function is present. 639 sub test_libfunction { 640 641 usage() if ($#_ != 1); 642 my ($func, $def) = @_; 643 return (test_compile ("main () {\n" . 644 " void $func (void);\n" . 645 " $func();\n" . 646 "}\n")); 647 } 648 649 # Test whether a lib variable is present. 650 sub test_libvariable { 651 652 usage() if ($#_ != 1); 653 my ($var, $def) = @_; 654 return (test_compile ("main () {\n" . 655 " extern int $var;\n" . 656 " $var = 42;\n" . 657 "}\n")); 658 } 659 660 # Main starts here 661 662 $base = $0; 663 $base =~ s{.*/}{}; 664 usage () unless (getopts ('vhI:L:sc:l:', \%opts)); 665 666 # See if we got a cache with the requests in it. 667 # If we can match the request, return the result. 668 if ($opts{c}) { 669 $cachekey = ''; 670 for my $a (@ARGV) { 671 $cachekey .= ' ' if ($cachekey ne ''); 672 $cachekey .= $a; 673 } 674 if (open (my $if, $opts{c})) { 675 while (my $line = <$if>) { 676 chomp ($line); 677 my ($key, $val) = split (/\t/, $line); 678 if ($key eq $cachekey) { 679 output ($val); 680 print ("\n"); 681 exit (0); 682 } 683 } 684 } 685 } 686 687 foreach my $d (split (/,/, $opts{L})) { 688 push (@libdirs, $d); 689 } 690 foreach my $d (split (/,/, $opts{I})) { 691 push (@headerdirs, $d); 692 } 693 foreach my $d (split (/,/, $opts{l})) { 694 push (@libs, $d); 695 } 696 697 push (@libdirs, @def_libdirs); 698 push (@headerdirs, @def_headerdirs); 699 my $action = shift (@ARGV); 700 701 if ($action eq 'header') { 702 header (@ARGV); 703 } elsif ($action eq 'headerdir') { 704 headerdir (@ARGV); 705 } elsif ($action eq 'lib') { 706 lib (@ARGV); 707 } elsif ($action eq 'so-cflags') { 708 so_cflags (@ARGV); 709 } elsif ($action eq 'so-lflags') { 710 so_lflags (@ARGV); 711 } elsif ($action eq 'c-compiler') { 712 c_compiler(@ARGV); 713 } elsif ($action eq 'c++-compiler') { 714 cpp_compiler(@ARGV); 715 } elsif ($action eq 'so-name') { 716 so_name (@ARGV); 717 } elsif ($action eq 'ifheader') { 718 if_header (@ARGV); 719 } elsif ($action eq 'ifheader01') { 720 if_header01 (@ARGV); 721 } elsif ($action eq 'libfunction') { 722 libfunction (@ARGV); 723 } elsif ($action eq 'libfunction01') { 724 libfunction01 (@ARGV); 725 } elsif ($action eq 'libvariable01') { 726 libvariable01 (@ARGV); 727 } elsif ($action eq 'optflags') { 728 optflags (@ARGV); 729 } else { 730 usage (); 731 } 732 733 print ("\n") if ($printed); 734 735 # Add to the cache if necessary. 736 if ($opts{c}) { 737 open (my $of, ">>$opts{c}") 738 or die ("Cannot append to cache file $opts{c}: $!\n"); 739 print $of ("$cachekey\t$cacheval\n"); 740 } 741 742 if ($#warnings > -1) { 743 foreach my $w (@warnings) { 744 print STDERR ("$base WARNING: $w") unless ($opts{s}); 745 } 746 exit (1); 747 } 748 exit (0); 749