Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37512779
en ru br
Репозитории ALT

Группа :: Разработка/Perl
Пакет: perl-Devel-CheckLib

 Главная   Изменения   Спек   Патчи   Исходники   Загрузить   Gear   Bugs and FR  Repocop 

Devel-CheckLib-1.01/000075500000000000000000000000001222430313200141225ustar00rootroot00000000000000Devel-CheckLib-1.01/CHANGES000064400000000000000000000042151222430313200151170ustar00rootroot000000000000001.01    2013-07-26      Correct version

1.00 2013-07-26 Deprecate use-devel-checklib script.

0.99 2013-04-02 Allow -R rpaths as libpaths used with solaris cc
(see RT #81330)

0.98 2012-03-17 Merge ldflags & perllibs.

0.97 2012-02-02 Fixed test.

0.96 2012-02-02 Pass linker options to MSVC.

0.95 2011-10-22 Clean up object files.
Also MSVC generates extra files, clean them up.

0.94 2011-10-14 Better error message.

0.93 2011-04-09 Add support for gcc that have version number in the command name.
Fix about that the command path include space character.

0.92 2010-12-13 Patch included, thanks to CHM and SISYPHUS (see RT #63742)

0.91 2010-09-29 Version bump up.

0.9 2010-09-29 Fix deprecated parenthesis. use "(qw())".

0.8 2010-09-15 Add include header files into dependencies files.
(see RT #61297)
Add minimum version number of perl.

0.7 2010-08-25 Add support for checking if a function exists
in a library and it returns the right value
(see RT #48332)
Add check_lib function

0.6 2009-05-20 Support EU::MM-stylee command line, thanks to
DAXIM (see RT #46044)

0.5 2008-03-12 Break up 'package Devel::CheckLib' in inc/ so
distributions including it don't get marked
as 'unauthorised'

0.4 2008-03-04 Look for headers as well as libraries;
Clean up temp dirs in tests;
use-devel-checklib fixed for Win32

0.3 2007-10-30 tests now skip when they need a compiler and can't
find one;
Borland compiler support;
added bin/use-devel-checklib script;
added EU::MM-stylee LIBS support

0.2 2007-10-18 better portability, more features
Renamed to Devel::CheckLib

0.1 2007-10-14 Initial release
Devel-CheckLib-1.01/MANIFEST000064400000000000000000000007501222430313200152550ustar00rootroot00000000000000CHANGES
lib/Devel/CheckLib.pm
Makefile.PL
MANIFEST
README
t/00-load.t
t/exit_with_message.t
t/found.t
t/lib/Helper.pm
t/not_found.t
TODO
bin/use-devel-checklib
t/multi-word-compiler.t
t/bad-single-word-compiler.t
t/dash-l-libs.t
t/headers.t
t/inc/headerfile.h
VMS-notes
t/coverage.sh
t/cmdline-LIBS-INC.t
t/custom-function.t
META.yml Module meta-data (added by MakeMaker)
META.json Module JSON meta-data (added by MakeMaker)
Devel-CheckLib-1.01/META.json000064400000000000000000000020741222430313200155460ustar00rootroot00000000000000{
"abstract" : "unknown",
"author" : [
"unknown"
],
"dynamic_config" : 1,
"generated_by" : "ExtUtils::MakeMaker version 6.72, CPAN::Meta::Converter version 2.120351",
"license" : [
"perl_5"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : "2"
},
"name" : "Devel-CheckLib",
"no_index" : {
"directory" : [
"t",
"inc"
]
},
"prereqs" : {
"build" : {
"requires" : {
"IO::CaptureOutput" : "1.0801",
"Test::More" : "0.62"
}
},
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"runtime" : {
"requires" : {
"Exporter" : "0",
"File::Spec" : "0",
"File::Temp" : "0.16",
"perl" : "5.00405"
}
}
},
"release_status" : "stable",
"resources" : {
"repository" : {
"url" : "http://github.com/mattn/p5-Devel-CheckLib"
}
},
"version" : "1.01"
}
Devel-CheckLib-1.01/META.yml000064400000000000000000000011021222430313200153650ustar00rootroot00000000000000---
abstract: unknown
author:
- unknown
build_requires:
IO::CaptureOutput: 1.0801
Test::More: 0.62
configure_requires:
ExtUtils::MakeMaker: 0
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 6.72, CPAN::Meta::Converter version 2.120351'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: 1.4
name: Devel-CheckLib
no_index:
directory:
- t
- inc
requires:
Exporter: 0
File::Spec: 0
File::Temp: 0.16
perl: 5.00405
resources:
repository: http://github.com/mattn/p5-Devel-CheckLib
version: 1.01
Devel-CheckLib-1.01/Makefile.PL000064400000000000000000000034031222430313200160740ustar00rootroot00000000000000# $Id: Makefile.PL,v 1.6 2008/03/04 21:49:19 drhyde Exp $

use 5.00405;
use ExtUtils::MakeMaker;

use strict;
$^W = 1;

WriteMakefile1(
NAME => 'Devel::CheckLib',
VERSION_FROM => 'lib/Devel/CheckLib.pm',
PREREQ_PM => {
'File::Temp' => 0.16,
'Exporter' => 0,
'File::Spec' => 0,
},
MIN_PERL_VERSION => '5.00405',
META_MERGE => {
resources => {
repository => 'http://github.com/mattn/p5-Devel-CheckLib',
},
},
BUILD_REQUIRES => {
'Test::More' => 0.62, # too high? but API changed here
'IO::CaptureOutput' => 1.0801,
},
LICENSE => 'perl',
EXE_FILES => [qw(
bin/use-devel-checklib
)],
);

sub WriteMakefile1 { #Written by Alexandr Ciornii, version 0.21. Added by eumm-upgrade.
my %params=@_;
my $eumm_version=$ExtUtils::MakeMaker::VERSION;
$eumm_version=eval $eumm_version;
die "EXTRA_META is deprecated" if exists $params{EXTRA_META};
die "License not specified" if not exists $params{LICENSE};
if ($params{BUILD_REQUIRES} and $eumm_version < 6.5503) {
#EUMM 6.5502 has problems with BUILD_REQUIRES
$params{PREREQ_PM}={ %{$params{PREREQ_PM} || {}} , %{$params{BUILD_REQUIRES}} };
delete $params{BUILD_REQUIRES};
}
delete $params{CONFIGURE_REQUIRES} if $eumm_version < 6.52;
delete $params{MIN_PERL_VERSION} if $eumm_version < 6.48;
delete $params{META_MERGE} if $eumm_version < 6.46;
delete $params{META_ADD} if $eumm_version < 6.46;
delete $params{LICENSE} if $eumm_version < 6.31;
delete $params{AUTHOR} if $] < 5.005;
delete $params{ABSTRACT_FROM} if $] < 5.005;
delete $params{BINARY_LOCATION} if $] < 5.005;

WriteMakefile(%params);
}

Devel-CheckLib-1.01/README000064400000000000000000000004011222430313200147750ustar00rootroot00000000000000This module provides a way of checking whether a particular library and
its headers are available, by attempting to compile a simple program and
link against it.

To install, do the usual dance:

perl Makefile.PL
make
make test
make install
Devel-CheckLib-1.01/TODO000064400000000000000000000000351222430313200146100ustar00rootroot00000000000000SGI (maybe)
VMS

pkg-config?
Devel-CheckLib-1.01/VMS-notes000064400000000000000000000035761222430313200156530ustar00rootroot00000000000000http://perl-qa.hexten.net/wiki/index.php/Testing_on_VMS

---

15:32 <anomenat> well $Config{cc} will contain 'CC/DECC', which is the right
command to use but "if -x $cc[0]" will fail
15:33 <anomenat> then "CC/DECC foo.c" will compile foo.c to foo.obj
15:37 <DrHyde> how do i pass include paths?
15:38 <anomenat> CC/DECC/INCLUDE_DIRECTORY=foo
15:39 <anomenat> I'm still trying to work out the best way to do the linking
bit though
15:40 <DrHyde> is CC/DECC/INCLUDE_DIRECTORY=foo/INCLUDE_DIRECTORY=bar valid?
15:41 <anomenat> yes
15:41 <DrHyde> hurrah!
15:41 <anomenat> I'm still trying to work out the best way to do linking though
16:17 <anomenat> well, buggered if I can find a standard place to put libraries
on VMS. There probably is one but my VMS skills are too weak.
16:17 <anomenat> anyway, the command is just "LINK foo.obj, bar.obj" where foo
is the previously compiled foo.c and bar is the library whose
presence you are testing for
16:18 <anomenat> but it won't be very portable because "bar.obj" needs to be a
proper path, unless it is a system library
16:26 <DrHyde> that's a good start, so thanks!
16:34 <anomenat> no problem. incidentally, VMS command line options can be
shortened to their shortest unambiguous form, and so
/include_directory can actually just be /inc
16:50 <anomenat> OK, it looks like SYS$LIBRARY is the VMS sort-of-equivalent of
/usr/lib on Linux
16:52 <anomenat> thus "LINK foo.obj, sys$library:vaxcrtl/share" links foo.obj
with the shared library vaxctrl
16:54 <anomenat> and "LINK foo.obj, sys$library:ucx$ipc/library" links foo.obj
with the static library ucx$ipc
16:54 <anomenat> also, "link/exe=bar.exe foo.obj" links foo.obj to create an
executable called bar.exe
Devel-CheckLib-1.01/bin/000075500000000000000000000000001222430313200146725ustar00rootroot00000000000000Devel-CheckLib-1.01/bin/use-devel-checklib000075500000000000000000000053171222430313200202610ustar00rootroot00000000000000#!perl -w
# $Id: use-devel-checklib,v 1.9 2008/03/12 19:52:50 drhyde Exp $

use strict;

$/ = undef;

use File::Spec;
use Devel::CheckLib;

warn "----------------------- [WARNING] --------\n";
warn "THIS SCRIPT WAS DEPRECATED.\n";
warn "YOU SHOULD USE configure_requires INSTEAD.\n";
warn "---------- [/WARNING] --------------------\n";

my @files = grep { -f $_ } qw(Makefile.PL Build.PL);
push @files, 'Makefile.PL' unless(@files);

my @libs = @ARGV;

mkdir 'inc';
mkdir 'inc/Devel';

open(CHECKLIBPM, $INC{'Devel/CheckLib.pm'}) ||
die("Can't read $INC{'Devel/CheckLib.pm'}: $!");
(my $checklibpm = <CHECKLIBPM>) =~ s/package Devel::CheckLib/package #\nDevel::CheckLib/;
close(CHECKLIBPM);
open(CHECKLIBPM, '>'.File::Spec->catfile(qw(inc Devel CheckLib.pm))) ||
die("Can't write inc/Devel/CheckLib.pm: $!");
print CHECKLIBPM $checklibpm;
close(CHECKLIBPM);

print "Copied Devel::CheckLib to inc/ directory\n";

foreach my $file (@files) {
open(FILE, $file) || next;
my $contents = <FILE>;
close(FILE);
open(FILE, ">$file") || die("Can't write $file\n");
print FILE q{use lib qw(inc);
use Devel::CheckLib;

# Prompt the user here for any paths and other configuration

check_lib_or_exit(
# fill in what you prompted the user for here
lib => [qw(}.join(' ', @libs).q{)]
);
};
print FILE "\n\n$contents";
close(FILE);
print "Updated/created $file\n";
}

open(MANIFEST, 'MANIFEST') || warn("Couldn't read MANIFEST, will create one\n");
my $manifest = <MANIFEST>;
close(MANIFEST);
open(MANIFEST, '>MANIFEST') || die("Couldn't write MANIFEST\n");
print MANIFEST "inc/Devel/CheckLib.pm\n$manifest";
close(MANIFEST);
print "Updated/created MANIFEST\n";

=head1 NAME

use-devel-checklib - (DEPRECATED)a script to package Devel::CheckLib with your code.

=head1 DESCRIPTION

This script was DEPRECATED.

If you need to depend on this library, you should use `configure_requires` in Makefile.PL or Build.PL instead.

=head1 WARNINGS, BUGS and FEEDBACK

This script has not been thoroughly tested. You should check by
hand that it has done what you expected after running it.

If you use Module::Build::Compat to write a Makefile.PL, then you
will need to re-run this script whenever you have generated a new
Makefile.PL.

I welcome feedback about my code, including constructive criticism.
Bug reports should be made using L<http://rt.cpan.org/> or by email.

=head1 SEE ALSO

L<Devel::CheckLib>

=head1 AUTHOR

David Cantrell E<lt>F<david@cantrell.org.uk>E<gt>

=head1 COPYRIGHT and LICENCE

Copyright 2007 David Cantrell

This software is free-as-in-speech software, and may be used,
distributed, and modified under the same conditions as perl itself.

=head1 CONSPIRACY

This module is also free-as-in-mason software.

=cut
Devel-CheckLib-1.01/lib/000075500000000000000000000000001222430313200146705ustar00rootroot00000000000000Devel-CheckLib-1.01/lib/Devel/000075500000000000000000000000001222430313200157275ustar00rootroot00000000000000Devel-CheckLib-1.01/lib/Devel/CheckLib.pm000064400000000000000000000354371222430313200177450ustar00rootroot00000000000000# $Id: CheckLib.pm,v 1.25 2008/10/27 12:16:23 drhyde Exp $

package Devel::CheckLib;

use 5.00405; #postfix foreach
use strict;
use vars qw($VERSION @ISA @EXPORT);
$VERSION = '1.01';
use Config qw(%Config);
use Text::ParseWords 'quotewords';

use File::Spec;
use File::Temp;

require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(assert_lib check_lib_or_exit check_lib);

# localising prevents the warningness leaking out of this module
local $^W = 1; # use warnings is a 5.6-ism

_findcc(); # bomb out early if there's no compiler

=head1 NAME

Devel::CheckLib - check that a library is available

=head1 DESCRIPTION

Devel::CheckLib is a perl module that checks whether a particular C
library and its headers are available.

=head1 SYNOPSIS

use Devel::CheckLib;

check_lib_or_exit( lib => 'jpeg', header => 'jpeglib.h' );
check_lib_or_exit( lib => [ 'iconv', 'jpeg' ] );

# or prompt for path to library and then do this:
check_lib_or_exit( lib => 'jpeg', libpath => $additional_path );

=head1 USING IT IN Makefile.PL or Build.PL

If you want to use this from Makefile.PL or Build.PL, do
not simply copy the module into your distribution as this may cause
problems when PAUSE and search.cpan.org index the distro. Instead, use
the use-devel-checklib script.

=head1 HOW IT WORKS

You pass named parameters to a function, describing to it how to build
and link to the libraries.

It works by trying to compile some code - which defaults to this:

int main(void) { return 0; }

and linking it to the specified libraries. If something pops out the end
which looks executable, it gets executed, and if main() returns 0 we know
that it worked. That tiny program is
built once for each library that you specify, and (without linking) once
for each header file.

If you want to check for the presence of particular functions in a
library, or even that those functions return particular results, then
you can pass your own function body for main() thus:

check_lib_or_exit(
function => 'foo();if(libversion() > 5) return 0; else return 1;'
incpath => ...
libpath => ...
lib => ...
header => ...
);

In that case, it will fail to build if either foo() or libversion() don't
exist, and main() will return the wrong value if libversion()'s return
value isn't what you want.

=head1 FUNCTIONS

All of these take the same named parameters and are exported by default.
To avoid exporting them, C<use Devel::CheckLib ()>.

=head2 assert_lib

This takes several named parameters, all of which are optional, and dies
with an error message if any of the libraries listed can
not be found. B<Note>: dying in a Makefile.PL or Build.PL may provoke
a 'FAIL' report from CPAN Testers' automated smoke testers. Use
C<check_lib_or_exit> instead.

The named parameters are:

=over

=item lib

Must be either a string with the name of a single
library or a reference to an array of strings of library names. Depending
on the compiler found, library names will be fed to the compiler either as
C<-l> arguments or as C<.lib> file names. (E.g. C<-ljpeg> or C<jpeg.lib>)

=item libpath

a string or an array of strings
representing additional paths to search for libraries.

=item LIBS

a C<ExtUtils::MakeMaker>-style space-seperated list of
libraries (each preceded by '-l') and directories (preceded by '-L').

This can also be supplied on the command-line.

=item debug

If true - emit information during processing that can be used for
debugging.

=back

And libraries are no use without header files, so ...

=over

=item header

Must be either a string with the name of a single
header file or a reference to an array of strings of header file names.

=item incpath

a string or an array of strings
representing additional paths to search for headers.

=item INC

a C<ExtUtils::MakeMaker>-style space-seperated list of
incpaths, each preceded by '-I'.

This can also be supplied on the command-line.

=back

=head2 check_lib_or_exit

This behaves exactly the same as C<assert_lib()> except that instead of
dieing, it warns (with exactly the same error message) and exits.
This is intended for use in Makefile.PL / Build.PL
when you might want to prompt the user for various paths and
things before checking that what they've told you is sane.

If any library or header is missing, it exits with an exit value of 0 to avoid
causing a CPAN Testers 'FAIL' report. CPAN Testers should ignore this
result -- which is what you want if an external library dependency is not
available.

=head2 check_lib

This behaves exactly the same as C<assert_lib()> except that it is silent,
returning false instead of dieing, or true otherwise.

=cut

sub check_lib_or_exit {
eval 'assert_lib(@_)';
if($@) {
warn $@;
exit;
}
}

sub check_lib {
eval 'assert_lib(@_)';
return $@ ? 0 : 1;
}

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};

# work-a-like for Makefile.PL's LIBS and INC arguments
# if given as command-line argument, append to %args
for my $arg (@ARGV) {
for my $mm_attr_key (qw(LIBS INC)) {
if (my ($mm_attr_value) = $arg =~ /\A $mm_attr_key = (.*)/x) {
# it is tempting to put some \s* into the expression, but the
# MM command-line parser only accepts LIBS etc. followed by =,
# so we should not be any more lenient with whitespace than that
$args{$mm_attr_key} .= " $mm_attr_value";
}
}
}

# using special form of split to trim whitespace
if(defined($args{LIBS})) {
foreach my $arg (split(' ', $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})) {
die("INC argument badly-formed: $arg\n") unless($arg =~ /^-I/);
push @incpaths, substr($arg, 2);
}
}

