1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
my $testnum = 0;
my $compile_ok = sub {
my($builder, $hdrs, $code, $link_ctl) = @_;
use IO::File;
my $conftest_base = $builder->localize_file_path(
"lib/Hash/conftest$testnum");
my $conftest_file = $builder->localize_file_path(
"lib/Hash/conftest$testnum.c");
$testnum++;
$builder->add_to_cleanup($conftest_file);
my $src_fh = IO::File->new($conftest_file, "w")
or die "can't write $conftest_file: $!";
$src_fh->printflush("#include \"EXTERN.h\"\n".
"#include \"perl.h\"\n".
"#include \"XSUB.h\"\n".
join("", map { "#include <$_>\n" } @$hdrs).
"int main(void) {$code}\n")
or die "can't write $conftest_file: $!";
$src_fh = undef;
return eval {
my $obj_file = $builder->compile_c($conftest_file,
no_feature_defs => 1);
my $cbuilder = $builder->cbuilder;
if($link_ctl) {
$builder->add_to_cleanup(
$cbuilder->exe_file($obj_file));
$cbuilder->link_executable(
objects => $obj_file,
extra_linker_flags => [
@{$builder->extra_linker_flags || []},
(exists($link_ctl->{extra}) ?
@{$link_ctl->{extra}} : ()),
],
);
}
1;
} || 0;
};
sub {
my($builder) = @_;
my %defs;
my @libs;
$compile_ok->($builder, ["stdio.h"], q{
char buf[5];
return sprintf(buf, "%d", 0) + 1;
}, {}) or die "probe system failed: can't compile innocuous program";
$compile_ok->($builder, [], q{
extern int HLBNzorFAJMYbPEjiEKkMFBaKqZMkqq(void);
return HLBNzorFAJMYbPEjiEKkMFBaKqZMkqq() + 1;
}, {}) and die "probe system failed: non-existent function usable";
$compile_ok->($builder, ["sys/mman.h"], q{
int res;
res = mmap(NULL, 4096, PROT_READ, MAP_SHARED, 3, 0)
== (void*)-1;
return res;
}, {}) or die "OS unsupported: mmap(2) not available";
$defs{QHAVE_GETPAGESIZE} = $compile_ok->($builder, [], q{
int res;
res = getpagesize();
return res;
}, {});
$defs{QHAVE_SYSCONF} = $compile_ok->($builder, [], q{
int res;
res = sysconf(0);
return res;
}, {});
$defs{QHAVE_PATHCONF} = $compile_ok->($builder, [], q{
int res;
res = pathconf("/", 0);
return res;
}, {});
$defs{QHAVE_CLOCK_GETTIME} = $compile_ok->($builder, [], q{
struct timespec ts;
int res;
res = clock_gettime(CLOCK_REALTIME, &ts);
return res;
}, {});
if(!$defs{QHAVE_CLOCK_GETTIME} &&
$compile_ok->($builder, [], q{
struct timespec ts;
int res;
res = clock_gettime(CLOCK_REALTIME, &ts);
return res;
}, {extra=>["-lrt"]})) {
push @libs, "-lrt";
$defs{QHAVE_CLOCK_GETTIME} = 1;
}
$defs{QHAVE_GETTIMEOFDAY} = $compile_ok->($builder, [], q{
struct timeval tv;
int res;
res = gettimeofday(&tv, NULL);
return res;
}, {});
# Cygwin declares openat(2) et al functions, and they
# superficially appear to work, but they're frauds. They don't
# actually use a reference to the directory, as a fd would appear
# to supply. Instead the directory fd encapsulates the absolute
# pathname under which the directory was opened, and openat(2)
# et al use the saved pathname. They therefore fail if the
# directory is renamed.
# <http://www.cygwin.com/ml/cygwin-developers/2008-04/msg00108.html>
# We therefore reject Cygwin's versions of these functions,
# in favour of our own fakery that we don't mistake for the
# real thing.
$defs{QHAVE_OPENAT} = $^O eq "cygwin" ? 0 :
$compile_ok->($builder, [], q{
int res;
res = openat(0, ".", 0, 0);
return res;
}, {});
$defs{QHAVE_FSTATAT} = $^O eq "cygwin" ? 0 :
$compile_ok->($builder, [], q{
struct stat st;
int res;
res = fstatat(0, ".", &st, 0);
return res;
}, {});
$defs{QHAVE_LINKAT} = $^O eq "cygwin" ? 0 :
$compile_ok->($builder, [], q{
int res;
res = linkat(0, ".", 0, ".", 0);
return res;
}, {});
$defs{QHAVE_UNLINKAT} = $^O eq "cygwin" ? 0 :
$compile_ok->($builder, [], q{
int res;
res = unlinkat(0, ".", 0);
return res;
}, {});
$defs{QHAVE_FDOPENDIR} = $compile_ok->($builder, [], q{
DIR *dirh;
dirh = fdopendir(0);
return !dirh;
}, {});
$defs{QHAVE_REALPATH} = $compile_ok->($builder, [], q{
char *res, buf[4096];
res = realpath(".", buf);
return !res;
}, {});
$defs{QHAVE_GETCWD} = $compile_ok->($builder, [], q{
char *res, buf[4096];
res = getcwd(buf, sizeof(buf));
return !res;
}, {});
return { defs => \%defs, libs => \@libs };
}
|