| File: | config/auto/headers.pm |
| Coverage: | 97.5% |
| line | stmt | bran | cond | sub | code |
|---|---|---|---|---|---|
| 1 | # Copyright (C) 2001-2003, Parrot Foundation. | ||||
| 2 | |||||
| 3 - 11 | =head1 NAME config/auto/headers.pm - C headers =head1 DESCRIPTION Probes for various C headers. =cut | ||||
| 12 | |||||
| 13 | package auto::headers; | ||||
| 14 | |||||
| 15 | 2 2 2 | use strict; | |||
| 16 | 2 2 2 | use warnings; | |||
| 17 | |||||
| 18 | 2 2 2 | use base qw(Parrot::Configure::Step); | |||
| 19 | 2 2 2 | use Parrot::Configure::Utils ':auto'; | |||
| 20 | |||||
| 21 | sub _init { | ||||
| 22 | 4 | my $self = shift; | |||
| 23 | 4 | my %data; | |||
| 24 | 4 | $data{description} = q{Probe for C headers}; | |||
| 25 | 4 | $data{result} = q{}; | |||
| 26 | 4 | return \%data; | |||
| 27 | } | ||||
| 28 | |||||
| 29 | sub runstep { | ||||
| 30 | 3 | my ( $self, $conf ) = @_; | |||
| 31 | |||||
| 32 | 3 | _set_from_Config($conf); | |||
| 33 | |||||
| 34 | 3 | my @extra_headers = _list_extra_headers($conf); | |||
| 35 | |||||
| 36 | 3 | my @found_headers; | |||
| 37 | 3 | foreach my $header (@extra_headers) { | |||
| 38 | 39 | my $pass = 0; | |||
| 39 | |||||
| 40 | # First try with just the header. If that fails, try with all the | ||||
| 41 | # headers we found so far. This is somewhat a hack, but makes probing | ||||
| 42 | # work on *BSD where some headers are documented as relying on others | ||||
| 43 | # being included first. | ||||
| 44 | 39 | foreach my $use_headers ( [$header], [ @found_headers, $header ] ) { | |||
| 45 | 72 | $conf->data->set( TEMP_testheaders => | |||
| 46 | 42 | join( '', map { "#include <$_>\n" } @$use_headers ) ); | |||
| 47 | 42 | $conf->data->set( TEMP_testheader => $header ); | |||
| 48 | |||||
| 49 | 42 | $conf->cc_gen('config/auto/headers/test_c.in'); | |||
| 50 | |||||
| 51 | 42 | $conf->data->set( TEMP_testheaders => undef ); | |||
| 52 | 42 | $conf->data->set( TEMP_testheader => undef ); | |||
| 53 | |||||
| 54 | 42 42 | eval { $conf->cc_build(); }; | |||
| 55 | 42 | if ( !$@ && $conf->cc_run() =~ /^$header OK/ ) { | |||
| 56 | 36 | $pass = 1; | |||
| 57 | 36 | push @found_headers, $header; | |||
| 58 | } | ||||
| 59 | 42 | $conf->cc_clean(); | |||
| 60 | 42 | last if $pass; | |||
| 61 | } | ||||
| 62 | |||||
| 63 | 39 | my $flag = "i_$header"; | |||
| 64 | 39 | $flag =~ s/\.h$//g; | |||
| 65 | 39 | $flag =~ s/\///g; | |||
| 66 | 39 | $conf->debug("$flag: $pass\n"); | |||
| 67 | 39 | $conf->data->set( $flag => $pass ? 'define' : undef ); | |||
| 68 | } | ||||
| 69 | |||||
| 70 | 3 | return 1; | |||
| 71 | } | ||||
| 72 | |||||
| 73 | sub _set_from_Config { | ||||
| 74 | 4 | my $conf = shift; | |||
| 75 | # Perl 5's Configure system doesn't call this by its full name, which may | ||||
| 76 | # confuse use later, particularly once we break free and start doing all | ||||
| 77 | # probing ourselves | ||||
| 78 | 4 | my %mapping = ( i_niin => "i_netinetin" ); | |||
| 79 | |||||
| 80 | 4 87 | for ( grep { /^i_/ } $conf->data->keys_p5() ) { | |||
| 81 | 87 | $conf->data->set( $mapping{$_} || $_ => $conf->data->get_p5($_) ); | |||
| 82 | } | ||||
| 83 | } | ||||
| 84 | |||||
| 85 | sub _list_extra_headers { | ||||
| 86 | 5 | my $conf = shift; | |||
| 87 | # some headers may not be probed-for by Perl 5, or might not be | ||||
| 88 | # properly reflected in %Config (i_fcntl seems to be wrong on my machine, | ||||
| 89 | # for instance). | ||||
| 90 | # | ||||
| 91 | # FreeBSD wants this order: | ||||
| 92 | #include <sys/types.h> | ||||
| 93 | #include <sys/socket.h> | ||||
| 94 | #include <netinet/in.h> | ||||
| 95 | #include <arpa/inet.h> | ||||
| 96 | # hence add sys/types.h to the reprobe list, and have 2 goes at getting | ||||
| 97 | # the header. | ||||
| 98 | 5 | my @extra_headers = qw(malloc.h fcntl.h setjmp.h pthread.h signal.h | |||
| 99 | sys/types.h sys/socket.h netinet/in.h arpa/inet.h | ||||
| 100 | sys/stat.h sysexit.h limits.h sys/sysctl.h); | ||||
| 101 | |||||
| 102 | # more extra_headers needed on mingw/msys; *BSD fails if they are present | ||||
| 103 | 5 | if ( $conf->data->get('OSNAME_provisional') eq "msys" ) { | |||
| 104 | 1 | push @extra_headers, qw(sysmman.h netdb.h sys/utsname.h); | |||
| 105 | } | ||||
| 106 | |||||
| 107 | 5 | if ( $conf->data->get('OSNAME_provisional') eq "MSWin32" ) { | |||
| 108 | # Microsoft provides two annotations mechanisms. __declspec, which | ||||
| 109 | # has been around for a while, and Microsoft's standard source code | ||||
| 110 | # annotation language (SAL), introduced with Visual C++ 8.0. See | ||||
| 111 | # <http://msdn2.microsoft.com/en-us/library/ms235402(VS.80).aspx>, | ||||
| 112 | # <http://msdn2.microsoft.com/en-us/library/dabb5z75(VS.80).aspx>. | ||||
| 113 | 1 | push @extra_headers, qw(sal.h); | |||
| 114 | } | ||||
| 115 | |||||
| 116 | 5 | return @extra_headers; | |||
| 117 | } | ||||
| 118 | |||||
| 119 | |||||
| 120 | 1; | ||||
| 121 | |||||
| 122 | # Local Variables: | ||||
| 123 | # mode: cperl | ||||
| 124 | # cperl-indent-level: 4 | ||||
| 125 | # fill-column: 100 | ||||
| 126 | # End: | ||||
| 127 | # vim: expandtab shiftwidth=4: | ||||