my ($cc, $ld) = _findcc();
my @missing;
my @wrongresult;
my @use_headers;

# 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 $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
);
} 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,
@$ld,
$cfile,
(map { "-I$_" } @incpaths),
"-o", "$exefile"
);
}
warn "# @sys_cmd\n" if $args{debug};
my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
push @missing, $header if $rv != 0 || ! -x $exefile;
_cleanup_exe($exefile);
unlink $ofile if -e $ofile;
unlink $cfile;
}

# 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(void) { ".($args{function} || 'return 0;')." }\n";
close($ch);
for my $lib ( @libs ) {
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,
(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,
@$ld,
$cfile,
"-o", "$exefile",
(map { "-I$_" } @incpaths),
(map { "-L$_" } @libpaths),
"-l$lib",
);
}
warn "# @sys_cmd\n" if $args{debug};
my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
push @missing, $lib if $rv != 0 || ! -x $exefile;
my $absexefile = File::Spec->rel2abs($exefile);
$absexefile = '"'.$absexefile.'"' if $absexefile =~ m/\s/;
push @wrongresult, $lib if $rv == 0 && -x $exefile && system($absexefile) != 0;
unlink $ofile if -e $ofile;
_cleanup_exe($exefile);
}
unlink $cfile;

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);
die("wrong result: $wrong_string\n") if @wrongresult;
}

