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