ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/staticperl/perl/lib/ExtUtils/MM_Win32.pm
Revision: 1.1
Committed: Thu Jun 30 14:27:11 2005 UTC (21 years, 4 months ago) by root
Branch: MAIN
CVS Tags: PERL-5-8-7, HEAD
Branch point for: PERL
Log Message:
*** empty log message ***

File Contents

# Content
1 package ExtUtils::MM_Win32;
2
3 use strict;
4
5
6 =head1 NAME
7
8 ExtUtils::MM_Win32 - methods to override UN*X behaviour in ExtUtils::MakeMaker
9
10 =head1 SYNOPSIS
11
12 use ExtUtils::MM_Win32; # Done internally by ExtUtils::MakeMaker if needed
13
14 =head1 DESCRIPTION
15
16 See ExtUtils::MM_Unix for a documentation of the methods provided
17 there. This package overrides the implementation of these methods, not
18 the semantics.
19
20 =cut
21
22 use Config;
23 use File::Basename;
24 use File::Spec;
25 use ExtUtils::MakeMaker qw( neatvalue );
26
27 use vars qw(@ISA $VERSION $BORLAND $GCC $DMAKE $NMAKE);
28
29 require ExtUtils::MM_Any;
30 require ExtUtils::MM_Unix;
31 @ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix );
32 $VERSION = '1.09';
33
34 $ENV{EMXSHELL} = 'sh'; # to run `commands`
35
36 $BORLAND = 1 if $Config{'cc'} =~ /^bcc/i;
37 $GCC = 1 if $Config{'cc'} =~ /^gcc/i;
38 $DMAKE = 1 if $Config{'make'} =~ /^dmake/i;
39 $NMAKE = 1 if $Config{'make'} =~ /^nmake/i;
40
41
42 =head2 Overridden methods
43
44 =over 4
45
46 =item B<dlsyms>
47
48 =cut
49
50 sub dlsyms {
51 my($self,%attribs) = @_;
52
53 my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {};
54 my($vars) = $attribs{DL_VARS} || $self->{DL_VARS} || [];
55 my($funclist) = $attribs{FUNCLIST} || $self->{FUNCLIST} || [];
56 my($imports) = $attribs{IMPORTS} || $self->{IMPORTS} || {};
57 my(@m);
58
59 if (not $self->{SKIPHASH}{'dynamic'}) {
60 push(@m,"
61 $self->{BASEEXT}.def: Makefile.PL
62 ",
63 q! $(PERLRUN) -MExtUtils::Mksymlists \\
64 -e "Mksymlists('NAME'=>\"!, $self->{NAME},
65 q!\", 'DLBASE' => '!,$self->{DLBASE},
66 # The above two lines quoted differently to work around
67 # a bug in the 4DOS/4NT command line interpreter. The visible
68 # result of the bug was files named q('extension_name',) *with the
69 # single quotes and the comma* in the extension build directories.
70 q!', 'DL_FUNCS' => !,neatvalue($funcs),
71 q!, 'FUNCLIST' => !,neatvalue($funclist),
72 q!, 'IMPORTS' => !,neatvalue($imports),
73 q!, 'DL_VARS' => !, neatvalue($vars), q!);"
74 !);
75 }
76 join('',@m);
77 }
78
79 =item replace_manpage_separator
80
81 Changes the path separator with .
82
83 =cut
84
85 sub replace_manpage_separator {
86 my($self,$man) = @_;
87 $man =~ s,/+,.,g;
88 $man;
89 }
90
91
92 =item B<maybe_command>
93
94 Since Windows has nothing as simple as an executable bit, we check the
95 file extension.
96
97 The PATHEXT env variable will be used to get a list of extensions that
98 might indicate a command, otherwise .com, .exe, .bat and .cmd will be
99 used by default.
100
101 =cut
102
103 sub maybe_command {
104 my($self,$file) = @_;
105 my @e = exists($ENV{'PATHEXT'})
106 ? split(/;/, $ENV{PATHEXT})
107 : qw(.com .exe .bat .cmd);
108 my $e = '';
109 for (@e) { $e .= "\Q$_\E|" }
110 chop $e;
111 # see if file ends in one of the known extensions
112 if ($file =~ /($e)$/i) {
113 return $file if -e $file;
114 }
115 else {
116 for (@e) {
117 return "$file$_" if -e "$file$_";
118 }
119 }
120 return;
121 }
122
123
124 =item B<find_tests>
125
126 The Win9x shell does not expand globs and I'll play it safe and assume
127 other Windows variants don't either.
128
129 So we do it for them.
130
131 =cut
132
133 sub find_tests {
134 return join(' ', <t\\*.t>);
135 }
136
137
138 =item B<init_DIRFILESEP>
139
140 Using \ for Windows.
141
142 =cut
143
144 sub init_DIRFILESEP {
145 my($self) = shift;
146
147 # The ^ makes sure its not interpreted as an escape in nmake
148 $self->{DIRFILESEP} = $NMAKE ? '^\\' :
149 $DMAKE ? '\\\\'
150 : '\\';
151 }
152
153 =item B<init_others>
154
155 Override some of the Unix specific commands with portable
156 ExtUtils::Command ones.
157
158 Also provide defaults for LD and AR in case the %Config values aren't
159 set.
160
161 LDLOADLIBS's default is changed to $Config{libs}.
162
163 Adjustments are made for Borland's quirks needing -L to come first.
164
165 =cut
166
167 sub init_others {
168 my ($self) = @_;
169
170 # Used in favor of echo because echo won't strip quotes. :(
171 $self->{ECHO} ||= $self->oneliner('print qq{@ARGV}', ['-l']);
172 $self->{ECHO_N} ||= $self->oneliner('print qq{@ARGV}');
173
174 $self->{TOUCH} ||= '$(PERLRUN) -MExtUtils::Command -e touch';
175 $self->{CHMOD} ||= '$(PERLRUN) -MExtUtils::Command -e chmod';
176 $self->{CP} ||= '$(PERLRUN) -MExtUtils::Command -e cp';
177 $self->{RM_F} ||= '$(PERLRUN) -MExtUtils::Command -e rm_f';
178 $self->{RM_RF} ||= '$(PERLRUN) -MExtUtils::Command -e rm_rf';
179 $self->{MV} ||= '$(PERLRUN) -MExtUtils::Command -e mv';
180 $self->{NOOP} ||= 'rem';
181 $self->{TEST_F} ||= '$(PERLRUN) -MExtUtils::Command -e test_f';
182 $self->{DEV_NULL} ||= '> NUL';
183
184 $self->{LD} ||= $Config{ld} || 'link';
185 $self->{AR} ||= $Config{ar} || 'lib';
186
187 $self->SUPER::init_others;
188
189 # Setting SHELL from $Config{sh} can break dmake. Its ok without it.
190 delete $self->{SHELL};
191
192 $self->{LDLOADLIBS} ||= $Config{libs};
193 # -Lfoo must come first for Borland, so we put it in LDDLFLAGS
194 if ($BORLAND) {
195 my $libs = $self->{LDLOADLIBS};
196 my $libpath = '';
197 while ($libs =~ s/(?:^|\s)(("?)-L.+?\2)(?:\s|$)/ /) {
198 $libpath .= ' ' if length $libpath;
199 $libpath .= $1;
200 }
201 $self->{LDLOADLIBS} = $libs;
202 $self->{LDDLFLAGS} ||= $Config{lddlflags};
203 $self->{LDDLFLAGS} .= " $libpath";
204 }
205
206 return 1;
207 }
208
209
210 =item init_platform (o)
211
212 Add MM_Win32_VERSION.
213
214 =item platform_constants (o)
215
216 =cut
217
218 sub init_platform {
219 my($self) = shift;
220
221 $self->{MM_Win32_VERSION} = $VERSION;
222 }
223
224 sub platform_constants {
225 my($self) = shift;
226 my $make_frag = '';
227
228 foreach my $macro (qw(MM_Win32_VERSION))
229 {
230 next unless defined $self->{$macro};
231 $make_frag .= "$macro = $self->{$macro}\n";
232 }
233
234 return $make_frag;
235 }
236
237
238 =item special_targets (o)
239
240 Add .USESHELL target for dmake.
241
242 =cut
243
244 sub special_targets {
245 my($self) = @_;
246
247 my $make_frag = $self->SUPER::special_targets;
248
249 $make_frag .= <<'MAKE_FRAG' if $DMAKE;
250 .USESHELL :
251 MAKE_FRAG
252
253 return $make_frag;
254 }
255
256
257 =item static_lib (o)
258
259 Changes how to run the linker.
260
261 The rest is duplicate code from MM_Unix. Should move the linker code
262 to its own method.
263
264 =cut
265
266 sub static_lib {
267 my($self) = @_;
268 return '' unless $self->has_link_code;
269
270 my(@m);
271 push(@m, <<'END');
272 $(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists
273 $(RM_RF) $@
274 END
275
276 # If this extension has its own library (eg SDBM_File)
277 # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
278 push @m, <<'MAKE_FRAG' if $self->{MYEXTLIB};
279 $(CP) $(MYEXTLIB) $@
280 MAKE_FRAG
281
282 push @m,
283 q{ $(AR) }.($BORLAND ? '$@ $(OBJECT:^"+")'
284 : ($GCC ? '-ru $@ $(OBJECT)'
285 : '-out:$@ $(OBJECT)')).q{
286 $(CHMOD) $(PERM_RWX) $@
287 $(NOECHO) $(ECHO) "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)\extralibs.ld
288 };
289
290 # Old mechanism - still available:
291 push @m, <<'MAKE_FRAG' if $self->{PERL_SRC} && $self->{EXTRALIBS};
292 $(NOECHO) $(ECHO) "$(EXTRALIBS)" >> $(PERL_SRC)\ext.libs
293 MAKE_FRAG
294
295 push @m, "\n", $self->dir_target('$(INST_ARCHAUTODIR)');
296 join('', @m);
297 }
298
299
300 =item dynamic_lib (o)
301
302 Complicated stuff for Win32 that I don't understand. :(
303
304 =cut
305
306 sub dynamic_lib {
307 my($self, %attribs) = @_;
308 return '' unless $self->needs_linking(); #might be because of a subdir
309
310 return '' unless $self->has_link_code;
311
312 my($otherldflags) = $attribs{OTHERLDFLAGS} || ($BORLAND ? 'c0d32.obj': '');
313 my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || "";
314 my($ldfrom) = '$(LDFROM)';
315 my(@m);
316
317 # one thing for GCC/Mingw32:
318 # we try to overcome non-relocateable-DLL problems by generating
319 # a (hopefully unique) image-base from the dll's name
320 # -- BKS, 10-19-1999
321 if ($GCC) {
322 my $dllname = $self->{BASEEXT} . "." . $self->{DLEXT};
323 $dllname =~ /(....)(.{0,4})/;
324 my $baseaddr = unpack("n", $1 ^ $2);
325 $otherldflags .= sprintf("-Wl,--image-base,0x%x0000 ", $baseaddr);
326 }
327
328 push(@m,'
329 # This section creates the dynamically loadable $(INST_DYNAMIC)
330 # from $(OBJECT) and possibly $(MYEXTLIB).
331 OTHERLDFLAGS = '.$otherldflags.'
332 INST_DYNAMIC_DEP = '.$inst_dynamic_dep.'
333
334 $(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP)
335 ');
336 if ($GCC) {
337 push(@m,
338 q{ dlltool --def $(EXPORT_LIST) --output-exp dll.exp
339 $(LD) -o $@ -Wl,--base-file -Wl,dll.base $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) $(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) dll.exp
340 dlltool --def $(EXPORT_LIST) --base-file dll.base --output-exp dll.exp
341 $(LD) -o $@ $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) $(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) dll.exp });
342 } elsif ($BORLAND) {
343 push(@m,
344 q{ $(LD) $(LDDLFLAGS) $(OTHERLDFLAGS) }.$ldfrom.q{,$@,,}
345 .($DMAKE ? q{$(PERL_ARCHIVE:s,/,\,) $(LDLOADLIBS:s,/,\,) }
346 .q{$(MYEXTLIB:s,/,\,),$(EXPORT_LIST:s,/,\,)}
347 : q{$(subst /,\,$(PERL_ARCHIVE)) $(subst /,\,$(LDLOADLIBS)) }
348 .q{$(subst /,\,$(MYEXTLIB)),$(subst /,\,$(EXPORT_LIST))})
349 .q{,$(RESFILES)});
350 } else { # VC
351 push(@m,
352 q{ $(LD) -out:$@ $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) }
353 .q{$(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) -def:$(EXPORT_LIST)});
354 }
355 push @m, '
356 $(CHMOD) $(PERM_RWX) $@
357 ';
358
359 push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
360 join('',@m);
361 }
362
363 =item clean
364
365 Clean out some extra dll.{base,exp} files which might be generated by
366 gcc. Otherwise, take out all *.pdb files.
367
368 =cut
369
370 sub clean
371 {
372 my ($self) = shift;
373 my $s = $self->SUPER::clean(@_);
374 my $clean = $GCC ? 'dll.base dll.exp' : '*.pdb';
375 $s .= <<END;
376 clean ::
377 -\$(RM_F) $clean
378
379 END
380 return $s;
381 }
382
383 =item init_linker
384
385 =cut
386
387 sub init_linker {
388 my $self = shift;
389
390 $self->{PERL_ARCHIVE} = "\$(PERL_INC)\\$Config{libperl}";
391 $self->{PERL_ARCHIVE_AFTER} = '';
392 $self->{EXPORT_LIST} = '$(BASEEXT).def';
393 }
394
395
396 =item perl_script
397
398 Checks for the perl program under several common perl extensions.
399
400 =cut
401
402 sub perl_script {
403 my($self,$file) = @_;
404 return $file if -r $file && -f _;
405 return "$file.pl" if -r "$file.pl" && -f _;
406 return "$file.plx" if -r "$file.plx" && -f _;
407 return "$file.bat" if -r "$file.bat" && -f _;
408 return;
409 }
410
411
412 =item xs_o (o)
413
414 This target is stubbed out. Not sure why.
415
416 =cut
417
418 sub xs_o {
419 return ''
420 }
421
422
423 =item pasthru (o)
424
425 All we send is -nologo to nmake to prevent it from printing its damned
426 banner.
427
428 =cut
429
430 sub pasthru {
431 my($self) = shift;
432 return "PASTHRU = " . ($NMAKE ? "-nologo" : "");
433 }
434
435
436 =item oneliner (o)
437
438 These are based on what command.com does on Win98. They may be wrong
439 for other Windows shells, I don't know.
440
441 =cut
442
443 sub oneliner {
444 my($self, $cmd, $switches) = @_;
445 $switches = [] unless defined $switches;
446
447 # Strip leading and trailing newlines
448 $cmd =~ s{^\n+}{};
449 $cmd =~ s{\n+$}{};
450
451 $cmd = $self->quote_literal($cmd);
452 $cmd = $self->escape_newlines($cmd);
453
454 $switches = join ' ', @$switches;
455
456 return qq{\$(PERLRUN) $switches -e $cmd};
457 }
458
459
460 sub quote_literal {
461 my($self, $text) = @_;
462
463 # I don't know if this is correct, but it seems to work on
464 # Win98's command.com
465 $text =~ s{"}{\\"}g;
466
467 # dmake eats '{' inside double quotes and leaves alone { outside double
468 # quotes; however it transforms {{ into { either inside and outside double
469 # quotes. It also translates }} into }. The escaping below is not
470 # 100% correct.
471 if( $DMAKE ) {
472 $text =~ s/{/{{/g;
473 $text =~ s/}}/}}}/g;
474 }
475
476 return qq{"$text"};
477 }
478
479
480 sub escape_newlines {
481 my($self, $text) = @_;
482
483 # Escape newlines
484 $text =~ s{\n}{\\\n}g;
485
486 return $text;
487 }
488
489
490 =item max_exec_len
491
492 nmake 1.50 limits command length to 2048 characters.
493
494 =cut
495
496 sub max_exec_len {
497 my $self = shift;
498
499 return $self->{_MAX_EXEC_LEN} ||= 2 * 1024;
500 }
501
502
503 =item os_flavor
504
505 Windows is Win32.
506
507 =cut
508
509 sub os_flavor {
510 return('Win32');
511 }
512
513
514 1;
515 __END__
516
517 =back
518
519 =cut
520
521