sub _cleanup_exe {
my ($exefile) = @_;
my $ofile = $exefile;
$ofile =~ s/$Config{_exe}$/$Config{_o}/;
unlink $exefile if -f $exefile;
unlink $ofile if -f $ofile;
unlink "$exefile\.manifest" if -f "$exefile\.manifest";
if ( $Config{cc} eq 'cl' ) {
# MSVC also creates foo.ilk and foo.pdb
my $ilkfile = $exefile;
$ilkfile =~ s/$Config{_exe}$/.ilk/;
my $pdbfile = $exefile;
$pdbfile =~ s/$Config{_exe}$/.pdb/;
unlink $ilkfile if -f $ilkfile;
unlink $pdbfile if -f $pdbfile;
}
return
}

# return ($cc, $ld)
# where $cc is an array ref of compiler name, compiler flags
# where $ld is an array ref of linker flags
sub _findcc {
# Need to use $keep=1 to work with MSWin32 backslashes and quotes
my $Config_ccflags = $Config{ccflags}; # use copy so ASPerl will compile
my @Config_ldflags = ();
for my $config_val ( @Config{qw(ldflags perllibs)} ){
push @Config_ldflags, $config_val if ( $config_val =~ /\S/ );
}
my @ccflags = grep { length } quotewords('\s+', 1, $Config_ccflags||'');
my @ldflags = grep { length } quotewords('\s+', 1, @Config_ldflags);
my @paths = split(/$Config{path_sep}/, $ENV{PATH});
my @cc = split(/\s+/, $Config{cc});
return ( [ @cc, @ccflags ], \@ldflags ) if -x $cc[0];
foreach my $path (@paths) {
my $compiler = File::Spec->catfile($path, $cc[0]) . $Config{_exe};
return ([ $compiler, @cc[1 .. $#cc], @ccflags ], \@ldflags)
if -x $compiler;
}
die("Couldn't find your C compiler\n");
}

# code substantially borrowed from IPC::Run3
sub _quiet_system {
my (@cmd) = @_;

# save handles
local *STDOUT_SAVE;
local *STDERR_SAVE;
open STDOUT_SAVE, ">&STDOUT" or die "CheckLib: $! saving STDOUT";
open STDERR_SAVE, ">&STDERR" or die "CheckLib: $! saving STDERR";

# redirect to nowhere
local *DEV_NULL;
open DEV_NULL, ">" . File::Spec->devnull
or die "CheckLib: $! opening handle to null device";
open STDOUT, ">&" . fileno DEV_NULL
or die "CheckLib: $! redirecting STDOUT to null handle";
open STDERR, ">&" . fileno DEV_NULL
or die "CheckLib: $! redirecting STDERR to null handle";

# run system command
my $rv = system(@cmd);

# restore handles
open STDOUT, ">&" . fileno STDOUT_SAVE
or die "CheckLib: $! restoring STDOUT handle";
open STDERR, ">&" . fileno STDERR_SAVE
or die "CheckLib: $! restoring STDERR handle";

return $rv;
}

=head1 PLATFORMS SUPPORTED

You must have a C compiler installed. We check for C<$Config{cc}>,
both literally as it is in Config.pm and also in the $PATH.

It has been tested with varying degrees on rigourousness on:

=over

=item gcc (on Linux, *BSD, Mac OS X, Solaris, Cygwin)

=item Sun's compiler tools on Solaris

=item IBM's tools on AIX

=item SGI's tools on Irix 6.5

=item Microsoft's tools on Windows

=item MinGW on Windows (with Strawberry Perl)

=item Borland's tools on Windows

=item QNX

=back

=head1 WARNINGS, BUGS and FEEDBACK

This is a very early release intended primarily for feedback from
people who have discussed it. The interface may change and it has
not been adequately tested.

Feedback is most welcome, including constructive criticism.
Bug reports should be made using L<http://rt.cpan.org/> or by email.

When submitting a bug report, please include the output from running:

perl -V
perl -MDevel::CheckLib -e0

=head1 SEE ALSO

L<Devel::CheckOS>

L<Probe::Perl>

=head1 AUTHORS

David Cantrell E<lt>david@cantrell.org.ukE<gt>

David Golden E<lt>dagolden@cpan.orgE<gt>

Yasuhiro Matsumoto E<lt>mattn@cpan.orgE<gt>

Thanks to the cpan-testers-discuss mailing list for prompting us to write it
in the first place;

to Chris Williams for help with Borland support;

to Tony Cook for help with Microsoft compiler command-line options

=head1 COPYRIGHT and LICENCE

Copyright 2007 David Cantrell. Portions copyright 2007 David Golden.

This module is free-as-in-speech software, and may be used, distributed,
and modified under the same conditions as perl itself.

=head1 CONSPIRACY

This module is also free-as-in-mason software.

=cut

1;
Devel-CheckLib-1.01/t/000075500000000000000000000000001222430313200143655ustar00rootroot00000000000000Devel-CheckLib-1.01/t/00-load.t000064400000000000000000000003501222430313200157040ustar00rootroot00000000000000use strict;
# compatible use warnings
BEGIN{ if (not $] < 5.006) { require warnings; warnings->import } }

use Test::More tests => 1;

eval "use Devel::CheckLib";
ok($@ =~ /Couldn't find your C compiler/ || !$@, "Can load module");
Devel-CheckLib-1.01/t/bad-single-word-compiler.t000064400000000000000000000014601222430313200213410ustar00rootroot00000000000000# $Id: bad-single-word-compiler.t,v 1.2 2008/02/07 14:16:39 drhyde Exp $

use strict;
BEGIN{ if (not $] < 5.006) { require warnings; warnings->import } }

use Test::More;

plan tests => 1;

use Config;
BEGIN {
BEGIN { if (not $] < 5.006 ) { warnings->unimport('redefine') } }
unless(defined($ActivePerl::VERSION) && $Config{cc} =~ /\bgcc\b/) {
*Config::STORE = sub { $_[0]->{$_[1]} = $_[2] }
}
}

if(defined($ActivePerl::VERSION) && $Config{cc} =~ /\bgcc\b/) {
my $obj = tied %Config::Config;
$obj->{cc} = "flibbertigibbet";
}
else {
eval { $Config{cc} = 'flibbertigibbet' };
}

SKIP: {
skip "Couldn't update %Config", 1 if $@ =~ /%Config::Config is read-only/;
eval "use Devel::CheckLib";
ok($@ =~ /^Couldn't find your C compiler/, "Bad single-word compiler is not OK");
}
Devel-CheckLib-1.01/t/cmdline-LIBS-INC.t000064400000000000000000000041431222430313200173250ustar00rootroot00000000000000use strict;
# compatible use warnings
BEGIN{ if (not $] < 5.006) { require warnings; warnings->import } }

use lib 't/lib';
use IO::CaptureOutput qw(capture);
use Config;

use File::Spec;
use Test::More;

my($debug, $stdout, $stderr) = ($ENV{DEVEL_CHECKLIB_DEBUG} || 0);
my $libdir;

eval "use Devel::CheckLib";
if($@ =~ /Couldn't find your C compiler/) { #'
plan skip_all => "Couldn't find your C compiler";
}

eval "use Helper qw(create_testlib)";
if($libdir = create_testlib("bazbam")) {
plan tests => 3;
} else {
plan skip_all => "Couldn't build a library to test against";
};

my $runtime = '-l'.(
$^O eq 'MSWin32' # if Win32 (not Cygwin) ...
? (
$Config{cc} =~ /(^|^\w+ )bcc/
? 'cc3250' # ... Borland
: 'msvcrt' # ... otherwise assume Microsoft
)
: 'm' # default to Unix-style
);

my $rval = undef;
my @args = (qq{LIBS=$runtime});
capture(
sub { $rval = system(
$Config{perlpath},
'-Mblib',
'-MDevel::CheckLib',
'-e',
"print @ARGV;assert_lib(debug => $debug)",
@args
)},
\$stdout,
\$stderr
);
ok($stderr eq '' && defined($rval) && $rval == 0, "linked OK: ".join(', ', @args)) || diag("\tSTDOUT: $stdout\n\tSTDERR: $stderr\n");

$rval = undef;
@args = map { "LIBS=$_" } ($runtime, '-lbazbam', "-L$libdir");
capture(
sub { $rval = system(
$Config{perlpath},
'-Mblib',
'-MDevel::CheckLib',
'-e',
"print @ARGV;assert_lib(debug => $debug)",
@args
)},
\$stdout,
\$stderr
);
ok($stderr eq '' && defined($rval) && $rval == 0, "linked OK: ".join(', ', @args)) || diag("\tSTDOUT: $stdout\n\tSTDERR: $stderr\n");

$rval = undef;
@args = (qq{"LIBS=$runtime -lbazbam -L$libdir"});
capture(
sub { $rval = system(
$Config{perlpath},
'-Mblib',
'-MDevel::CheckLib',
'-e',
"print @ARGV;assert_lib(debug => $debug)",
@args
)},
\$stdout,
\$stderr
);
ok($stderr eq '' && defined($rval) && $rval == 0, "linked OK: ".join(', ', @args)) || diag("\tSTDOUT: $stdout\n\tSTDERR: $stderr\n");
Devel-CheckLib-1.01/t/coverage.sh000075500000000000000000000002101222430313200165100ustar00rootroot00000000000000#!/bin/sh
# $Id: coverage.sh,v 1.1 2008/02/26 21:54:55 drhyde Exp $

cover -delete
HARNESS_PERL_SWITCHES=-MDevel::Cover make test
cover
Devel-CheckLib-1.01/t/custom-function.t000064400000000000000000000045761222430313200177230ustar00rootroot00000000000000use strict;
# compatible use warnings
BEGIN{ if (not $] < 5.006) { require warnings; warnings->import } }

