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