File Coverage

lib/ExtUtils/Mksymlists.pm
Criterion Covered Total %
statement 17 144 11.8
branch 0 72 0.0
condition 0 26 0.0
subroutine 6 12 50.0
pod 0 1 0.0
total 23 255 9.0


line stmt bran cond sub pod time code
1              
2             use 5.006;
3 1     1   6083 use strict qw[ subs refs ];
  1         3  
4 1     1   5 # no strict 'vars'; # until filehandles are exempted
  1         1  
  1         22  
5             use warnings;
6 1     1   4  
  1         1  
  1         21  
7             use Carp;
8 1     1   4 use Exporter;
  1         1  
  1         75  
9 1     1   5 use Config;
  1         2  
  1         38  
10 1     1   6  
  1         1  
  1         1707  
11             our @ISA = qw(Exporter);
12             our @EXPORT = qw(&Mksymlists);
13             our $VERSION = '7.64';
14             $VERSION =~ tr/_//d;
15              
16             my(%spec) = @_;
17             my($osname) = $^O;
18 0     0 0    
19 0           croak("Insufficient information specified to Mksymlists")
20             unless ( $spec{NAME} or
21             ($spec{FILE} and ($spec{DL_FUNCS} or $spec{FUNCLIST})) );
22              
23 0 0 0       $spec{DL_VARS} = [] unless $spec{DL_VARS};
      0        
      0        
24             ($spec{FILE} = $spec{NAME}) =~ s/.*::// unless $spec{FILE};
25 0 0         $spec{FUNCLIST} = [] unless $spec{FUNCLIST};
26 0 0         $spec{DL_FUNCS} = { $spec{NAME} => [] }
27 0 0         unless ( ($spec{DL_FUNCS} and keys %{$spec{DL_FUNCS}}) or
28             @{$spec{FUNCLIST}});
29 0           if (defined $spec{DL_FUNCS}) {
30 0 0 0       foreach my $package (sort keys %{$spec{DL_FUNCS}}) {
  0   0        
31 0 0         my($packprefix,$bootseen);
32 0           ($packprefix = $package) =~ s/\W/_/g;
  0            
33 0           foreach my $sym (@{$spec{DL_FUNCS}->{$package}}) {
34 0           if ($sym =~ /^boot_/) {
35 0           push(@{$spec{FUNCLIST}},$sym);
  0            
36 0 0         $bootseen++;
37 0           }
  0            
38 0           else {
39             push(@{$spec{FUNCLIST}},"XS_${packprefix}_$sym");
40             }
41 0           }
  0            
42             push(@{$spec{FUNCLIST}},"boot_$packprefix") unless $bootseen;
43             }
44 0 0         }
  0            
45              
46             # We'll need this if we ever add any OS which uses mod2fname
47             # not as pseudo-builtin.
48             # require DynaLoader;
49             if (defined &DynaLoader::mod2fname and not $spec{DLBASE}) {
50             $spec{DLBASE} = DynaLoader::mod2fname([ split(/::/,$spec{NAME}) ]);
51 0 0 0       }
52 0            
53             if ($osname eq 'aix') { _write_aix(\%spec); }
54             elsif ($osname eq 'MacOS'){ _write_aix(\%spec) }
55 0 0         elsif ($osname eq 'VMS') { _write_vms(\%spec) }
  0 0          
    0          
    0          
    0          
56 0           elsif ($osname eq 'os2') { _write_os2(\%spec) }
57 0           elsif ($osname eq 'MSWin32') { _write_win32(\%spec) }
58 0           else {
59 0           croak("Don't know how to create linker option file for $osname\n");
60             }
61 0           }
62              
63              
64             my($data) = @_;
65              
66             rename "$data->{FILE}.exp", "$data->{FILE}.exp_old";
67 0     0      
68             open( my $exp, ">", "$data->{FILE}.exp")
69 0           or croak("Can't create $data->{FILE}.exp: $!\n");
70             print $exp join("\n",@{$data->{DL_VARS}}, "\n") if @{$data->{DL_VARS}};
71 0 0         print $exp join("\n",@{$data->{FUNCLIST}}, "\n") if @{$data->{FUNCLIST}};
72             close $exp;
73 0 0         }
  0            
  0            
74 0 0          
  0            
  0            