use lib 't/lib';
use IO::CaptureOutput qw(capture);
use Config;

use File::Spec;
use Test::More;

eval "use Devel::CheckLib";
if($@ =~ /Couldn't find your C compiler/) {
plan skip_all => "Couldn't find your C compiler";
}
my $libdir;
eval "use Helper qw(create_testlib)";
unless($libdir = create_testlib("bazbam")) {
plan skip_all => "Couldn't build a library to test against";
};

my($debug, $stdout, $stderr) = ($ENV{DEVEL_CHECKLIB_DEBUG} || 0);

# cases are strings to interpolate into the assert_lib call
my %failcases = (
qq{
incpath => 't/inc',
libpath => '$libdir',
lib => 'bazbam',
header => 'headerfile.h',
# bar() doesn't exist
function => 'bar();'
} => 'Can\'t link/include',
qq{
incpath => 't/inc',
libpath => '$libdir',
lib => 'bazbam',
header => 'headerfile.h',
# libversion returns wrong result
function => 'foo();if(libversion() < 5) return 0; else return 1;'
} => 'wrong result',
);
my %passcases = (
qq{
incpath => 't/inc',
libpath => '$libdir',
lib => 'bazbam',
header => 'headerfile.h',
functionbody => 'foo(); return 0;'
}, "function exists",
qq{
incpath => 't/inc',
libpath => '$libdir',
lib => 'bazbam',
header => 'headerfile.h',
functionbody => 'if(libversion() > 5) return 0; else return 1;'
}, "function returns right value",
qq{
incpath => 't/inc',
libpath => '$libdir',
lib => 'bazbam',
header => 'headerfile.h',
functionbody => 'foo();if(libversion() > 5) return 0; else return 1;'
}, "function exists and other function returns right value",
);

