summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgregor herrmann <gregoa@debian.org>2022-05-07 20:46:02 +0200
committergregor herrmann <gregoa@debian.org>2022-05-07 20:46:02 +0200
commita1d39bf853e20805af41cf9de4205611dd372626 (patch)
tree922944217f8fcae2c353f0b19d09e58b8c893a36
parentcbcab4aaf385d75640e976f304e3a9974547e3a9 (diff)
New upstream version 1.16
-rw-r--r--CHANGES5
-rw-r--r--META.json8
-rw-r--r--META.yml4
-rw-r--r--lib/Devel/CheckLib.pm226
-rw-r--r--t/exit_with_message.t2
-rw-r--r--t/lib/Helper.pm24
-rw-r--r--t/multi-word-compiler.t9
7 files changed, 132 insertions, 146 deletions
diff --git a/CHANGES b/CHANGES
index c6316b8..e06bda7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+1.16 2022-05-04 Stop all the tests that require a working compiler from
+ skipping on AIX
+
+1.15 2022-05-04 Refactor, stop GCC optimising away test code
+
1.14 2019-11-12 Use Capture::Tiny instead of Capture::Output
1.13 2018-06-23 Improve Makefile.PL
diff --git a/META.json b/META.json
index d4c0fbb..5b1f222 100644
--- a/META.json
+++ b/META.json
@@ -6,13 +6,13 @@
"Yasuhiro Matsumoto"
],
"dynamic_config" : 0,
- "generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010",
+ "generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
"license" : [
"perl_5"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
- "version" : "2"
+ "version" : 2
},
"name" : "Devel-CheckLib",
"no_index" : {
@@ -54,6 +54,6 @@
"url" : "http://github.com/mattn/p5-Devel-CheckLib"
}
},
- "version" : "1.14",
- "x_serialization_backend" : "JSON::PP version 2.27400_02"
+ "version" : "1.16",
+ "x_serialization_backend" : "JSON::PP version 4.02"
}
diff --git a/META.yml b/META.yml
index 7a70e3a..20ea1a6 100644
--- a/META.yml
+++ b/META.yml
@@ -12,7 +12,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: '0'
dynamic_config: 0
-generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010'
+generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -29,5 +29,5 @@ requires:
perl: '5.00405'
resources:
repository: http://github.com/mattn/p5-Devel-CheckLib
-version: '1.14'
+version: '1.16'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff --git a/lib/Devel/CheckLib.pm b/lib/Devel/CheckLib.pm
index 1efd43f..2e5a252 100644
--- a/lib/Devel/CheckLib.pm
+++ b/lib/Devel/CheckLib.pm
@@ -5,9 +5,9 @@ package Devel::CheckLib;
use 5.00405; #postfix foreach
use strict;
use vars qw($VERSION @ISA @EXPORT);
-$VERSION = '1.14';
+$VERSION = '1.16';
use Config qw(%Config);
-use Text::ParseWords 'quotewords';
+use Text::ParseWords qw(quotewords shellwords);
use File::Spec;
use File::Temp;
@@ -260,21 +260,79 @@ sub _parse_line {
return(@pieces);
}
+sub _parsewords {
+ return shellwords @_ if $^O ne 'MSWin32';
+ # for Win32, take off "" but leave \
+ map { my $s=$_; $s =~ s/^"(.*)"$/$1/; $s } grep defined && length, quotewords '\s+', 1, @_;
+}
+
+sub _compile_cmd {
+ my ($Config_cc, $cc, $cfile, $exefile, $incpaths, $ld, $Config_libs, $lib, $libpaths) = @_;
+ my @sys_cmd = @$cc;
+ if ( $Config_cc eq 'cl' ) { # Microsoft compiler
+ # this is horribly sensitive to the order of arguments
+ push @sys_cmd,
+ $cfile,
+ (defined $lib ? "${lib}.lib" : ()),
+ "/Fe$exefile",
+ (map '/I'.$_, @$incpaths),
+ "/link",
+ @$ld,
+ _parsewords($Config_libs),
+ (defined $lib ? map '/libpath:'.$_, @$libpaths : ()),
+ ;
+ } elsif($Config_cc =~ /bcc32(\.exe)?/) { # Borland
+ push @sys_cmd,
+ @$ld,
+ (map "-I$_", @$incpaths),
+ "-o$exefile",
+ (defined $lib ? ((map "-L$_", @$libpaths), "-l$lib") : ()),
+ $cfile,
+ ;
+ } else { # Unix-ish: gcc, Sun, AIX (gcc, cc), ...
+ push @sys_cmd,
+ (map "-I$_", @$incpaths),
+ $cfile,
+ (!defined $lib ? () : (
+ (map "-L$_", @$libpaths),
+ ($^O eq 'darwin' ? (map { "-Wl,-rpath,$_" } @$libpaths) : ()),
+ "-l$lib",
+ )),
+ @$ld,
+ "-o", $exefile,
+ ;
+ }
+ @sys_cmd;
+}
+
+sub _make_cfile {
+ my ($use_headers, $function, $debug) = @_;
+ my $code = '';
+ $code .= qq{#include <$_>\n} for @$use_headers;
+ $code .= "int main(int argc, char *argv[]) { ".($function || 'return 0;')." }\n";
+ if ($debug) {
+ (my $c = $code) =~ s:^:# :gm;
+ warn "# Code:\n$c\n";
+ }
+ my ($ch, $cfile) = File::Temp::tempfile(
+ 'assertlibXXXXXXXX', SUFFIX => '.c'
+ );
+ print $ch $code;
+ close $ch;
+ (my $ofile = $cfile) =~ s/\.c$/$Config{_o}/;
+ ($cfile, $ofile);
+}
+
sub assert_lib {
my %args = @_;
- my (@libs, @libpaths, @headers, @incpaths);
-
- # FIXME: these four just SCREAM "refactor" at me
- @libs = (ref($args{lib}) ? @{$args{lib}} : $args{lib})
- if $args{lib};
- @libpaths = (ref($args{libpath}) ? @{$args{libpath}} : $args{libpath})
- if $args{libpath};
- @headers = (ref($args{header}) ? @{$args{header}} : $args{header})
- if $args{header};
- @incpaths = (ref($args{incpath}) ? @{$args{incpath}} : $args{incpath})
- if $args{incpath};
+ $args{$_} = [$args{$_}]
+ for grep $args{$_} && !ref($args{$_}), qw(lib libpath header incpath);
+ my @libs = @{$args{lib} || []};
+ my @libpaths = @{$args{libpath} || []};
+ my @headers = @{$args{header} || []};
+ my @incpaths = @{$args{incpath} || []};
my $analyze_binary = $args{analyze_binary};
- my $not_execute = $args{not_execute};
+ my $execute = !$args{not_execute};
my @argv = @ARGV;
push @argv, _parse_line('\s+', 0, $ENV{PERL_MM_OPT}||'');
@@ -292,15 +350,14 @@ sub assert_lib {
}
}
- # using special form of split to trim whitespace
if(defined($args{LIBS})) {
- foreach my $arg (split(' ', $args{LIBS})) {
+ foreach my $arg (_parsewords($args{LIBS})) {
die("LIBS argument badly-formed: $arg\n") unless($arg =~ /^-[lLR]/);
push @{$arg =~ /^-l/ ? \@libs : \@libpaths}, substr($arg, 2);
}
}
if(defined($args{INC})) {
- foreach my $arg (split(' ', $args{INC})) {
+ foreach my $arg (_parsewords($args{INC})) {
die("INC argument badly-formed: $arg\n") unless($arg =~ /^-I/);
push @incpaths, substr($arg, 2);
}
@@ -315,45 +372,9 @@ sub assert_lib {
# first figure out which headers we can't find ...
for my $header (@headers) {
push @use_headers, $header;
- my($ch, $cfile) = File::Temp::tempfile(
- 'assertlibXXXXXXXX', SUFFIX => '.c'
- );
- my $ofile = $cfile;
- $ofile =~ s/\.c$/$Config{_o}/;
- print $ch qq{#include <$_>\n} for @use_headers;
- print $ch qq{int main(void) { return 0; }\n};
- close($ch);
+ my ($cfile, $ofile) = _make_cfile(\@use_headers, '', $args{debug});
my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe};
- my @sys_cmd;
- # FIXME: re-factor - almost identical code later when linking
- if ( $Config{cc} eq 'cl' ) { # Microsoft compiler
- require Win32;
- @sys_cmd = (
- @$cc,
- $cfile,
- "/Fe$exefile",
- (map { '/I'.Win32::GetShortPathName($_) } @incpaths),
- "/link",
- @$ld,
- split(' ', $Config{libs}),
- );
- } elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland
- @sys_cmd = (
- @$cc,
- @$ld,
- (map { "-I$_" } @incpaths),
- "-o$exefile",
- $cfile
- );
- } else { # Unix-ish: gcc, Sun, AIX (gcc, cc), ...
- @sys_cmd = (
- @$cc,
- (map { "-I$_" } @incpaths),
- $cfile,
- @$ld,
- "-o", "$exefile"
- );
- }
+ my @sys_cmd = _compile_cmd($Config{cc}, $cc, $cfile, $exefile, \@incpaths, $ld, $Config{libs});
warn "# @sys_cmd\n" if $args{debug};
my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
push @missing, $header if $rv != 0 || ! -f $exefile;
@@ -362,58 +383,13 @@ sub assert_lib {
}
# now do each library in turn with headers
- my($ch, $cfile) = File::Temp::tempfile(
- 'assertlibXXXXXXXX', SUFFIX => '.c'
- );
- my $ofile = $cfile;
- $ofile =~ s/\.c$/$Config{_o}/;
- print $ch qq{#include <$_>\n} foreach (@headers);
- print $ch "int main(int argc, char *argv[]) { ".($args{function} || 'return 0;')." }\n";
- close($ch);
+ my ($cfile, $ofile) = _make_cfile(\@use_headers, @args{qw(function debug)});
for my $lib ( @libs ) {
+ last if $Config{cc} eq 'CC/DECC'; # VMS
my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe};
- my @sys_cmd;
- if ( $Config{cc} eq 'cl' ) { # Microsoft compiler
- require Win32;
- my @libpath = map {
- q{/libpath:} . Win32::GetShortPathName($_)
- } @libpaths;
- # this is horribly sensitive to the order of arguments
- @sys_cmd = (
- @$cc,
- $cfile,
- "${lib}.lib",
- "/Fe$exefile",
- (map { '/I'.Win32::GetShortPathName($_) } @incpaths),
- "/link",
- @$ld,
- split(' ', $Config{libs}),
- (map {'/libpath:'.Win32::GetShortPathName($_)} @libpaths),
- );
- } elsif($Config{cc} eq 'CC/DECC') { # VMS
- } elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland
- @sys_cmd = (
- @$cc,
- @$ld,
- "-o$exefile",
- (map { "-I$_" } @incpaths),
- (map { "-L$_" } @libpaths),
- "-l$lib",
- $cfile);
- } else { # Unix-ish
- # gcc, Sun, AIX (gcc, cc)
- @sys_cmd = (
- @$cc,
- (map { "-I$_" } @incpaths),
- $cfile,
- (map { "-L$_" } @libpaths),
- "-l$lib",
- @$ld,
- "-o", "$exefile",
- );
- }
+ my @sys_cmd = _compile_cmd($Config{cc}, $cc, $cfile, $exefile, \@incpaths, $ld, $Config{libs}, $lib, \@libpaths);
warn "# @sys_cmd\n" if $args{debug};
- local $ENV{LD_RUN_PATH} = join(":", grep $_, @libpaths, $ENV{LD_RUN_PATH}) unless $^O eq 'MSWin32';
+ local $ENV{LD_RUN_PATH} = join(":", grep $_, @libpaths, $ENV{LD_RUN_PATH}) unless $^O eq 'MSWin32' or $^O eq 'darwin';
local $ENV{PATH} = join(";", @libpaths).";".$ENV{PATH} if $^O eq 'MSWin32';
my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
if ($rv != 0 || ! -f $exefile) {
@@ -423,24 +399,24 @@ sub assert_lib {
chmod 0755, $exefile;
my $absexefile = File::Spec->rel2abs($exefile);
$absexefile = '"'.$absexefile.'"' if $absexefile =~ m/\s/;
- if (!$not_execute && system($absexefile) != 0) {
- push @wrongresult, $lib;
- }
- else {
- if ($analyze_binary) {
- push @wronganalysis, $lib if !$analyze_binary->($lib, $exefile)
- }
+ warn "# Execute($execute): $absexefile\n" if $args{debug};
+ if ($execute) {
+ my $retval = system($absexefile);
+ warn "# return value: $retval\n" if $args{debug};
+ push @wrongresult, $lib if $retval != 0;
}
+ push @wronganalysis, $lib
+ if $analyze_binary and !$analyze_binary->($lib, $exefile);
}
_cleanup_exe($exefile);
- }
+ }
unlink $cfile;
- my $miss_string = join( q{, }, map { qq{'$_'} } @missing );
+ my $miss_string = join( q{, }, map qq{'$_'}, @missing );
die("Can't link/include C library $miss_string, aborting.\n") if @missing;
- my $wrong_string = join( q{, }, map { qq{'$_'} } @wrongresult);
+ my $wrong_string = join( q{, }, map qq{'$_'}, @wrongresult);
die("wrong result: $wrong_string\n") if @wrongresult;
- my $analysis_string = join(q{, }, map { qq{'$_'} } @wronganalysis );
+ my $analysis_string = join(q{, }, map qq{'$_'}, @wronganalysis );
die("wrong analysis: $analysis_string") if @wronganalysis;
}
@@ -459,14 +435,12 @@ sub _cleanup_exe {
$pdbfile =~ s/$Config{_exe}$/.pdb/;
push @rmfiles, $ilkfile, $pdbfile;
}
- foreach (@rmfiles) {
- if ( -f $_ ) {
- unlink $_ or warn "Could not remove $_: $!";
- }
+ foreach (grep -f, @rmfiles) {
+ unlink $_ or warn "Could not remove $_: $!";
}
return
}
-
+
# return ($cc, $ld)
# where $cc is an array ref of compiler name, compiler flags
# where $ld is an array ref of linker flags
@@ -474,14 +448,15 @@ sub _findcc {
my ($debug, $user_ccflags, $user_ldflags) = @_;
# Need to use $keep=1 to work with MSWin32 backslashes and quotes
my $Config_ccflags = $Config{ccflags}; # use copy so ASPerl will compile
+ $Config_ccflags =~ s:-O\S*::; # stop GCC optimising away test code
my @Config_ldflags = ();
for my $config_val ( @Config{qw(ldflags)} ){
push @Config_ldflags, $config_val if ( $config_val =~ /\S/ );
}
- my @ccflags = grep { length } quotewords('\s+', 1, $Config_ccflags||'', $user_ccflags||'');
- my @ldflags = grep { length && $_ !~ m/^-Wl/ } quotewords('\s+', 1, @Config_ldflags, $user_ldflags||'');
+ my @ccflags = grep { length } _parsewords($Config_ccflags||'', $user_ccflags||'');
+ my @ldflags = grep { length && $_ !~ m/^-Wl/ } _parsewords(@Config_ldflags, $user_ldflags||'');
my @paths = split(/$Config{path_sep}/, $ENV{PATH});
- my @cc = split(/\s+/, $Config{cc});
+ my @cc = _parsewords($Config{cc});
if (check_compiler ($cc[0], $debug)) {
return ( [ @cc, @ccflags ], \@ldflags );
}
@@ -510,11 +485,10 @@ sub check_compiler
{
my ($compiler, $debug) = @_;
if (-f $compiler && -x $compiler) {
- if ($debug) {
- warn("# Compiler seems to be $compiler\n");
- }
+ warn "# Compiler seems to be $compiler\n" if $debug;
return 1;
}
+ warn "# Compiler was not $compiler\n" if $debug;
return '';
}
diff --git a/t/exit_with_message.t b/t/exit_with_message.t
index 67daae1..b79d207 100644
--- a/t/exit_with_message.t
+++ b/t/exit_with_message.t
@@ -12,7 +12,7 @@ check_lib_or_exit( qw/lib hlagh/ );
ENDPRINT
$fh->close;
-my $err = `$^X $fh 2>&1`;
+my $err = `"$^X" $fh 2>&1`;
if($err =~ /Couldn't find your C compiler/) {
plan skip_all => "Couldn't find your C compiler";
diff --git a/t/lib/Helper.pm b/t/lib/Helper.pm
index f298c71..ca08b35 100644
--- a/t/lib/Helper.pm
+++ b/t/lib/Helper.pm
@@ -43,7 +43,7 @@ sub create_testlib {
print {$code_fh} "int libversion() { return 42; }\nint foo() { return 0; }\n";
$code_fh->close;
- my $cc = $Config{cc};
+ my $cc = (split(/\s+/, $Config{cc}))[0];
my $gccv = $Config{gccversion};
my $rv =
$cc eq 'gcc' ? _gcc_lib( $libname ) :
@@ -62,20 +62,19 @@ sub _gcc_lib {
my $ar = find_binary('ar') or return;
my $ranlib = find_binary('ranlib') or return;
my $ccflags = $Config{ccflags};
-
- _quiet_system("$cc $ccflags -c ${libname}.c") and return;
- _quiet_system("$ar rc lib${libname}.a ${libname}.o") and return;
- _quiet_system("$ranlib lib${libname}.a") and return;
- return -f "lib${libname}.a"
+ my $libfile = "lib${libname}.a";
+ _quiet_system(qq{"$cc" $ccflags -c ${libname}.c}) and return;
+ _quiet_system($ar, 'rc', $libfile, "${libname}$Config{_o}") and return;
+ _quiet_system($ranlib, $libfile) and return;
+ return -f $libfile
}
sub _cl_lib {
my ($libname) = @_;
my $cc = find_compiler() or return;
my $ar = find_binary('lib') or return;
-
_quiet_system($cc, '/c', "${libname}.c") and return;
- _quiet_system($ar, "${libname}.obj") and return;
+ _quiet_system($ar, "${libname}$Config{_o}") and return;
return -f "${libname}.lib";
}
@@ -115,7 +114,14 @@ sub lib_to_bin {
}
sub find_compiler {
- return find_binary($Config{cc});
+ my $result = find_binary($Config{cc});
+ return $result if($result);
+
+ # sometimes $Config{cc} isn't very clean eg it can be 'cc -q32' on AIX
+ return find_binary((split(/\s+/, $Config{cc}))[0])
+ if($Config{cc} =~ /\s/);
+
+ undef;
}
1; # must be true
diff --git a/t/multi-word-compiler.t b/t/multi-word-compiler.t
index 1fe415a..c9c0f86 100644
--- a/t/multi-word-compiler.t
+++ b/t/multi-word-compiler.t
@@ -20,19 +20,20 @@ BEGIN {
}
}
+my $fake_cc = qq{"$^X" $Config{cc}};
if ($Mock::Config::VERSION) {
- Mock::Config->import(cc => "$^X $Config{cc}");
+ Mock::Config->import(cc => $fake_cc);
}
elsif (defined($ActivePerl::VERSION) && $Config{cc} =~ /\bgcc\b/) {
my $obj = tied %Config::Config;
- $obj->{cc} = "$^X $Config{cc}";
+ $obj->{cc} = $fake_cc;
}
else {
- eval { $Config{cc} = "$^X $Config{cc}"; }
+ eval { $Config{cc} = $fake_cc; }
}
SKIP: {
skip "Couldn't update %Config", 1 if $@ =~ /%Config::Config is read-only/;
eval "use Devel::CheckLib";
- ok(!$@, "Good multi-word compiler is OK");
+ is $@, "", "Good multi-word compiler is OK";
}