75 0            
76             my($data) = @_;
77             require Config;
78             my $threaded = ($Config::Config{archname} =~ /-thread/ ? " threaded" : "");
79              
80 0     0     if (not $data->{DLBASE}) {
81 0           ($data->{DLBASE} = $data->{NAME}) =~ s/.*:://;
82 0 0         $data->{DLBASE} = substr($data->{DLBASE},0,7) . '_';
83             }
84 0 0         my $distname = $data->{DISTNAME} || $data->{NAME};
85 0           $distname = "Distribution $distname";
86 0           my $patchlevel = " pl$Config{perl_patchlevel}" || '';
87             my $comment = sprintf "Perl (v%s%s%s) module %s",
88 0   0       $Config::Config{version}, $threaded, $patchlevel, $data->{NAME};
89 0           chomp $comment;
90 0   0       if ($data->{INSTALLDIRS} and $data->{INSTALLDIRS} eq 'perl') {
91             $distname = 'perl5-porters@perl.org';
92 0           $comment = "Core $comment";
93 0           }
94 0 0 0       $comment = "$comment (Perl-config: $Config{config_args})";
95 0           $comment = substr($comment, 0, 200) . "...)" if length $comment > 203;
96 0           rename "$data->{FILE}.def", "$data->{FILE}_def.old";
97              
98 0           open(my $def, ">", "$data->{FILE}.def")
99 0 0         or croak("Can't create $data->{FILE}.def: $!\n");
100 0           print $def "LIBRARY '$data->{DLBASE}' INITINSTANCE TERMINSTANCE\n";
101             print $def "DESCRIPTION '\@#$distname:$data->{VERSION}#\@ $comment'\n";
102 0 0         print $def "CODE LOADONCALL\n";
103             print $def "DATA LOADONCALL NONSHARED MULTIPLE\n";
104 0           print $def "EXPORTS\n ";
105 0           print $def join("\n ",@{$data->{DL_VARS}}, "\n") if @{$data->{DL_VARS}};
106 0           print $def join("\n ",@{$data->{FUNCLIST}}, "\n") if @{$data->{FUNCLIST}};
107 0           _print_imports($def, $data);
108 0           close $def;
109 0 0         }
  0            
  0            
110 0 0          
  0            
  0            
111 0           my ($def, $data)= @_;
112 0           my $imports= $data->{IMPORTS}
113             or return;
114             if ( keys %$imports ) {
115             print $def "IMPORTS\n";
116 0     0     foreach my $name (sort keys %$imports) {
117             print $def " $name=$imports->{$name}\n";
118 0 0         }
119 0 0         }
120 0           }
121 0            
122 0           my($data) = @_;
123              
124             require Config;
125             if (not $data->{DLBASE}) {
126             ($data->{DLBASE} = $data->{NAME}) =~ s/.*:://;
127             $data->{DLBASE} = substr($data->{DLBASE},0,7) . '_';
128 0     0     }
129             rename "$data->{FILE}.def", "$data->{FILE}_def.old";
130 0            
131 0 0         open( my $def, ">", "$data->{FILE}.def" )
132 0           or croak("Can't create $data->{FILE}.def: $!\n");
133 0           # put library name in quotes (it could be a keyword, like 'Alias')
134             if ($Config::Config{'cc'} !~ /\bgcc/i) {
135 0           print $def "LIBRARY \"$data->{DLBASE}\"\n";
136             }
137 0 0         print $def "EXPORTS\n ";
138             my @syms;
139             # Export public symbols both with and without underscores to
140 0 0         # ensure compatibility between DLLs from Borland C and Visual C
141 0           # NOTE: DynaLoader itself only uses the names without underscores,
142             # so this is only to cover the case when the extension DLL may be
143 0           # linked to directly from C. GSAR 97-07-10
144 0            
145             #bcc dropped in 5.16, so dont create useless extra symbols for export table
146             unless("$]" >= 5.016) {
147             if ($Config::Config{'cc'} =~ /^bcc/i) {
148             push @syms, "_$_", "$_ = _$_"
149             for (@{$data->{DL_VARS}}, @{$data->{FUNCLIST}});
150             }
151             else {
152 0 0         push @syms, "$_", "_$_ = $_"
153 0 0         for (@{$data->{DL_VARS}}, @{$data->{FUNCLIST}});
154             }
155 0           } else {
  0            
  0            
156             push @syms, "$_"
157             for (@{$data->{DL_VARS}}, @{$data->{FUNCLIST}});
158             }
159 0           print $def join("\n ",@syms, "\n") if @syms;
  0            
  0            
160             _print_imports($def, $data);
161             close $def;
162             }
163 0            
  0            
  0            
164              
165 0 0         my($data) = @_;
166 0            
167 0           require Config; # a reminder for once we do $^O
168             require ExtUtils::XSSymSet;
169              
170             my($isvax) = $Config::Config{'archname'} =~ /VAX/i;
171             my($set) = new ExtUtils::XSSymSet;
172 0     0      
173             rename "$data->{FILE}.opt", "$data->{FILE}.opt_old";
174 0            
175 0           open(my $opt,">", "$data->{FILE}.opt")
176             or croak("Can't create $data->{FILE}.opt: $!\n");
177 0            
178 0           # Options file declaring universal symbols
179             # Used when linking shareable image for dynamic extension,
180 0           # or when linking PerlShr into which we've added this package
181             # as a static extension
182 0 0         # We don't do anything to preserve order, so we won't relax
183             # the GSMATCH criteria for a dynamic extension
184              
185             print $opt "case_sensitive=yes\n"
186             if $Config::Config{d_vms_case_sensitive_symbols};
187              
188             foreach my $sym (@{$data->{FUNCLIST}}) {
189             my $safe = $set->addsym($sym);
190             if ($isvax) { print $opt "UNIVERSAL=$safe\n" }
191             else { print $opt "SYMBOL_VECTOR=($safe=PROCEDURE)\n"; }
192             }
193 0 0          
194             foreach my $sym (@{$data->{DL_VARS}}) {
195 0           my $safe = $set->addsym($sym);
  0            
196 0           print $opt "PSECT_ATTR=${sym},PIC,OVR,RD,NOEXE,WRT,NOSHR\n";
197 0 0         if ($isvax) { print $opt "UNIVERSAL=$safe\n" }
  0            
198 0           else { print $opt "SYMBOL_VECTOR=($safe=DATA)\n"; }
199             }
200              
201 0           close $opt;
  0            
