da98d20be299b39ac93960d9fc635e7d3f537033
[p5sagit/p5-mst-13.2.git] / lib / ExtUtils / Liblist.pm
1 package ExtUtils::Liblist;
2 require ExtUtils::MakeMaker; # currently for MM_Unix::lsdir
3
4 # Broken out of MakeMaker from version 4.11
5
6 use Config;
7 use Cwd;
8 # --- Determine libraries to use and how to use them ---
9
10 sub ext {
11     my($potential_libs, $Verbose) = @_;
12     return ("", "", "") unless $potential_libs;
13     print STDOUT "Potential libraries are '$potential_libs':" if $Verbose;
14
15     my($so)   = $Config{'so'};
16     my($libs) = $Config{'libs'};
17
18     # compute $extralibs, $bsloadlibs and $ldloadlibs from
19     # $potential_libs
20     # this is a rewrite of Andy Dougherty's extliblist in perl
21     # its home is in <distribution>/ext/util
22
23     my(@searchpath); # from "-L/path" entries in $potential_libs
24     my(@libpath) = split " ", $Config{'libpth'};
25     my(@ldloadlibs, @bsloadlibs, @extralibs);
26     my($fullname, $thislib, $thispth, @fullname);
27     my($pwd) = fastcwd(); # from Cwd.pm
28     my($found) = 0;
29
30     foreach $thislib (split ' ', $potential_libs){
31
32         # Handle possible linker path arguments.
33         if ($thislib =~ s/^(-[LR])//){  # save path flag type
34             my($ptype) = $1;
35             unless (-d $thislib){
36                 print STDOUT "$ptype$thislib ignored, directory does not exist\n"
37                         if $Verbose;
38                 next;
39             }
40             if ($thislib !~ m|^/|) {
41               print STDOUT "Warning: $ptype$thislib changed to $ptype$pwd/$thislib\n";
42               $thislib = "$pwd/$thislib";
43             }
44             push(@searchpath, $thislib);
45             push(@extralibs,  "$ptype$thislib");
46             push(@ldloadlibs, "$ptype$thislib");
47             next;
48         }
49
50         # Handle possible library arguments.
51         unless ($thislib =~ s/^-l//){
52           print STDOUT "Unrecognized argument in LIBS ignored: '$thislib'\n";
53           next;
54         }
55
56         my($found_lib)=0;
57         foreach $thispth (@searchpath, @libpath){
58
59                 # Try to find the full name of the library.  We need this to
60                 # determine whether it's a dynamically-loadable library or not.
61                 # This tends to be subject to various os-specific quirks.
62                 # For gcc-2.6.2 on linux (March 1995), DLD can not load
63                 # .sa libraries, with the exception of libm.sa, so we
64                 # deliberately skip them.
65             if (@fullname = MM_Unix::lsdir($thispth,"^lib$thislib\.$so\.[0-9]+")){
66                 # Take care that libfoo.so.10 wins against libfoo.so.9.
67                 # Compare two libraries to find the most recent version
68                 # number.  E.g.  if you have libfoo.so.9.0.7 and
69                 # libfoo.so.10.1, first convert all digits into two
70                 # decimal places.  Then we'll add ".00" to the shorter
71                 # strings so that we're comparing strings of equal length
72                 # Thus we'll compare libfoo.so.09.07.00 with
73                 # libfoo.so.10.01.00.  Some libraries might have letters
74                 # in the version.  We don't know what they mean, but will
75                 # try to skip them gracefully -- we'll set any letter to
76                 # '0'.  Finally, sort in reverse so we can take the
77                 # first element.
78
79                 #TODO: iterate through the directory instead of sorting
80
81                 $fullname = "$thispth/" .
82                 (sort { my($ma) = $a;
83                         my($mb) = $b;
84                         $ma =~ tr/A-Za-z/0/s;
85                         $ma =~ s/\b(\d)\b/0$1/g;
86                         $mb =~ tr/A-Za-z/0/s;
87                         $mb =~ s/\b(\d)\b/0$1/g;
88                         while (length($ma) < length($mb)) { $ma .= ".00"; }
89                         while (length($mb) < length($ma)) { $mb .= ".00"; }
90                         # Comparison deliberately backwards
91                         $mb cmp $ma;} @fullname)[0];
92             } elsif (-f ($fullname="$thispth/lib$thislib.$so")
93                  && (($Config{'dlsrc'} ne "dl_dld.xs") || ($thislib eq "m"))){
94             } elsif (-f ($fullname="$thispth/lib${thislib}_s.a")
95                  && ($thislib .= "_s") ){ # we must explicitly use _s version
96             } elsif (-f ($fullname="$thispth/lib$thislib.a")){
97             } elsif (-f ($fullname="$thispth/Slib$thislib.a")){
98             } else {
99                 print STDOUT "$thislib not found in $thispth" if $Verbose;
100                 next;
101             }
102             print STDOUT "'-l$thislib' found at $fullname" if $Verbose;
103             $found++;
104             $found_lib++;
105
106             # Now update library lists
107
108             # what do we know about this library...
109             my $is_dyna = ($fullname !~ /\.a$/);
110             my $in_perl = ($libs =~ /\B-l${thislib}\b/s);
111
112             # Do not add it into the list if it is already linked in
113             # with the main perl executable.
114             # We have to special-case the NeXT, because all the math 
115             # is also in libsys_s
116             unless ($in_perl || 
117                     ($Config{'osname'} eq 'next' && $thislib eq 'm') ){
118                 push(@extralibs, "-l$thislib");
119             }
120
121             # We might be able to load this archive file dynamically
122             if ( $Config{'dlsrc'} =~ /dl_next|dl_dld/){
123                 # We push -l$thislib instead of $fullname because
124                 # it avoids hardwiring a fixed path into the .bs file.
125                 # Mkbootstrap will automatically add dl_findfile() to
126                 # the .bs file if it sees a name in the -l format.
127                 # USE THIS, when dl_findfile() is fixed: 
128                 # push(@bsloadlibs, "-l$thislib");
129                 # OLD USE WAS while checking results against old_extliblist
130                 push(@bsloadlibs, "$fullname");
131             } else {
132                 if ($is_dyna){
133                     # For SunOS4, do not add in this shared library if
134                     # it is already linked in the main perl executable
135                     push(@ldloadlibs, "-l$thislib")
136                         unless ($in_perl and $Config{'osname'} eq 'sunos');
137                 } else {
138                     push(@ldloadlibs, "-l$thislib");
139                 }
140             }
141             last;       # found one here so don't bother looking further
142         }
143         print STDOUT "Warning (non-fatal): No library found for -l$thislib" 
144             unless $found_lib>0;
145     }
146     return ('','','') unless $found;
147     ("@extralibs", "@bsloadlibs", "@ldloadlibs");
148 }
149
150
151 1;