plan tests => scalar(keys %failcases) + scalar(keys %passcases);

for my $c (keys %failcases) {
capture(
sub { eval "assert_lib(debug => $debug, $c)"; },
\$stdout,
\$stderr
);
ok($@ =~ /^$failcases{$c}/, "failed to build: $failcases{$c}") ||
diag("$c\n$@\n\tSTDOUT: $stdout\n\tSTDERR: $stderr\n");
}
for my $c ( keys %passcases ) {
capture(
sub { eval "assert_lib(debug => $debug, $c)"; },
\$stdout,
\$stderr
);
is($@, q{}, "$passcases{$c}") ||
diag("\tSTDOUT: $stdout\n\tSTDERR: $stderr\n");
}
Devel-CheckLib-1.01/t/dash-l-libs.t000064400000000000000000000023161222430313200166530ustar00rootroot00000000000000use strict;
# compatible use warnings
BEGIN{ if (not $] < 5.006) { require warnings; warnings->import } }

use lib 't/lib';
use IO::CaptureOutput qw(capture);
use Config;

use File::Spec;
use Test::More;

my($debug, $stdout, $stderr) = ($ENV{DEVEL_CHECKLIB_DEBUG} || 0);
my $libdir;

eval "use Devel::CheckLib";
if($@ =~ /Couldn't find your C compiler/) {
plan skip_all => "Couldn't find your C compiler";
}

