Commit | Line | Data |
c07a80fd |
1 | package ExtUtils::Mksymlists; |
2 | use strict qw[ subs refs ]; |
3 | # no strict 'vars'; # until filehandles are exempted |
4 | |
5 | use Carp; |
c07a80fd |
6 | use Exporter; |
f1387719 |
7 | use vars qw( @ISA @EXPORT $VERSION ); |
8 | @ISA = 'Exporter'; |
9 | @EXPORT = '&Mksymlists'; |
8a1da95f |
10 | $VERSION = substr q$Revision: 1.12 $, 10; |
c07a80fd |
11 | |
12 | sub Mksymlists { |
13 | my(%spec) = @_; |
f1387719 |
14 | my($osname) = $^O; |
c07a80fd |
15 | |
16 | croak("Insufficient information specified to Mksymlists") |
17 | unless ( $spec{NAME} or |
18 | ($spec{FILE} and ($spec{DL_FUNCS} or $spec{FUNCLIST})) ); |
19 | |
20 | $spec{DL_VARS} = [] unless $spec{DL_VARS}; |
21 | ($spec{FILE} = $spec{NAME}) =~ s/.*::// unless $spec{FILE}; |
22 | $spec{DL_FUNCS} = { $spec{NAME} => [] } |
23 | unless ( ($spec{DL_FUNCS} and keys %{$spec{DL_FUNCS}}) or |
24 | $spec{FUNCLIST}); |
25 | $spec{FUNCLIST} = [] unless $spec{FUNCLIST}; |
26 | if (defined $spec{DL_FUNCS}) { |
27 | my($package); |
28 | foreach $package (keys %{$spec{DL_FUNCS}}) { |
29 | my($packprefix,$sym,$bootseen); |
30 | ($packprefix = $package) =~ s/\W/_/g; |
31 | foreach $sym (@{$spec{DL_FUNCS}->{$package}}) { |
32 | if ($sym =~ /^boot_/) { |
33 | push(@{$spec{FUNCLIST}},$sym); |
34 | $bootseen++; |
35 | } |
36 | else { push(@{$spec{FUNCLIST}},"XS_${packprefix}_$sym"); } |
37 | } |
38 | push(@{$spec{FUNCLIST}},"boot_$packprefix") unless $bootseen; |
39 | } |
40 | } |
41 | |
42 | # We'll need this if we ever add any OS which uses mod2fname |
760ac839 |
43 | # not as pseudo-builtin. |
c07a80fd |
44 | # require DynaLoader; |
c2e89b3d |
45 | if (defined &DynaLoader::mod2fname and not $spec{DLBASE}) { |
46 | $spec{DLBASE} = DynaLoader::mod2fname([ split(/::/,$spec{NAME}) ]); |
47 | } |
c07a80fd |
48 | |
f1387719 |
49 | if ($osname eq 'aix') { _write_aix(\%spec); } |
50 | elsif ($osname eq 'VMS') { _write_vms(\%spec) } |
51 | elsif ($osname =~ m|^os/?2$|i) { _write_os2(\%spec) } |
52 | else { croak("Don't know how to create linker option file for $osname\n"); } |
c07a80fd |
53 | } |
54 | |
55 | |
56 | sub _write_aix { |
57 | my($data) = @_; |
58 | |
59 | rename "$data->{FILE}.exp", "$data->{FILE}.exp_old"; |
60 | |
61 | open(EXP,">$data->{FILE}.exp") |
62 | or croak("Can't create $data->{FILE}.exp: $!\n"); |
63 | print EXP join("\n",@{$data->{DL_VARS}}, "\n") if @{$data->{DL_VARS}}; |
64 | print EXP join("\n",@{$data->{FUNCLIST}}, "\n") if @{$data->{FUNCLIST}}; |
65 | close EXP; |
66 | } |
67 | |
68 | |
69 | sub _write_os2 { |
70 | my($data) = @_; |
71 | |
72 | if (not $data->{DLBASE}) { |
73 | ($data->{DLBASE} = $data->{NAME}) =~ s/.*:://; |
74 | $data->{DLBASE} = substr($data->{DLBASE},0,7) . '_'; |
75 | } |
76 | rename "$data->{FILE}.def", "$data->{FILE}_def.old"; |
77 | |
78 | open(DEF,">$data->{FILE}.def") |
79 | or croak("Can't create $data->{FILE}.def: $!\n"); |
80 | print DEF "LIBRARY '$data->{DLBASE}' INITINSTANCE TERMINSTANCE\n"; |
81 | print DEF "CODE LOADONCALL\n"; |
82 | print DEF "DATA LOADONCALL NONSHARED MULTIPLE\n"; |
c2e89b3d |
83 | print DEF "EXPORTS\n "; |
84 | print DEF join("\n ",@{$data->{DL_VARS}}, "\n") if @{$data->{DL_VARS}}; |
85 | print DEF join("\n ",@{$data->{FUNCLIST}}, "\n") if @{$data->{FUNCLIST}}; |
86 | if (%{$data->{IMPORTS}}) { |
87 | print DEF "IMPORTS\n"; |
88 | my ($name, $exp); |
89 | while (($name, $exp)= each %{$data->{IMPORTS}}) { |
90 | print DEF " $name=$exp\n"; |
91 | } |
92 | } |
c07a80fd |
93 | close DEF; |
94 | } |
95 | |
96 | |
97 | sub _write_vms { |
98 | my($data) = @_; |
a6e61155 |
99 | |
f1387719 |
100 | require Config; # a reminder for once we do $^O |
a6e61155 |
101 | |
102 | my($isvax) = $Config::Config{'arch'} =~ /VAX/i; |
c07a80fd |
103 | my($sym); |
104 | |
105 | rename "$data->{FILE}.opt", "$data->{FILE}.opt_old"; |
106 | |
107 | open(OPT,">$data->{FILE}.opt") |
108 | or croak("Can't create $data->{FILE}.opt: $!\n"); |
109 | |
110 | # Options file declaring universal symbols |
111 | # Used when linking shareable image for dynamic extension, |
112 | # or when linking PerlShr into which we've added this package |
113 | # as a static extension |
114 | # We don't do anything to preserve order, so we won't relax |
115 | # the GSMATCH criteria for a dynamic extension |
116 | |
117 | foreach $sym (@{$data->{FUNCLIST}}) { |
118 | if ($isvax) { print OPT "UNIVERSAL=$sym\n" } |
119 | else { print OPT "SYMBOL_VECTOR=($sym=PROCEDURE)\n"; } |
120 | } |
121 | foreach $sym (@{$data->{DL_VARS}}) { |
122 | print OPT "PSECT_ATTR=${sym},PIC,OVR,RD,NOEXE,WRT,NOSHR\n"; |
123 | if ($isvax) { print OPT "UNIVERSAL=$sym\n" } |
124 | else { print OPT "SYMBOL_VECTOR=($sym=DATA)\n"; } |
125 | } |
126 | close OPT; |
127 | |
128 | # Options file specifying RTLs to which this extension must be linked. |
129 | # Eventually, the list of libraries will be supplied by a working |
130 | # extliblist routine. |
131 | open OPT,'>rtls.opt'; |
132 | print OPT "PerlShr/Share\n"; |
a6e61155 |
133 | foreach $rtl (split(/\s+/,$Config::Config{'libs'})) { print OPT "$rtl\n"; } |
c07a80fd |
134 | close OPT; |
135 | } |
136 | |
137 | 1; |
138 | |
139 | __END__ |
140 | |
141 | =head1 NAME |
142 | |
143 | ExtUtils::Mksymlists - write linker options files for dynamic extension |
144 | |
145 | =head1 SYNOPSIS |
146 | |
147 | use ExtUtils::Mksymlists; |
148 | Mksymlists({ NAME => $name , |
149 | DL_VARS => [ $var1, $var2, $var3 ], |
150 | DL_FUNCS => { $pkg1 => [ $func1, $func2 ], |
151 | $pkg2 => [ $func3 ] }); |
152 | |
153 | =head1 DESCRIPTION |
154 | |
155 | C<ExtUtils::Mksymlists> produces files used by the linker under some OSs |
1fef88e7 |
156 | during the creation of shared libraries for dynamic extensions. It is |
c07a80fd |
157 | normally called from a MakeMaker-generated Makefile when the extension |
158 | is built. The linker option file is generated by calling the function |
159 | C<Mksymlists>, which is exported by default from C<ExtUtils::Mksymlists>. |
160 | It takes one argument, a list of key-value pairs, in which the following |
161 | keys are recognized: |
162 | |
163 | =item NAME |
164 | |
165 | This gives the name of the extension (I<e.g.> Tk::Canvas) for which |
166 | the linker option file will be produced. |
167 | |
168 | =item DL_FUNCS |
169 | |
170 | This is identical to the DL_FUNCS attribute available via MakeMaker, |
171 | from which it is usually taken. Its value is a reference to an |
172 | associative array, in which each key is the name of a package, and |
173 | each value is an a reference to an array of function names which |
174 | should be exported by the extension. For instance, one might say |
a5f75d66 |
175 | C<DL_FUNCS =E<gt> { Homer::Iliad =E<gt> [ qw(trojans greeks) ], |
176 | Homer::Odyssey =E<gt> [ qw(travellers family suitors) ] }>. The |
c07a80fd |
177 | function names should be identical to those in the XSUB code; |
178 | C<Mksymlists> will alter the names written to the linker option |
179 | file to match the changes made by F<xsubpp>. In addition, if |
180 | none of the functions in a list begin with the string B<boot_>, |
181 | C<Mksymlists> will add a bootstrap function for that package, |
182 | just as xsubpp does. (If a B<boot_E<lt>pkgE<gt>> function is |
183 | present in the list, it is passed through unchanged.) If |
184 | DL_FUNCS is not specified, it defaults to the bootstrap |
185 | function for the extension specified in NAME. |
186 | |
187 | =item DL_VARS |
188 | |
189 | This is identical to the DL_VARS attribute available via MakeMaker, |
190 | and, like DL_FUNCS, it is usually specified via MakeMaker. Its |
191 | value is a reference to an array of variable names which should |
192 | be exported by the extension. |
193 | |
194 | =item FILE |
195 | |
196 | This key can be used to specify the name of the linker option file |
197 | (minus the OS-specific extension), if for some reason you do not |
198 | want to use the default value, which is the last word of the NAME |
199 | attribute (I<e.g.> for Tk::Canvas, FILE defaults to 'Canvas'). |
200 | |
201 | =item FUNCLIST |
202 | |
203 | This provides an alternate means to specify function names to be |
204 | exported from the extension. Its value is a reference to an |
205 | array of function names to be exported by the extension. These |
206 | names are passed through unaltered to the linker options file. |
207 | |
208 | =item DLBASE |
209 | |
210 | This item specifies the name by which the linker knows the |
211 | extension, which may be different from the name of the |
212 | extension itself (for instance, some linkers add an '_' to the |
213 | name of the extension). If it is not specified, it is derived |
214 | from the NAME attribute. It is presently used only by OS2. |
215 | |
216 | When calling C<Mksymlists>, one should always specify the NAME |
217 | attribute. In most cases, this is all that's necessary. In |
218 | the case of unusual extensions, however, the other attributes |
219 | can be used to provide additional information to the linker. |
220 | |
221 | =head1 AUTHOR |
222 | |
223 | Charles Bailey I<E<lt>bailey@genetics.upenn.eduE<gt>> |
224 | |
225 | =head1 REVISION |
226 | |
a5f75d66 |
227 | Last revised 14-Feb-1996, for Perl 5.002. |