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