202 0           }
203 0            
204 0 0         1;
  0            
205 0            
206              
207             =head1 NAME
208 0            
209             ExtUtils::Mksymlists - write linker options files for dynamic extension
210              
211             =head1 SYNOPSIS
212              
213             use ExtUtils::Mksymlists;
214             Mksymlists( NAME => $name ,
215             DL_VARS => [ $var1, $var2, $var3 ],
216             DL_FUNCS => { $pkg1 => [ $func1, $func2 ],
217             $pkg2 => [ $func3 ] );
218              
219             =head1 DESCRIPTION
220              
221             C<ExtUtils::Mksymlists> produces files used by the linker under some OSs
222             during the creation of shared libraries for dynamic extensions. It is
223             normally called from a MakeMaker-generated Makefile when the extension
224             is built. The linker option file is generated by calling the function
225             C<Mksymlists>, which is exported by default from C<ExtUtils::Mksymlists>.
226             It takes one argument, a list of key-value pairs, in which the following
227             keys are recognized:
228              
229             =over 4
230              
231             =item DLBASE
232              
233             This item specifies the name by which the linker knows the
234             extension, which may be different from the name of the
235             extension itself (for instance, some linkers add an '_' to the
236             name of the extension). If it is not specified, it is derived
237             from the NAME attribute. It is presently used only by OS2 and Win32.
238              
239             =item DL_FUNCS
240              
241             This is identical to the DL_FUNCS attribute available via MakeMaker,
242             from which it is usually taken. Its value is a reference to an
243             associative array, in which each key is the name of a package, and
244             each value is an a reference to an array of function names which
245             should be exported by the extension. For instance, one might say
246             C<DL_FUNCS =E<gt> { Homer::Iliad =E<gt> [ qw(trojans greeks) ],
247             Homer::Odyssey =E<gt> [ qw(travellers family suitors) ] }>. The
248             function names should be identical to those in the XSUB code;
249             C<Mksymlists> will alter the names written to the linker option
250             file to match the changes made by F<xsubpp>. In addition, if
251             none of the functions in a list begin with the string B<boot_>,
252             C<Mksymlists> will add a bootstrap function for that package,
253             just as xsubpp does. (If a B<boot_E<lt>pkgE<gt>> function is
254             present in the list, it is passed through unchanged.) If
255             DL_FUNCS is not specified, it defaults to the bootstrap
256             function for the extension specified in NAME.
257              
258             =item DL_VARS
259              
260             This is identical to the DL_VARS attribute available via MakeMaker,
261             and, like DL_FUNCS, it is usually specified via MakeMaker. Its
262             value is a reference to an array of variable names which should
263             be exported by the extension.
264              
265             =item FILE
266              
267             This key can be used to specify the name of the linker option file
268             (minus the OS-specific extension), if for some reason you do not
269             want to use the default value, which is the last word of the NAME
270             attribute (I<e.g.> for C<Tk::Canvas>, FILE defaults to C<Canvas>).
271              
272             =item FUNCLIST
273              
274             This provides an alternate means to specify function names to be
275             exported from the extension. Its value is a reference to an
276             array of function names to be exported by the extension. These
277             names are passed through unaltered to the linker options file.
278             Specifying a value for the FUNCLIST attribute suppresses automatic
279             generation of the bootstrap function for the package. To still create
280             the bootstrap name you have to specify the package name in the
281             DL_FUNCS hash:
282              
283             Mksymlists( NAME => $name ,
284             FUNCLIST => [ $func1, $func2 ],
285             DL_FUNCS => { $pkg => [] } );
286              
287              
288             =item IMPORTS
289              
290             This attribute is used to specify names to be imported into the
291             extension. It is currently only used by OS/2 and Win32.
292              
293             =item NAME
294              
295             This gives the name of the extension (I<e.g.> C<Tk::Canvas>) for which
296             the linker option file will be produced.
297              
298             =back
299              
300             When calling C<Mksymlists>, one should always specify the NAME
301             attribute. In most cases, this is all that's necessary. In
302             the case of unusual extensions, however, the other attributes
303             can be used to provide additional information to the linker.
304              
305             =head1 AUTHOR
306              
307             Charles Bailey I<E<lt>bailey@newman.upenn.eduE<gt>>
308              
309             =head1 REVISION
310              
311             Last revised 14-Feb-1996, for Perl 5.002.