eval "use Helper qw(create_testlib)";
if($libdir = create_testlib("bazbam")) {
plan tests => 1;
} else {
plan skip_all => "Couldn't build a library to test against";
};

my $runtime = '-l'.(
$^O eq 'MSWin32' # if Win32 (not Cygwin) ...
? (
$Config{cc} =~ /(^|^\w+ )bcc/
? 'cc3250' # ... Borland
: 'msvcrt' # ... otherwise assume Microsoft
)
: 'm' # default to Unix-style
);

# my $runtime = $^O eq 'MSWin32' ? '-lmsvcrt' : '-lm';
my $args = qq{LIBS => '$runtime -lbazbam -L$libdir'};

capture(
sub { eval "assert_lib(debug => $debug, $args)"; },
\$stdout,
\$stderr
);
is($@, q{}, "$args") || diag("\tSTDOUT: $stdout\n\tSTDERR: $stderr\n");
Devel-CheckLib-1.01/t/exit_with_message.t000064400000000000000000000010441222430313200202610ustar00rootroot00000000000000use strict;
# compatible use warnings
BEGIN{ if (not $] < 5.006) { require warnings; warnings->import } }

use Test::More;
use File::Temp;

my $fh = File::Temp->new();
print {$fh} << 'ENDPRINT';
use Devel::CheckLib;
check_lib_or_exit( qw/lib hlagh/ );
ENDPRINT
$fh->close;

