1 package ExtUtils::Mksymlists;
4 use strict qw[ subs refs ];
5 # no strict 'vars'; # until filehandles are exempted
12 our @ISA = qw(Exporter);
13 our @EXPORT = qw(&Mksymlists);
14 our $VERSION = '7.52';
21 croak("Insufficient information specified to Mksymlists")
22 unless ( $spec{NAME} or
23 ($spec{FILE} and ($spec{DL_FUNCS} or $spec{FUNCLIST})) );
25 $spec{DL_VARS} = [] unless $spec{DL_VARS};
26 ($spec{FILE} = $spec{NAME}) =~ s/.*::// unless $spec{FILE};
27 $spec{FUNCLIST} = [] unless $spec{FUNCLIST};
28 $spec{DL_FUNCS} = { $spec{NAME} => [] }
29 unless ( ($spec{DL_FUNCS} and keys %{$spec{DL_FUNCS}}) or
31 if (defined $spec{DL_FUNCS}) {
32 foreach my $package (sort keys %{$spec{DL_FUNCS}}) {
33 my($packprefix,$bootseen);
34 ($packprefix = $package) =~ s/\W/_/g;
35 foreach my $sym (@{$spec{DL_FUNCS}->{$package}}) {
36 if ($sym =~ /^boot_/) {
37 push(@{$spec{FUNCLIST}},$sym);
41 push(@{$spec{FUNCLIST}},"XS_${packprefix}_$sym");
44 push(@{$spec{FUNCLIST}},"boot_$packprefix") unless $bootseen;
48 # We'll need this if we ever add any OS which uses mod2fname
49 # not as pseudo-builtin.
51 if (defined &DynaLoader::mod2fname and not $spec{DLBASE}) {
52 $spec{DLBASE} = DynaLoader::mod2fname([ split(/::/,$spec{NAME}) ]);
55 if ($osname eq 'aix') { _write_aix(\%spec); }
56 elsif ($osname eq 'MacOS'){ _write_aix(\%spec) }
57 elsif ($osname eq 'VMS') { _write_vms(\%spec) }
58 elsif ($osname eq 'os2') { _write_os2(\%spec) }
59 elsif ($osname eq 'MSWin32') { _write_win32(\%spec) }
61 croak("Don't know how to create linker option file for $osname\n");
69 rename "$data->{FILE}.exp", "$data->{FILE}.exp_old";
71 open( my $exp, ">", "$data->{FILE}.exp")
72 or croak("Can't create $data->{FILE}.exp: $!\n");
73 print $exp join("\n",@{$data->{DL_VARS}}, "\n") if @{$data->{DL_VARS}};
74 print $exp join("\n",@{$data->{FUNCLIST}}, "\n") if @{$data->{FUNCLIST}};
82 my $threaded = ($Config::Config{archname} =~ /-thread/ ? " threaded" : "");
84 if (not $data->{DLBASE}) {
85 ($data->{DLBASE} = $data->{NAME}) =~ s/.*:://;
86 $data->{DLBASE} = substr($data->{DLBASE},0,7) . '_';
88 my $distname = $data->{DISTNAME} || $data->{NAME};
89 $distname = "Distribution $distname";
90 my $patchlevel = " pl$Config{perl_patchlevel}" || '';
91 my $comment = sprintf "Perl (v%s%s%s) module %s",
92 $Config::Config{version}, $threaded, $patchlevel, $data->{NAME};
94 if ($data->{INSTALLDIRS} and $data->{INSTALLDIRS} eq 'perl') {
95 $distname = 'perl5-porters@perl.org';
96 $comment = "Core $comment";
98 $comment = "$comment (Perl-config: $Config{config_args})";
99 $comment = substr($comment, 0, 200) . "...)" if length $comment > 203;
100 rename "$data->{FILE}.def", "$data->{FILE}_def.old";
102 open(my $def, ">", "$data->{FILE}.def")
103 or croak("Can't create $data->{FILE}.def: $!\n");
104 print $def "LIBRARY '$data->{DLBASE}' INITINSTANCE TERMINSTANCE\n";
105 print $def "DESCRIPTION '\@#$distname:$data->{VERSION}#\@ $comment'\n";
106 print $def "CODE LOADONCALL\n";
107 print $def "DATA LOADONCALL NONSHARED MULTIPLE\n";
108 print $def "EXPORTS\n ";
109 print $def join("\n ",@{$data->{DL_VARS}}, "\n") if @{$data->{DL_VARS}};
110 print $def join("\n ",@{$data->{FUNCLIST}}, "\n") if @{$data->{FUNCLIST}};
111 _print_imports($def, $data);
116 my ($def, $data)= @_;
117 my $imports= $data->{IMPORTS}
119 if ( keys %$imports ) {
120 print $def "IMPORTS\n";
121 foreach my $name (sort keys %$imports) {
122 print $def " $name=$imports->{$name}\n";
131 if (not $data->{DLBASE}) {
132 ($data->{DLBASE} = $data->{NAME}) =~ s/.*:://;
133 $data->{DLBASE} = substr($data->{DLBASE},0,7) . '_';
135 rename "$data->{FILE}.def", "$data->{FILE}_def.old";
137 open( my $def, ">", "$data->{FILE}.def" )
138 or croak("Can't create $data->{FILE}.def: $!\n");
139 # put library name in quotes (it could be a keyword, like 'Alias')
140 if ($Config::Config{'cc'} !~ /\bgcc/i) {
141 print $def "LIBRARY \"$data->{DLBASE}\"\n";
143 print $def "EXPORTS\n ";
145 # Export public symbols both with and without underscores to
146 # ensure compatibility between DLLs from Borland C and Visual C
147 # NOTE: DynaLoader itself only uses the names without underscores,
148 # so this is only to cover the case when the extension DLL may be
149 # linked to directly from C. GSAR 97-07-10
151 #bcc dropped in 5.16, so dont create useless extra symbols for export table
152 unless("$]" >= 5.016) {
153 if ($Config::Config{'cc'} =~ /^bcc/i) {
154 push @syms, "_$_", "$_ = _$_"
155 for (@{$data->{DL_VARS}}, @{$data->{FUNCLIST}});
158 push @syms, "$_", "_$_ = $_"
159 for (@{$data->{DL_VARS}}, @{$data->{FUNCLIST}});
163 for (@{$data->{DL_VARS}}, @{$data->{FUNCLIST}});
165 print $def join("\n ",@syms, "\n") if @syms;
166 _print_imports($def, $data);
174 require Config; # a reminder for once we do $^O
175 require ExtUtils::XSSymSet;
177 my($isvax) = $Config::Config{'archname'} =~ /VAX/i;
178 my($set) = new ExtUtils::XSSymSet;
180 rename "$data->{FILE}.opt", "$data->{FILE}.opt_old";
182 open(my $opt,">", "$data->{FILE}.opt")
183 or croak("Can't create $data->{FILE}.opt: $!\n");
185 # Options file declaring universal symbols
186 # Used when linking shareable image for dynamic extension,
187 # or when linking PerlShr into which we've added this package
188 # as a static extension
189 # We don't do anything to preserve order, so we won't relax
190 # the GSMATCH criteria for a dynamic extension
192 print $opt "case_sensitive=yes\n"
193 if $Config::Config{d_vms_case_sensitive_symbols};
195 foreach my $sym (@{$data->{FUNCLIST}}) {
196 my $safe = $set->addsym($sym);
197 if ($isvax) { print $opt "UNIVERSAL=$safe\n" }
198 else { print $opt "SYMBOL_VECTOR=($safe=PROCEDURE)\n"; }
201 foreach my $sym (@{$data->{DL_VARS}}) {
202 my $safe = $set->addsym($sym);
203 print $opt "PSECT_ATTR=${sym},PIC,OVR,RD,NOEXE,WRT,NOSHR\n";
204 if ($isvax) { print $opt "UNIVERSAL=$safe\n" }
205 else { print $opt "SYMBOL_VECTOR=($safe=DATA)\n"; }
217 ExtUtils::Mksymlists - write linker options files for dynamic extension
221 use ExtUtils::Mksymlists;
222 Mksymlists( NAME => $name ,
223 DL_VARS => [ $var1, $var2, $var3 ],
224 DL_FUNCS => { $pkg1 => [ $func1, $func2 ],
225 $pkg2 => [ $func3 ] );
229 C<ExtUtils::Mksymlists> produces files used by the linker under some OSs
230 during the creation of shared libraries for dynamic extensions. It is
231 normally called from a MakeMaker-generated Makefile when the extension
232 is built. The linker option file is generated by calling the function
233 C<Mksymlists>, which is exported by default from C<ExtUtils::Mksymlists>.
234 It takes one argument, a list of key-value pairs, in which the following
241 This item specifies the name by which the linker knows the
242 extension, which may be different from the name of the
243 extension itself (for instance, some linkers add an '_' to the
244 name of the extension). If it is not specified, it is derived
245 from the NAME attribute. It is presently used only by OS2 and Win32.
249 This is identical to the DL_FUNCS attribute available via MakeMaker,
250 from which it is usually taken. Its value is a reference to an
251 associative array, in which each key is the name of a package, and
252 each value is an a reference to an array of function names which
253 should be exported by the extension. For instance, one might say
254 C<DL_FUNCS =E<gt> { Homer::Iliad =E<gt> [ qw(trojans greeks) ],
255 Homer::Odyssey =E<gt> [ qw(travellers family suitors) ] }>. The
256 function names should be identical to those in the XSUB code;
257 C<Mksymlists> will alter the names written to the linker option
258 file to match the changes made by F<xsubpp>. In addition, if
259 none of the functions in a list begin with the string B<boot_>,
260 C<Mksymlists> will add a bootstrap function for that package,
261 just as xsubpp does. (If a B<boot_E<lt>pkgE<gt>> function is
262 present in the list, it is passed through unchanged.) If
263 DL_FUNCS is not specified, it defaults to the bootstrap
264 function for the extension specified in NAME.
268 This is identical to the DL_VARS attribute available via MakeMaker,
269 and, like DL_FUNCS, it is usually specified via MakeMaker. Its
270 value is a reference to an array of variable names which should
271 be exported by the extension.
275 This key can be used to specify the name of the linker option file
276 (minus the OS-specific extension), if for some reason you do not
277 want to use the default value, which is the last word of the NAME
278 attribute (I<e.g.> for C<Tk::Canvas>, FILE defaults to C<Canvas>).
282 This provides an alternate means to specify function names to be
283 exported from the extension. Its value is a reference to an
284 array of function names to be exported by the extension. These
285 names are passed through unaltered to the linker options file.
286 Specifying a value for the FUNCLIST attribute suppresses automatic
287 generation of the bootstrap function for the package. To still create
288 the bootstrap name you have to specify the package name in the
291 Mksymlists( NAME => $name ,
292 FUNCLIST => [ $func1, $func2 ],
293 DL_FUNCS => { $pkg => [] } );
298 This attribute is used to specify names to be imported into the
299 extension. It is currently only used by OS/2 and Win32.
303 This gives the name of the extension (I<e.g.> C<Tk::Canvas>) for which
304 the linker option file will be produced.
308 When calling C<Mksymlists>, one should always specify the NAME
309 attribute. In most cases, this is all that's necessary. In
310 the case of unusual extensions, however, the other attributes
311 can be used to provide additional information to the linker.
315 Charles Bailey I<E<lt>bailey@newman.upenn.eduE<gt>>
319 Last revised 14-Feb-1996, for Perl 5.002.