X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FExtUtils%2FLiblist.pm;h=35966218b4a9864e808c338724d0720c0559d0da;hb=1e65eb70bcb514e61cdd8408bdbe4e5a20b7fd95;hp=7672f5ef3114dd84a458ca952bd764be04c3824e;hpb=8e07c86ebc651fe92eb7e3b25f801f57cfb8dd6f;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/ExtUtils/Liblist.pm b/lib/ExtUtils/Liblist.pm index 7672f5e..3596621 100644 --- a/lib/ExtUtils/Liblist.pm +++ b/lib/ExtUtils/Liblist.pm @@ -1,160 +1,287 @@ package ExtUtils::Liblist; -# Broken out of MakeMaker from version 4.11 +use strict; -use Config; -use Cwd; -# --- Determine libraries to use and how to use them --- +use vars qw($VERSION @ISA); +$VERSION = '1.03'; +use File::Spec; +require ExtUtils::Liblist::Kid; +@ISA = qw(ExtUtils::Liblist::Kid File::Spec); + +# Backwards compatibility with old interface. sub ext { - my($potential_libs, $Verbose) = @_; - return ("", "", "") unless $potential_libs; - print STDOUT "Potential libraries are '$potential_libs':\n" if $Verbose; - - my($so) = $Config{'so'}; - my($libs) = $Config{'libs'}; - - # compute $extralibs, $bsloadlibs and $ldloadlibs from - # $potential_libs - # this is a rewrite of Andy Dougherty's extliblist in perl - # its home is in /ext/util - - my(@searchpath); # from "-L/path" entries in $potential_libs - my(@libpath) = split " ", $Config{'libpth'}; - my(@ldloadlibs, @bsloadlibs, @extralibs); - my($fullname, $thislib, $thispth, @fullname); - my($pwd) = fastcwd(); # from Cwd.pm - my($found) = 0; - - foreach $thislib (split ' ', $potential_libs){ - - # Handle possible linker path arguments. - if ($thislib =~ s/^(-[LR])//){ # save path flag type - my($ptype) = $1; - unless (-d $thislib){ - print STDOUT "$ptype$thislib ignored, directory does not exist\n" - if $Verbose; - next; - } - if ($thislib !~ m|^/|) { - print STDOUT "Warning: $ptype$thislib changed to $ptype$pwd/$thislib\n"; - $thislib = "$pwd/$thislib"; - } - push(@searchpath, $thislib); - push(@extralibs, "$ptype$thislib"); - push(@ldloadlibs, "$ptype$thislib"); - next; - } - - # Handle possible library arguments. - unless ($thislib =~ s/^-l//){ - print STDOUT "Unrecognized argument in LIBS ignored: '$thislib'\n"; - next; - } - - my($found_lib)=0; - foreach $thispth (@searchpath, @libpath){ - - # Try to find the full name of the library. We need this to - # determine whether it's a dynamically-loadable library or not. - # This tends to be subject to various os-specific quirks. - # For gcc-2.6.2 on linux (March 1995), DLD can not load - # .sa libraries, with the exception of libm.sa, so we - # deliberately skip them. - if (@fullname = lsdir($thispth,"^lib$thislib\.$so\.[0-9]+")){ - # Take care that libfoo.so.10 wins against libfoo.so.9. - # Compare two libraries to find the most recent version - # number. E.g. if you have libfoo.so.9.0.7 and - # libfoo.so.10.1, first convert all digits into two - # decimal places. Then we'll add ".00" to the shorter - # strings so that we're comparing strings of equal length - # Thus we'll compare libfoo.so.09.07.00 with - # libfoo.so.10.01.00. Some libraries might have letters - # in the version. We don't know what they mean, but will - # try to skip them gracefully -- we'll set any letter to - # '0'. Finally, sort in reverse so we can take the - # first element. - - #TODO: iterate through the directory instead of sorting - - $fullname = "$thispth/" . - (sort { my($ma) = $a; - my($mb) = $b; - $ma =~ tr/A-Za-z/0/s; - $ma =~ s/\b(\d)\b/0$1/g; - $mb =~ tr/A-Za-z/0/s; - $mb =~ s/\b(\d)\b/0$1/g; - while (length($ma) < length($mb)) { $ma .= ".00"; } - while (length($mb) < length($ma)) { $mb .= ".00"; } - # Comparison deliberately backwards - $mb cmp $ma;} @fullname)[0]; - } elsif (-f ($fullname="$thispth/lib$thislib.$so") - && (($Config{'dlsrc'} ne "dl_dld.xs") || ($thislib eq "m"))){ - } elsif (-f ($fullname="$thispth/lib${thislib}_s.a") - && ($thislib .= "_s") ){ # we must explicitly use _s version - } elsif (-f ($fullname="$thispth/lib$thislib.a")){ - } elsif (-f ($fullname="$thispth/Slib$thislib.a")){ - } else { - print STDOUT "$thislib not found in $thispth\n" if $Verbose; - next; - } - print STDOUT "'-l$thislib' found at $fullname\n" if $Verbose; - $found++; - $found_lib++; - - # Now update library lists - - # what do we know about this library... - my $is_dyna = ($fullname !~ /\.a$/); - my $in_perl = ($libs =~ /\B-l${thislib}\b/s); - - # Do not add it into the list if it is already linked in - # with the main perl executable. - # We have to special-case the NeXT, because all the math - # is also in libsys_s - unless ($in_perl || - ($Config{'osname'} eq 'next' && $thislib eq 'm') ){ - push(@extralibs, "-l$thislib"); - } - - # We might be able to load this archive file dynamically - if ( $Config{'dlsrc'} =~ /dl_next|dl_dld/){ - # We push -l$thislib instead of $fullname because - # it avoids hardwiring a fixed path into the .bs file. - # Mkbootstrap will automatically add dl_findfile() to - # the .bs file if it sees a name in the -l format. - # USE THIS, when dl_findfile() is fixed: - # push(@bsloadlibs, "-l$thislib"); - # OLD USE WAS while checking results against old_extliblist - push(@bsloadlibs, "$fullname"); - } else { - if ($is_dyna){ - # For SunOS4, do not add in this shared library if - # it is already linked in the main perl executable - push(@ldloadlibs, "-l$thislib") - unless ($in_perl and $Config{'osname'} eq 'sunos'); - } else { - push(@ldloadlibs, "-l$thislib"); - } - } - last; # found one here so don't bother looking further - } - print STDOUT "Warning (non-fatal): No library found for -l$thislib\n" - unless $found_lib>0; - } - return ('','','') unless $found; - ("@extralibs", "@bsloadlibs", "@ldloadlibs"); + goto &ExtUtils::Liblist::Kid::ext; } -sub lsdir { #yes, duplicate code seems less hassle than having an - #extra file with only lsdir - my($dir, $regex) = @_; - local(*DIR, @ls); - opendir(DIR, $dir || ".") or return (); - @ls = readdir(DIR); - closedir(DIR); - @ls = grep(/$regex/, @ls) if $regex; - @ls; +sub lsdir { + shift; + my $rex = qr/$_[1]/; + opendir DIR, $_[0]; + my @out = grep /$rex/, readdir DIR; + closedir DIR; + return @out; } -1; +__END__ + +=head1 NAME + +ExtUtils::Liblist - determine libraries to use and how to use them + +=head1 SYNOPSIS + + require ExtUtils::Liblist; + + $MM->ext($potential_libs, $verbose, $need_names); + + # Usually you can get away with: + ExtUtils::Liblist->ext($potential_libs, $verbose, $need_names) + +=head1 DESCRIPTION + +This utility takes a list of libraries in the form C<-llib1 -llib2 +-llib3> and returns lines suitable for inclusion in an extension +Makefile. Extra library paths may be included with the form +C<-L/another/path> this will affect the searches for all subsequent +libraries. + +It returns an array of four or five scalar values: EXTRALIBS, +BSLOADLIBS, LDLOADLIBS, LD_RUN_PATH, and, optionally, a reference to +the array of the filenames of actual libraries. Some of these don't +mean anything unless on Unix. See the details about those platform +specifics below. The list of the filenames is returned only if +$need_names argument is true. + +Dependent libraries can be linked in one of three ways: + +=over 2 + +=item * For static extensions + +by the ld command when the perl binary is linked with the extension +library. See EXTRALIBS below. + +=item * For dynamic extensions at build/link time + +by the ld command when the shared object is built/linked. See +LDLOADLIBS below. + +=item * For dynamic extensions at load time + +by the DynaLoader when the shared object is loaded. See BSLOADLIBS +below. + +=back + +=head2 EXTRALIBS + +List of libraries that need to be linked with when linking a perl +binary which includes this extension. Only those libraries that +actually exist are included. These are written to a file and used +when linking perl. + +=head2 LDLOADLIBS and LD_RUN_PATH + +List of those libraries which can or must be linked into the shared +library when created using ld. These may be static or dynamic +libraries. LD_RUN_PATH is a colon separated list of the directories +in LDLOADLIBS. It is passed as an environment variable to the process +that links the shared library. + +=head2 BSLOADLIBS + +List of those libraries that are needed but can be linked in +dynamically at run time on this platform. SunOS/Solaris does not need +this because ld records the information (from LDLOADLIBS) into the +object file. This list is used to create a .bs (bootstrap) file. + +=head1 PORTABILITY + +This module deals with a lot of system dependencies and has quite a +few architecture specific Cs in the code. + +=head2 VMS implementation + +The version of ext() which is executed under VMS differs from the +Unix-OS/2 version in several respects: + +=over 2 + +=item * + +Input library and path specifications are accepted with or without the +C<-l> and C<-L> prefixes used by Unix linkers. If neither prefix is +present, a token is considered a directory to search if it is in fact +a directory, and a library to search for otherwise. Authors who wish +their extensions to be portable to Unix or OS/2 should use the Unix +prefixes, since the Unix-OS/2 version of ext() requires them. + +=item * + +Wherever possible, shareable images are preferred to object libraries, +and object libraries to plain object files. In accordance with VMS +naming conventions, ext() looks for files named Ishr and Irtl; +it also looks for Ilib and libI to accommodate Unix conventions +used in some ported software. + +=item * + +For each library that is found, an appropriate directive for a linker options +file is generated. The return values are space-separated strings of +these directives, rather than elements used on the linker command line. + +=item * + +LDLOADLIBS contains both the libraries found based on C<$potential_libs> and +the CRTLs, if any, specified in Config.pm. EXTRALIBS contains just those +libraries found based on C<$potential_libs>. BSLOADLIBS and LD_RUN_PATH +are always empty. + +=back + +In addition, an attempt is made to recognize several common Unix library +names, and filter them out or convert them to their VMS equivalents, as +appropriate. + +In general, the VMS version of ext() should properly handle input from +extensions originally designed for a Unix or VMS environment. If you +encounter problems, or discover cases where the search could be improved, +please let us know. + +=head2 Win32 implementation + +The version of ext() which is executed under Win32 differs from the +Unix-OS/2 version in several respects: + +=over 2 + +=item * + +If C<$potential_libs> is empty, the return value will be empty. +Otherwise, the libraries specified by C<$Config{perllibs}> (see Config.pm) +will be appended to the list of C<$potential_libs>. The libraries +will be searched for in the directories specified in C<$potential_libs>, +C<$Config{libpth}>, and in C<$Config{installarchlib}/CORE>. +For each library that is found, a space-separated list of fully qualified +library pathnames is generated. + +=item * + +Input library and path specifications are accepted with or without the +C<-l> and C<-L> prefixes used by Unix linkers. + +An entry of the form C<-La:\foo> specifies the C directory to look +for the libraries that follow. + +An entry of the form C<-lfoo> specifies the library C, which may be +spelled differently depending on what kind of compiler you are using. If +you are using GCC, it gets translated to C, but for other win32 +compilers, it becomes C. If no files are found by those translated +names, one more attempt is made to find them using either C or +C, depending on whether GCC or some other win32 compiler is +being used, respectively. + +If neither the C<-L> or C<-l> prefix is present in an entry, the entry is +considered a directory to search if it is in fact a directory, and a +library to search for otherwise. The C<$Config{lib_ext}> suffix will +be appended to any entries that are not directories and don't already have +the suffix. + +Note that the C<-L> and C<-l> prefixes are B, but authors +who wish their extensions to be portable to Unix or OS/2 should use the +prefixes, since the Unix-OS/2 version of ext() requires them. + +=item * + +Entries cannot be plain object files, as many Win32 compilers will +not handle object files in the place of libraries. + +=item * + +Entries in C<$potential_libs> beginning with a colon and followed by +alphanumeric characters are treated as flags. Unknown flags will be ignored. + +An entry that matches C disables the appending of default +libraries found in C<$Config{perllibs}> (this should be only needed very rarely). + +An entry that matches C disables all searching for +the libraries specified after it. Translation of C<-Lfoo> and +C<-lfoo> still happens as appropriate (depending on compiler being used, +as reflected by C<$Config{cc}>), but the entries are not verified to be +valid files or directories. + +An entry that matches C reenables searching for +the libraries specified after it. You can put it at the end to +enable searching for default libraries specified by C<$Config{perllibs}>. + +=item * + +The libraries specified may be a mixture of static libraries and +import libraries (to link with DLLs). Since both kinds are used +pretty transparently on the Win32 platform, we do not attempt to +distinguish between them. + +=item * + +LDLOADLIBS and EXTRALIBS are always identical under Win32, and BSLOADLIBS +and LD_RUN_PATH are always empty (this may change in future). + +=item * + +You must make sure that any paths and path components are properly +surrounded with double-quotes if they contain spaces. For example, +C<$potential_libs> could be (literally): + + "-Lc:\Program Files\vc\lib" msvcrt.lib "la test\foo bar.lib" + +Note how the first and last entries are protected by quotes in order +to protect the spaces. + +=item * + +Since this module is most often used only indirectly from extension +C files, here is an example C entry to add +a library to the build process for an extension: + + LIBS => ['-lgl'] + +When using GCC, that entry specifies that MakeMaker should first look +for C (followed by C) in all the locations specified by +C<$Config{libpth}>. + +When using a compiler other than GCC, the above entry will search for +C (followed by C). + +If the library happens to be in a location not in C<$Config{libpth}>, +you need: + + LIBS => ['-Lc:\gllibs -lgl'] + +Here is a less often used example: + + LIBS => ['-lgl', ':nosearch -Ld:\mesalibs -lmesa -luser32'] + +This specifies a search for library C as before. If that search +fails to find the library, it looks at the next item in the list. The +C<:nosearch> flag will prevent searching for the libraries that follow, +so it simply returns the value as C<-Ld:\mesalibs -lmesa -luser32>, +since GCC can use that value as is with its linker. + +When using the Visual C compiler, the second item is returned as +C<-libpath:d:\mesalibs mesa.lib user32.lib>. + +When using the Borland compiler, the second item is returned as +C<-Ld:\mesalibs mesa.lib user32.lib>, and MakeMaker takes care of +moving the C<-Ld:\mesalibs> to the correct place in the linker +command line. + +=back + + +=head1 SEE ALSO + +L + +=cut +