my $err = `$^X $fh 2>&1`;

if($err =~ /Couldn't find your C compiler/) {
plan skip_all => "Couldn't find your C compiler";
} else {
plan tests => 1;
like ($err, "/^Can't link\\/include C library 'hlagh'/ms",
"missing hlagh detected non-fatally"
);
}
Devel-CheckLib-1.01/t/found.t000064400000000000000000000027051222430313200156710ustar00rootroot00000000000000use strict;
# compatible use warnings
BEGIN{ if (not $] < 5.006) { require warnings; warnings->import } }

use lib 't/lib';
use IO::CaptureOutput qw(capture);
use Config;

use File::Spec;
use Test::More;

eval "use Devel::CheckLib";
if($@ =~ /Couldn't find your C compiler/) {
plan skip_all => "Couldn't find your C compiler";
} else {
eval "use Helper qw/create_testlib/";
}

my($debug, $stdout, $stderr) = ($ENV{DEVEL_CHECKLIB_DEBUG} || 0);

# compile a test library
my $libdir = create_testlib("bazbam");

my @lib =
$^O eq 'MSWin32' # if Win32 (not Cygwin) ...
? (
$Config{cc} =~ /(^|^\w+ )bcc/
# FIXME - find a second Borland lib
? ('cc3250', 'cc3250') # ... Borland
: ('msvcrt', 'kernel32') # ... otherwise assume Microsoft
)
: qw(m c) # default to Unix-style
;

# cases are strings to interpolate into the assert_lib call
my @cases = (
qq/lib => '$lib[0]'/,
qq/lib => '$lib[1]'/,
qq/lib => ['$lib[0]', '$lib[1]']/,
);

push @cases, qq{lib => 'bazbam', libpath => '$libdir'} if $libdir;

plan tests => 2 * scalar @cases;


for my $c ( @cases ) {
capture(
sub { eval "assert_lib(debug => $debug, $c)"; },
\$stdout,
\$stderr
);
is($@, q{}, "$c") || diag("\tSTDOUT: $stdout\n\tSTDERR: $stderr\n");
ok(check_lib(debug => $debug, eval($c)), "... and check_lib is true");
}
Devel-CheckLib-1.01/t/headers.t000064400000000000000000000025171222430313200161720ustar00rootroot00000000000000use strict;
# compatible use warnings
BEGIN{ if (not $] < 5.006) { require warnings; warnings->import } }

use lib 't/lib';
use IO::CaptureOutput qw(capture);
use Config;

use File::Spec;
use Test::More;

eval "use Devel::CheckLib";
if($@ =~ /Couldn't find your C compiler/) {
plan skip_all => "Couldn't find your C compiler";
}

my($debug, $stdout, $stderr) = ($ENV{DEVEL_CHECKLIB_DEBUG} || 0);

# cases are strings to interpolate into the assert_lib call
my %failcases = (
qq{incpath => '.', header => 'headerfile.h'} => "Can't link/include",
qq{INC => '-t/inc', header => 'headerfile.h'} => "INC argument badly-formed"
);
my @passcases = (
qq{incpath => '.', header => 't/inc/headerfile.h'},
qq{incpath => [qw(t/inc)], header => 'headerfile.h'},
qq{INC => '-I. -It/inc', header => 'headerfile.h'}
);

plan tests => scalar(keys %failcases) + scalar(@passcases);

for my $c (keys %failcases) {
capture(
sub { eval "assert_lib(debug => $debug, $c)"; },
\$stdout,
\$stderr
);
ok($@ =~ /^$failcases{$c}/, "$c") ||
diag("$@\n\tSTDOUT: $stdout\n\tSTDERR: $stderr\n");
}
for my $c ( @passcases ) {
capture(
sub { eval "assert_lib(debug => $debug, $c)"; },
\$stdout,
\$stderr
);
is($@, q{}, "$c") || diag("\tSTDOUT: $stdout\n\tSTDERR: $stderr\n");
}
Devel-CheckLib-1.01/t/inc/000075500000000000000000000000001222430313200151365ustar00rootroot00000000000000Devel-CheckLib-1.01/t/inc/headerfile.h000064400000000000000000000000461222430313200173770ustar00rootroot00000000000000int foo(void);
int libversion(void);

Devel-CheckLib-1.01/t/lib/000075500000000000000000000000001222430313200151335ustar00rootroot00000000000000Devel-CheckLib-1.01/t/lib/Helper.pm000064400000000000000000000066771222430313200167300ustar00rootroot00000000000000package Helper;
use strict;
# compatible use warnings
BEGIN{ if (not $] < 5.006) { require warnings; warnings->import } }

use Config;
use Cwd;
use Exporter;
use IO::File;
use File::Spec::Functions qw/catfile canonpath splitdir/;
use File::Temp qw/tempdir/;

