Refresh MakeMaker to 5.39
[p5sagit/p5-mst-13.2.git] / lib / ExtUtils / Liblist.pm
CommitLineData
005c1a0e 1package ExtUtils::Liblist;
8a1da95f 2use vars qw($VERSION);
005c1a0e 3# Broken out of MakeMaker from version 4.11
4
bab2b58e 5$VERSION = substr q$Revision: 1.21 $, 10;
f1387719 6
005c1a0e 7use Config;
8f1aa56b 8use Cwd 'cwd';
4633a7c4 9use File::Basename;
10
005c1a0e 11sub ext {
55497cff 12 if ($^O eq 'VMS') { return &_vms_ext; }
13 else { return &_unix_os2_ext; }
14}
15
16sub _unix_os2_ext {
c2e89b3d 17 my($self,$potential_libs, $Verbose) = @_;
f1387719 18 if ($^O =~ 'os2' and $Config{libs}) {
4e68a208 19 # Dynamic libraries are not transitive, so we may need including
20 # the libraries linked against perl.dll again.
21
22 $potential_libs .= " " if $potential_libs;
23 $potential_libs .= $Config{libs};
24 }
4633a7c4 25 return ("", "", "", "") unless $potential_libs;
8e07c86e 26 print STDOUT "Potential libraries are '$potential_libs':\n" if $Verbose;
005c1a0e 27
28 my($so) = $Config{'so'};
29 my($libs) = $Config{'libs'};
55497cff 30 my $Config_libext = $Config{lib_ext} || ".a";
31
005c1a0e 32
33 # compute $extralibs, $bsloadlibs and $ldloadlibs from
34 # $potential_libs
35 # this is a rewrite of Andy Dougherty's extliblist in perl
36 # its home is in <distribution>/ext/util
37
38 my(@searchpath); # from "-L/path" entries in $potential_libs
39 my(@libpath) = split " ", $Config{'libpth'};
4633a7c4 40 my(@ldloadlibs, @bsloadlibs, @extralibs, @ld_run_path, %ld_run_path_seen);
005c1a0e 41 my($fullname, $thislib, $thispth, @fullname);
8f1aa56b 42 my($pwd) = cwd(); # from Cwd.pm
005c1a0e 43 my($found) = 0;
44
45 foreach $thislib (split ' ', $potential_libs){
46
47 # Handle possible linker path arguments.
48 if ($thislib =~ s/^(-[LR])//){ # save path flag type
49 my($ptype) = $1;
50 unless (-d $thislib){
51 print STDOUT "$ptype$thislib ignored, directory does not exist\n"
52 if $Verbose;
53 next;
54 }
f1387719 55 unless ($self->file_name_is_absolute($thislib)) {
005c1a0e 56 print STDOUT "Warning: $ptype$thislib changed to $ptype$pwd/$thislib\n";
f1387719 57 $thislib = $self->catdir($pwd,$thislib);
005c1a0e 58 }
59 push(@searchpath, $thislib);
60 push(@extralibs, "$ptype$thislib");
61 push(@ldloadlibs, "$ptype$thislib");
62 next;
63 }
64
65 # Handle possible library arguments.
66 unless ($thislib =~ s/^-l//){
67 print STDOUT "Unrecognized argument in LIBS ignored: '$thislib'\n";
68 next;
69 }
70
71 my($found_lib)=0;
72 foreach $thispth (@searchpath, @libpath){
73
74 # Try to find the full name of the library. We need this to
75 # determine whether it's a dynamically-loadable library or not.
76 # This tends to be subject to various os-specific quirks.
77 # For gcc-2.6.2 on linux (March 1995), DLD can not load
78 # .sa libraries, with the exception of libm.sa, so we
79 # deliberately skip them.
c2e89b3d 80 if (@fullname = $self->lsdir($thispth,"^lib$thislib\.$so\.[0-9]+")){
005c1a0e 81 # Take care that libfoo.so.10 wins against libfoo.so.9.
82 # Compare two libraries to find the most recent version
83 # number. E.g. if you have libfoo.so.9.0.7 and
84 # libfoo.so.10.1, first convert all digits into two
85 # decimal places. Then we'll add ".00" to the shorter
86 # strings so that we're comparing strings of equal length
87 # Thus we'll compare libfoo.so.09.07.00 with
88 # libfoo.so.10.01.00. Some libraries might have letters
89 # in the version. We don't know what they mean, but will
90 # try to skip them gracefully -- we'll set any letter to
91 # '0'. Finally, sort in reverse so we can take the
92 # first element.
93
94 #TODO: iterate through the directory instead of sorting
95
96 $fullname = "$thispth/" .
97 (sort { my($ma) = $a;
98 my($mb) = $b;
99 $ma =~ tr/A-Za-z/0/s;
100 $ma =~ s/\b(\d)\b/0$1/g;
101 $mb =~ tr/A-Za-z/0/s;
102 $mb =~ s/\b(\d)\b/0$1/g;
103 while (length($ma) < length($mb)) { $ma .= ".00"; }
104 while (length($mb) < length($ma)) { $mb .= ".00"; }
105 # Comparison deliberately backwards
106 $mb cmp $ma;} @fullname)[0];
107 } elsif (-f ($fullname="$thispth/lib$thislib.$so")
108 && (($Config{'dlsrc'} ne "dl_dld.xs") || ($thislib eq "m"))){
4633a7c4 109 } elsif (-f ($fullname="$thispth/lib${thislib}_s$Config_libext")
005c1a0e 110 && ($thislib .= "_s") ){ # we must explicitly use _s version
4633a7c4 111 } elsif (-f ($fullname="$thispth/lib$thislib$Config_libext")){
864a5fa8 112 } elsif (-f ($fullname="$thispth/$thislib$Config_libext")){
4633a7c4 113 } elsif (-f ($fullname="$thispth/Slib$thislib$Config_libext")){
8f1aa56b 114 } elsif ($^O eq 'dgux'
c07a80fd 115 && -l ($fullname="$thispth/lib$thislib$Config_libext")
116 && readlink($fullname) =~ /^elink:/) {
117 # Some of DG's libraries look like misconnected symbolic
118 # links, but development tools can follow them. (They
119 # look like this:
120 #
121 # libm.a -> elink:${SDE_PATH:-/usr}/sde/\
122 # ${TARGET_BINARY_INTERFACE:-m88kdgux}/usr/lib/libm.a
123 #
124 # , the compilation tools expand the environment variables.)
005c1a0e 125 } else {
8e07c86e 126 print STDOUT "$thislib not found in $thispth\n" if $Verbose;
005c1a0e 127 next;
128 }
8e07c86e 129 print STDOUT "'-l$thislib' found at $fullname\n" if $Verbose;
4633a7c4 130 my($fullnamedir) = dirname($fullname);
131 push @ld_run_path, $fullnamedir unless $ld_run_path_seen{$fullnamedir}++;
005c1a0e 132 $found++;
133 $found_lib++;
134
135 # Now update library lists
136
137 # what do we know about this library...
4633a7c4 138 my $is_dyna = ($fullname !~ /\Q$Config_libext\E$/);
4e68a208 139 my $in_perl = ($libs =~ /\B-l\Q$ {thislib}\E\b/s);
005c1a0e 140
141 # Do not add it into the list if it is already linked in
142 # with the main perl executable.
974f612f 143 # We have to special-case the NeXT, because math and ndbm
144 # are both in libsys_s
005c1a0e 145 unless ($in_perl ||
974f612f 146 ($Config{'osname'} eq 'next' &&
147 ($thislib eq 'm' || $thislib eq 'ndbm')) ){
005c1a0e 148 push(@extralibs, "-l$thislib");
149 }
150
151 # We might be able to load this archive file dynamically
974f612f 152 if ( ($Config{'dlsrc'} =~ /dl_next/ && $Config{'osvers'} lt '4_0')
153 || ($Config{'dlsrc'} =~ /dl_dld/) )
154 {
005c1a0e 155 # We push -l$thislib instead of $fullname because
156 # it avoids hardwiring a fixed path into the .bs file.
157 # Mkbootstrap will automatically add dl_findfile() to
158 # the .bs file if it sees a name in the -l format.
159 # USE THIS, when dl_findfile() is fixed:
160 # push(@bsloadlibs, "-l$thislib");
161 # OLD USE WAS while checking results against old_extliblist
162 push(@bsloadlibs, "$fullname");
163 } else {
164 if ($is_dyna){
165 # For SunOS4, do not add in this shared library if
166 # it is already linked in the main perl executable
167 push(@ldloadlibs, "-l$thislib")
8f1aa56b 168 unless ($in_perl and $^O eq 'sunos');
005c1a0e 169 } else {
170 push(@ldloadlibs, "-l$thislib");
171 }
172 }
173 last; # found one here so don't bother looking further
174 }
864a5fa8 175 print STDOUT "Warning (will try anyway): No library found for -l$thislib\n"
005c1a0e 176 unless $found_lib>0;
177 }
4633a7c4 178 return ('','','','') unless $found;
179 ("@extralibs", "@bsloadlibs", "@ldloadlibs",join(":",@ld_run_path));
005c1a0e 180}
181
55497cff 182
183sub _vms_ext {
184 my($self, $potential_libs,$verbose) = @_;
185 return ('', '', '', '') unless $potential_libs;
186
187 my(@dirs,@libs,$dir,$lib,%sh,%olb,%obj);
188 my $cwd = cwd();
189 my($so,$lib_ext,$obj_ext) = @Config{'so','lib_ext','obj_ext'};
190 # List of common Unix library names and there VMS equivalents
191 # (VMS equivalent of '' indicates that the library is automatially
192 # searched by the linker, and should be skipped here.)
193 my %libmap = ( 'm' => '', 'f77' => '', 'F77' => '', 'V77' => '', 'c' => '',
194 'malloc' => '', 'crypt' => '', 'resolv' => '', 'c_s' => '',
195 'socket' => '', 'X11' => 'DECW$XLIBSHR',
196 'Xt' => 'DECW$XTSHR', 'Xm' => 'DECW$XMLIBSHR',
197 'Xmu' => 'DECW$XMULIBSHR');
198 if ($Config{'vms_cc_type'} ne 'decc') { $libmap{'curses'} = 'VAXCCURSE'; }
199
200 print STDOUT "Potential libraries are '$potential_libs'\n" if $verbose;
201
202 # First, sort out directories and library names in the input
203 foreach $lib (split ' ',$potential_libs) {
204 push(@dirs,$1), next if $lib =~ /^-L(.*)/;
205 push(@dirs,$lib), next if $lib =~ /[:>\]]$/;
206 push(@dirs,$lib), next if -d $lib;
207 push(@libs,$1), next if $lib =~ /^-l(.*)/;
208 push(@libs,$lib);
209 }
210 push(@dirs,split(' ',$Config{'libpth'}));
211
212 # Now make sure we've got VMS-syntax absolute directory specs
213 # (We don't, however, check whether someone's hidden a relative
214 # path in a logical name.)
215 foreach $dir (@dirs) {
216 unless (-d $dir) {
217 print STDOUT "Skipping nonexistent Directory $dir\n" if $verbose > 1;
218 $dir = '';
219 next;
220 }
221 print STDOUT "Resolving directory $dir\n" if $verbose;
222 if ($self->file_name_is_absolute($dir)) { $dir = $self->fixpath($dir,1); }
223 else { $dir = $self->catdir($cwd,$dir); }
224 }
225 @dirs = grep { length($_) } @dirs;
226 unshift(@dirs,''); # Check each $lib without additions first
227
228 LIB: foreach $lib (@libs) {
229 if (exists $libmap{$lib}) {
230 next unless length $libmap{$lib};
231 $lib = $libmap{$lib};
232 }
233
234 my(@variants,$variant,$name,$test,$cand);
235 my($ctype) = '';
236
237 # If we don't have a file type, consider it a possibly abbreviated name and
238 # check for common variants. We try these first to grab libraries before
239 # a like-named executable image (e.g. -lperl resolves to perlshr.exe
240 # before perl.exe).
241 if ($lib !~ /\.[^:>\]]*$/) {
242 push(@variants,"${lib}shr","${lib}rtl","${lib}lib");
243 push(@variants,"lib$lib") if $lib !~ /[:>\]]/;
244 }
245 push(@variants,$lib);
246 print STDOUT "Looking for $lib\n" if $verbose;
247 foreach $variant (@variants) {
248 foreach $dir (@dirs) {
249 my($type);
250
251 $name = "$dir$variant";
252 print "\tChecking $name\n" if $verbose > 2;
253 if (-f ($test = VMS::Filespec::rmsexpand($name))) {
254 # It's got its own suffix, so we'll have to figure out the type
255 if ($test =~ /(?:$so|exe)$/i) { $type = 'sh'; }
256 elsif ($test =~ /(?:$lib_ext|olb)$/i) { $type = 'olb'; }
257 elsif ($test =~ /(?:$obj_ext|obj)$/i) {
258 print STDOUT "Warning (will try anyway): Plain object file $test found in library list\n";
259 $type = 'obj';
260 }
261 else {
262 print STDOUT "Warning (will try anyway): Unknown library type for $test; assuming shared\n";
263 $type = 'sh';
264 }
265 }
266 elsif (-f ($test = VMS::Filespec::rmsexpand($name,$so)) or
267 -f ($test = VMS::Filespec::rmsexpand($name,'.exe'))) {
268 $type = 'sh';
269 $name = $test unless $test =~ /exe;?\d*$/i;
270 }
271 elsif (not length($ctype) and # If we've got a lib already, don't bother
272 ( -f ($test = VMS::Filespec::rmsexpand($name,$lib_ext)) or
273 -f ($test = VMS::Filespec::rmsexpand($name,'.olb')))) {
274 $type = 'olb';
275 $name = $test unless $test =~ /olb;?\d*$/i;
276 }
277 elsif (not length($ctype) and # If we've got a lib already, don't bother
278 ( -f ($test = VMS::Filespec::rmsexpand($name,$obj_ext)) or
279 -f ($test = VMS::Filespec::rmsexpand($name,'.obj')))) {
280 print STDOUT "Warning (will try anyway): Plain object file $test found in library list\n";
281 $type = 'obj';
282 $name = $test unless $test =~ /obj;?\d*$/i;
283 }
284 if (defined $type) {
285 $ctype = $type; $cand = $name;
286 last if $ctype eq 'sh';
287 }
288 }
289 if ($ctype) {
290 eval '$' . $ctype . "{'$cand'}++";
291 die "Error recording library: $@" if $@;
292 print STDOUT "\tFound as $name (really $test), type $type\n" if $verbose > 1;
293 next LIB;
294 }
295 }
296 print STDOUT "Warning (will try anyway): No library found for $lib\n";
297 }
298
299 @libs = sort keys %obj;
300 # This has to precede any other CRTLs, so just make it first
301 if ($olb{VAXCCURSE}) {
302 push(@libs,"$olb{VAXCCURSE}/Library");
303 delete $olb{VAXCCURSE};
304 }
305 push(@libs, map { "$_/Library" } sort keys %olb);
306 push(@libs, map { "$_/Share" } sort keys %sh);
307 $lib = join(' ',@libs);
308 print "Result: $lib\n" if $verbose;
309 wantarray ? ($lib, '', $lib, '') : $lib;
310}
311
005c1a0e 3121;
c2e89b3d 313
864a5fa8 314__END__
cb1a09d0 315
864a5fa8 316=head1 NAME
317
318ExtUtils::Liblist - determine libraries to use and how to use them
319
320=head1 SYNOPSIS
321
322C<require ExtUtils::Liblist;>
323
324C<ExtUtils::Liblist::ext($potential_libs, $Verbose);>
325
326=head1 DESCRIPTION
327
328This utility takes a list of libraries in the form C<-llib1 -llib2
329-llib3> and prints out lines suitable for inclusion in an extension
330Makefile. Extra library paths may be included with the form
331C<-L/another/path> this will affect the searches for all subsequent
332libraries.
333
334It returns an array of four scalar values: EXTRALIBS, BSLOADLIBS,
335LDLOADLIBS, and LD_RUN_PATH.
336
337Dependent libraries can be linked in one of three ways:
338
339=over 2
340
341=item * For static extensions
342
343by the ld command when the perl binary is linked with the extension
344library. See EXTRALIBS below.
345
346=item * For dynamic extensions
347
348by the ld command when the shared object is built/linked. See
349LDLOADLIBS below.
350
351=item * For dynamic extensions
352
353by the DynaLoader when the shared object is loaded. See BSLOADLIBS
354below.
355
356=back
357
358=head2 EXTRALIBS
359
360List of libraries that need to be linked with when linking a perl
361binary which includes this extension Only those libraries that
362actually exist are included. These are written to a file and used
363when linking perl.
364
365=head2 LDLOADLIBS and LD_RUN_PATH
366
367List of those libraries which can or must be linked into the shared
368library when created using ld. These may be static or dynamic
369libraries. LD_RUN_PATH is a colon separated list of the directories
370in LDLOADLIBS. It is passed as an environment variable to the process
371that links the shared library.
372
373=head2 BSLOADLIBS
374
375List of those libraries that are needed but can be linked in
376dynamically at run time on this platform. SunOS/Solaris does not need
377this because ld records the information (from LDLOADLIBS) into the
378object file. This list is used to create a .bs (bootstrap) file.
379
380=head1 PORTABILITY
381
382This module deals with a lot of system dependencies and has quite a
383few architecture specific B<if>s in the code.
384
55497cff 385=head2 VMS implementation
386
387The version of ext() which is executed under VMS differs from the
388Unix-OS/2 version in several respects:
389
390=over 2
391
392=item *
393
394Input library and path specifications are accepted with or without the
395C<-l> and C<-L> prefices used by Unix linkers. If neither prefix is
396present, a token is considered a directory to search if it is in fact
397a directory, and a library to search for otherwise. Authors who wish
398their extensions to be portable to Unix or OS/2 should use the Unix
399prefixes, since the Unix-OS/2 version of ext() requires them.
400
401=item *
402
403Wherever possible, shareable images are preferred to object libraries,
404and object libraries to plain object files. In accordance with VMS
405naming conventions, ext() looks for files named I<lib>shr and I<lib>rtl;
406it also looks for I<lib>lib and libI<lib> to accomodate Unix conventions
407used in some ported software.
408
409=item *
410
411For each library that is found, an appropriate directive for a linker options
412file is generated. The return values are space-separated strings of
413these directives, rather than elements used on the linker command line.
414
415=item *
416
417LDLOADLIBS and EXTRALIBS are always identical under VMS, and BSLOADLIBS
418and LD_RIN_PATH are always empty.
419
420=back
421
422In addition, an attempt is made to recognize several common Unix library
423names, and filter them out or convert them to their VMS equivalents, as
424appropriate.
425
426In general, the VMS version of ext() should properly handle input from
427extensions originally designed for a Unix or VMS environment. If you
428encounter problems, or discover cases where the search could be improved,
429please let us know.
430
864a5fa8 431=head1 SEE ALSO
432
433L<ExtUtils::MakeMaker>
434
435=cut
436