use vars qw/@EXPORT @ISA/;
@ISA = qw/Exporter/;
@EXPORT = qw(
create_testlib
find_compiler
find_binary
);

my $orig_wd = cwd;

BEGIN { require Devel::CheckLib; } # for _quiet_system()
sub _quiet_system {
goto &Devel::CheckLib::_quiet_system;
}

#--------------------------------------------------------------------------#
# create_testlib( 'bazbam' )
#
# takes a library name and compiles a simple library with two functions,
# foo() (which returns 0) and libversion() (which returns 42), in a temp
# directory and returns the temp directory. Returns undef if something
# went wrong
#--------------------------------------------------------------------------#

sub create_testlib {
my ($libname) = (@_);
return unless $libname;
my $tempdir = tempdir(CLEANUP => 1, TEMPLATE => "Devel-Assert-testlib-XXXXXXXX");
chdir $tempdir;
my $code_fh = IO::File->new("${libname}.c", ">");
print {$code_fh} "int libversion() { return 42; }\nint foo() { return 0; }\n";
$code_fh->close;

my $cc = $Config{cc};
my $gccv = $Config{gccversion};
my $rv =
$cc eq 'gcc' ? _gcc_lib( $libname ) :
$cc eq 'cc' ? _gcc_lib( $libname ) :
$cc eq 'cl' ? _cl_lib( $libname ) :
$gccv ? _gcc_lib( $libname ) :
undef ;

chdir $orig_wd;
return $rv ? canonpath($tempdir) : undef;
}

sub _gcc_lib {
my ($libname) = @_;
my $cc = find_compiler() or return;
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"
}

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;
return -f "${libname}.lib";
}

#--------------------------------------------------------------------------#
# find_binary, find_compiler
#
# Returns absolute path to an executable file in $ENV{PATH} or undef
# if it can't be found. find_binary() takes a program argument;
# find_compiler takes no arguments and just returns the path to $Config{cc}
#--------------------------------------------------------------------------#

sub find_binary {
my ($program) = @_;
if ($Config{_exe} && $program !~ /$Config{_exe}$/) {
$program .= $Config{_exe};
}
return $program if -x $program;

my @search_paths = split /$Config{path_sep}/, $ENV{PATH};
my @lib_search_paths = map lib_to_bin($_), split /$Config{path_sep}/, $ENV{LIBRARY_PATH}||'';

for my $path ( @search_paths, @lib_search_paths ) {
my $binary = catfile( $path, $program );
return $binary if -x $binary;
}

return;
}

sub lib_to_bin {
my ( $lib_dir ) = @_;
my @parts = splitdir $lib_dir;
pop @parts;
push @parts, 'bin';
my $bin_dir = catfile(@parts);
return $bin_dir;
}

sub find_compiler {
return find_binary($Config{cc});
}

1; # must be true
Devel-CheckLib-1.01/t/multi-word-compiler.t000064400000000000000000000014411222430313200204650ustar00rootroot00000000000000# $Id: multi-word-compiler.t,v 1.3 2008/02/07 14:16:39 drhyde Exp $

use strict;
BEGIN{ if (not $] < 5.006) { require warnings; warnings->import } }

use Test::More;

plan tests => 1;

use Config;
BEGIN {
BEGIN { if (not $] < 5.006 ) { warnings->unimport('redefine') } }
unless(defined($ActivePerl::VERSION) && $Config{cc} =~ /\bgcc\b/) {
*Config::STORE = sub { $_[0]->{$_[1]} = $_[2] }
}
}

if(defined($ActivePerl::VERSION) && $Config{cc} =~ /\bgcc\b/) {
my $obj = tied %Config::Config;
$obj->{cc} = "$^X $Config{cc}";
}
else {
$Config{cc} = "$^X $Config{cc}";
}

eval { $Config{cc} = "$^X $Config{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");
}
Devel-CheckLib-1.01/t/not_found.t000064400000000000000000000026461222430313200165550ustar00rootroot00000000000000use strict;
# compatible use warnings
BEGIN{ if (not $] < 5.006) { require warnings; warnings->import } }

use Test::More;
use Config;
my $debug = 0;

eval "use Devel::CheckLib";
if($@ =~ /Couldn't find your C compiler/) {
plan skip_all => "Couldn't find your C compiler";
}

my $platform_lib =
$^O eq 'MSWin32' # if Win32 (not Cygwin) ...
? (
$Config{cc} =~ /(^|^\w+ )bcc/
? 'cc3250' # ... Borland
: 'msvcrt' # ... otherwise assume Microsoft
)
: 'm' # default to Unix-style
;

# Cases are AoH: { arg => $string, missing => $string }
my @cases = (
{ arg => qq{lib => 'foo'}, missing => ['foo'] },
{ arg => qq{lib => [qw/$platform_lib foo/]}, missing => ['foo'] },
{ arg => qq{lib => [qw/foo $platform_lib/]}, missing => ['foo'] },
{ arg => qq{lib => [qw/foo bar/]}, missing => [qw/foo bar/] },
);

plan tests => 3 * @cases;

for my $c ( @cases ) {
eval "assert_lib(debug => $debug, $c->{arg})";
my $err = $@;
ok ( $err, "died on '$c->{arg}'" );
my $miss_string = join(q{, }, map { qq{'$_'} } @{$c->{missing}} );
like ($err, "/^Can't link\/include C library ${miss_string}/ms",
"missing $miss_string detected"
);
ok(!check_lib(debug => $debug, eval($c->{arg})),
"... and check_lib is false");
}
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin