File Coverage

lib/ExtUtils/MM_Win32.pm
Criterion Covered Total %
statement 31 206 15.0
branch 5 102 4.9
condition 0 44 0.0
subroutine 8 40 20.0
pod 32 32 100.0
total 76 424 17.9


line stmt bran cond sub pod time code
1              
2             use strict;
3 2     2   35451 use warnings;
  2         11  
  2         49  
4 2     2   9  
  2         11  
  2         78  
5             =head1 NAME
6              
7             ExtUtils::MM_Win32 - methods to override UN*X behaviour in ExtUtils::MakeMaker
8              
9             =head1 SYNOPSIS
10              
11             use ExtUtils::MM_Win32; # Done internally by ExtUtils::MakeMaker if needed
12              
13             =head1 DESCRIPTION
14              
15             See L<ExtUtils::MM_Unix> for a documentation of the methods provided
16             there. This package overrides the implementation of these methods, not
17             the semantics.
18              
19             =cut
20              
21             use ExtUtils::MakeMaker::Config;
22 2     2   388 use File::Basename;
  2         6  
  2         12  
23 2     2   13 use File::Spec;
  2         4  
  2         173  
24 2     2   12 use ExtUtils::MakeMaker qw(neatvalue _sprintf562);
  2         3  
  2         55  
25 2     2   705  
  2         5  
  2         5789  
26             require ExtUtils::MM_Any;
27             require ExtUtils::MM_Unix;
28             our @ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix );
29             our $VERSION = '7.64';
30             $VERSION =~ tr/_//d;
31              
32             $ENV{EMXSHELL} = 'sh'; # to run `commands`
33              
34             my ( $BORLAND, $GCC, $MSVC ) = _identify_compiler_environment( \%Config );
35              
36             my ( $config ) = @_;
37              
38 2     2   5 my $BORLAND = $config->{cc} =~ /\bbcc/i ? 1 : 0;
39             my $GCC = $config->{cc} =~ /\bgcc\b/i ? 1 : 0;
40 2 50       9 my $MSVC = $config->{cc} =~ /\b(?:cl|icl)/i ? 1 : 0; # MSVC can come as clarm.exe, icl=Intel C
41 2 50       5  
42 2 50       12 return ( $BORLAND, $GCC, $MSVC );
43             }
44 2         6  
45              
46             =head2 Overridden methods
47              
48             =over 4
49              
50             =item B<dlsyms>
51              
52             =cut
53              
54             my($self,%attribs) = @_;
55             return '' if $self->{SKIPHASH}{'dynamic'};
56             $self->xs_dlsyms_iterator(\%attribs);
57 0     0 1 0 }
58 0 0       0  
59 0         0 =item xs_dlsyms_ext
60              
61             On Win32, is C<.def>.
62              
63             =cut
64              
65             '.def';
66             }
67              
68             =item replace_manpage_separator
69 0     0 1 0  
70             Changes the path separator with .
71              
72             =cut
73              
74             my($self,$man) = @_;
75             $man =~ s,[/\\]+,.,g;
76             $man;
77             }
78              
79 0     0 1 0  
80 0         0 =item B<maybe_command>
81 0         0  
82             Since Windows has nothing as simple as an executable bit, we check the
83             file extension.
84              
85             The PATHEXT env variable will be used to get a list of extensions that
86             might indicate a command, otherwise .com, .exe, .bat and .cmd will be
87             used by default.
88              
89             =cut
90              
91             my($self,$file) = @_;
92             my @e = exists($ENV{'PATHEXT'})
93             ? split(/;/, $ENV{PATHEXT})
94             : qw(.com .exe .bat .cmd);
95             my $e = '';
96             for (@e) { $e .= "\Q$_\E|" }
97 0     0 1 0 chop $e;
98             # see if file ends in one of the known extensions
99             if ($file =~ /($e)$/i) {
100 0 0       0 return $file if -e $file;
101 0         0 }
102 0         0 else {
  0         0  
103 0         0 for (@e) {
104             return "$file$_" if -e "$file$_";
105 0 0       0 }
106 0 0       0 }
107             return;
108             }
109 0         0  
110 0 0       0  
111             =item B<init_DIRFILESEP>
112              
113 0         0 Using \ for Windows, except for "gmake" where it is /.
114              
115             =cut
116              
117             my($self) = shift;
118              
119             # The ^ makes sure its not interpreted as an escape in nmake
120             $self->{DIRFILESEP} = $self->is_make_type('nmake') ? '^\\' :
121             $self->is_make_type('dmake') ? '\\\\' :
122             $self->is_make_type('gmake') ? '/'
123             : '\\';
124 0     0 1 0 }
125              
126             =item init_tools
127 0 0       0  
    0          
    0          
128             Override some of the slower, portable commands with Windows specific ones.
129              
130             =cut
131              
132             my ($self) = @_;
133              
134             $self->{NOOP} ||= 'rem';
135             $self->{DEV_NULL} ||= '> NUL';
136              
137             $self->{FIXIN} ||= $self->{PERL_CORE} ?
138             "\$(PERLRUN) -I$self->{PERL_SRC}\\cpan\\ExtUtils-PL2Bat\\lib $self->{PERL_SRC}\\win32\\bin\\pl2bat.pl" :
139             'pl2bat.bat';
140 0     0 1 0  
141             $self->SUPER::init_tools;
142 0   0     0  
143 0   0     0 # Setting SHELL from $Config{sh} can break dmake. Its ok without it.
144             delete $self->{SHELL};
145              
146 0 0 0     0 return;
147             }
148              
149 0         0  
150             =item init_others
151              
152 0         0 Override the default link and compile tools.
153              
154 0         0 LDLOADLIBS's default is changed to $Config{libs}.
155              
156             Adjustments are made for Borland's quirks needing -L to come first.
157              
158             =cut
159              
160             my $self = shift;
161              
162             $self->{LD} ||= 'link';
163             $self->{AR} ||= 'lib';
164              
165             $self->SUPER::init_others;
166              
167             $self->{LDLOADLIBS} ||= $Config{libs};
168             # -Lfoo must come first for Borland, so we put it in LDDLFLAGS
169 0     0 1 0 if ($BORLAND) {
170             my $libs = $self->{LDLOADLIBS};
171 0   0     0 my $libpath = '';
172 0   0     0 while ($libs =~ s/(?:^|\s)(("?)-L.+?\2)(?:\s|$)/ /) {
173             $libpath .= ' ' if length $libpath;
174 0         0 $libpath .= $1;
175             }
176 0   0     0 $self->{LDLOADLIBS} = $libs;
177             $self->{LDDLFLAGS} ||= $Config{lddlflags};
178 0 0       0 $self->{LDDLFLAGS} .= " $libpath";
179 0         0 }
180 0         0  
181 0         0 return;
182 0 0       0 }
183 0         0  
184              
185 0         0 =item init_platform
186 0   0     0  
187 0         0 Add MM_Win32_VERSION.
188              
189             =item platform_constants
190 0         0  
191             =cut
192              
193             my($self) = shift;
194              
195             $self->{MM_Win32_VERSION} = $VERSION;
196              
197             return;
198             }
199              
200             my($self) = shift;
201             my $make_frag = '';
202              
203 0     0 1 0 foreach my $macro (qw(MM_Win32_VERSION))
204             {
205 0         0 next unless defined $self->{$macro};
206             $make_frag .= "$macro = $self->{$macro}\n";
207 0         0 }
208              
209             return $make_frag;
210             }
211 0     0 1 0  
212 0         0 =item specify_shell
213              
214 0         0 Set SHELL to $ENV{COMSPEC} only if make is type 'gmake'.
215              
216 0 0       0 =cut
217 0         0  
218             my $self = shift;
219             return '' unless $self->is_make_type('gmake');
220 0         0 "\nSHELL = $ENV{COMSPEC}\n";
221             }
222              
223             =item constants
224              
225             Add MAXLINELENGTH for dmake before all the constants are output.
226              
227             =cut
228              
229             my $self = shift;
230 0     0 1 0  
231 0 0       0 my $make_text = $self->SUPER::constants;
232 0         0 return $make_text unless $self->is_make_type('dmake');
233              
234             # dmake won't read any single "line" (even those with escaped newlines)
235             # larger than a certain size which can be as small as 8k. PM_TO_BLIB
236             # on large modules like DateTime::TimeZone can create lines over 32k.
237             # So we'll crank it up to a <ironic>WHOPPING</ironic> 64k.
238             #
239             # This has to come here before all the constants and not in
240             # platform_constants which is after constants.
241             my $size = $self->{MAXLINELENGTH} || 800000;
242 0     0 1 0 my $prefix = qq{
243             # Get dmake to read long commands like PM_TO_BLIB
244 0         0 MAXLINELENGTH = $size
245 0 0       0  
246             };
247              
248             return $prefix . $make_text;
249             }
250              
251              
252             =item special_targets
253              
254 0   0     0 Add .USESHELL target for dmake.
255 0         0  
256             =cut
257              
258             my($self) = @_;
259              
260             my $make_frag = $self->SUPER::special_targets;
261 0         0  
262             $make_frag .= <<'MAKE_FRAG' if $self->is_make_type('dmake');
263             .USESHELL :
264             MAKE_FRAG
265              
266             return $make_frag;
267             }
268              
269             =item static_lib_pure_cmd
270              
271             Defines how to run the archive utility
272 0     0 1 0  
273             =cut
274 0         0  
275             my ($self, $from) = @_;
276 0 0       0 $from =~ s/(\$\(\w+)(\))/$1:^"+"$2/g if $BORLAND;
277             sprintf qq{\t\$(AR) %s\n}, ($BORLAND ? '$@ ' . $from
278             : ($GCC ? '-ru $@ ' . $from
279             : '-out:$@ ' . $from));
280 0         0 }
281              
282             =item dynamic_lib
283              
284             Methods are overridden here: not dynamic_lib itself, but the utility
285             ones that do the OS-specific work.
286              
287             =cut
288              
289             my ($self, $attribs, $from, $to, $todir, $ldfrom, $exportlist) = @_;
290 0     0 1 0 my @m = sprintf '%s : %s $(MYEXTLIB) %s$(DFSEP).exists %s $(PERL_ARCHIVEDEP) $(INST_DYNAMIC_DEP)'."\n", $to, $from, $todir, $exportlist;
291 0 0       0 if ($GCC) {
292 0 0       0 # per https://rt.cpan.org/Ticket/Display.html?id=78395 no longer
    0          
293             # uses dlltool - relies on post 2002 MinGW
294             # 1 2
295             push @m, _sprintf562 <<'EOF', $exportlist, $ldfrom;
296             $(LD) %1$s -o $@ $(LDDLFLAGS) %2$s $(OTHERLDFLAGS) $(MYEXTLIB) "$(PERL_ARCHIVE)" $(LDLOADLIBS) -Wl,--enable-auto-image-base
297             EOF
298             } elsif ($BORLAND) {
299             my $ldargs = $self->is_make_type('dmake')
300             ? q{"$(PERL_ARCHIVE:s,/,\,)" $(LDLOADLIBS:s,/,\,) $(MYEXTLIB:s,/,\,),}
301             : q{"$(subst /,\,$(PERL_ARCHIVE))" $(subst /,\,$(LDLOADLIBS)) $(subst /,\,$(MYEXTLIB)),};
302             my $subbed;
303             if ($exportlist eq '$(EXPORT_LIST)') {
304             $subbed = $self->is_make_type('dmake')
305 0     0 1 0 ? q{$(EXPORT_LIST:s,/,\,)}
306 0         0 : q{$(subst /,\,$(EXPORT_LIST))};
307 0 0       0 } else {
    0          
308             # in XSMULTI, exportlist is per-XS, so have to sub in perl not make
309             ($subbed = $exportlist) =~ s#/#\\#g;
310             }
311 0         0 push @m, sprintf <<'EOF', $ldfrom, $ldargs . $subbed;
312             $(LD) $(LDDLFLAGS) $(OTHERLDFLAGS) %s,$@,,%s,$(RESFILES)
313             EOF
314             } else { # VC
315 0 0       0 push @m, sprintf <<'EOF', $ldfrom, $exportlist;
316             $(LD) -out:$@ $(LDDLFLAGS) %s $(OTHERLDFLAGS) $(MYEXTLIB) "$(PERL_ARCHIVE)" $(LDLOADLIBS) -def:%s
317             EOF
318 0         0 # Embed the manifest file if it exists
319 0 0       0 push(@m, q{ if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
320 0 0       0 if exist $@.manifest del $@.manifest});
321             }
322             push @m, "\n\t\$(CHMOD) \$(PERM_RWX) \$\@\n";
323              
324             join '', @m;
325 0         0 }
326              
327 0         0 my ($self, $attribs) = @_;
328             my $otherldflags = $attribs->{OTHERLDFLAGS} || ($BORLAND ? 'c0d32.obj': '');
329             my $inst_dynamic_dep = $attribs->{INST_DYNAMIC_DEP} || "";
330             sprintf <<'EOF', $otherldflags, $inst_dynamic_dep;
331 0         0 # This section creates the dynamically loadable objects from relevant
332             # objects and possibly $(MYEXTLIB).
333             OTHERLDFLAGS = %s
334             INST_DYNAMIC_DEP = %s
335 0         0 EOF
336             }
337              
338 0         0 =item extra_clean_files
339              
340 0         0 Clean out some extra dll.{base,exp} files which might be generated by
341             gcc. Otherwise, take out all *.pdb files.
342              
343             =cut
344 0     0 1 0  
345 0   0     0 my $self = shift;
346 0   0     0  
347 0         0 return $GCC ? (qw(dll.base dll.exp)) : ('*.pdb');
348             }
349              
350             =item init_linker
351              
352             =cut
353              
354             my $self = shift;
355              
356             $self->{PERL_ARCHIVE} = "\$(PERL_INC)\\$Config{libperl}";
357             $self->{PERL_ARCHIVEDEP} = "\$(PERL_INCDEP)\\$Config{libperl}";
358             $self->{PERL_ARCHIVE_AFTER} = '';
359             $self->{EXPORT_LIST} = '$(BASEEXT).def';
360             }
361              
362              
363 0     0 1 0 =item perl_script
364              
365 0 0       0 Checks for the perl program under several common perl extensions.
366              
367             =cut
368              
369             my($self,$file) = @_;
370             return $file if -r $file && -f _;
371             return "$file.pl" if -r "$file.pl" && -f _;
372             return "$file.plx" if -r "$file.plx" && -f _;
373 0     0 1 0 return "$file.bat" if -r "$file.bat" && -f _;
374             return;
375 0         0 }
376 0         0  
377 0         0 my ($self) = @_;
378 0         0 return 0 unless $self->can_load_xs;
379             require Win32;
380             require File::Spec;
381             my ($vol, $dir) = File::Spec->splitpath($INC{'ExtUtils/MakeMaker.pm'});
382             # can_dep_space via GetShortPathName, if short paths are supported
383             my $canary = Win32::GetShortPathName(File::Spec->catpath($vol, $dir, 'MakeMaker.pm'));
384             (undef, undef, my $file) = File::Spec->splitpath($canary);
385             return (length $file > 11) ? 0 : 1;
386             }
387              
388             =item quote_dep
389 0     0 1 0  
390 0 0 0     0 =cut
391 0 0 0     0  
392 0 0 0     0 my ($self, $arg) = @_;
393 0 0 0     0 if ($arg =~ / / and not $self->is_make_type('gmake')) {
394 0         0 require Win32;
395             $arg = Win32::GetShortPathName($arg);
396             die <<EOF if not defined $arg or $arg =~ / /;
397             Tried to use make dependency with space for non-GNU make:
398 0     0 1 0 '$arg'
399 0 0       0 Fallback to short pathname failed.
400 0         0 EOF
401 0         0 return $arg;
402 0         0 }
403             return $self->SUPER::quote_dep($arg);
404 0         0 }
405 0         0  
406 0 0       0  
407             =item xs_obj_opt
408              
409             Override to fixup -o flags for MSVC.
410              
411             =cut
412              
413             my ($self, $output_file) = @_;
414 0     0 1 0 ($MSVC ? "/Fo" : "-o ") . $output_file;
415 0 0 0     0 }
416 0         0  
417 0         0  
418 0 0 0     0 =item pasthru
419              
420             All we send is -nologo to nmake to prevent it from printing its damned
421             banner.
422              
423 0         0 =cut
424              
425 0         0 my($self) = shift;
426             my $old = $self->SUPER::pasthru;
427             return $old unless $self->is_make_type('nmake');
428             $old =~ s/(PASTHRU\s*=\s*)/$1 -nologo /;
429             $old;
430             }
431              
432              
433             =item arch_check (override)
434              
435             Normalize all arguments for consistency of comparison.
436 0     0 1 0  
437 0 0       0 =cut
438              
439             my $self = shift;
440              
441             # Win32 is an XS module, minperl won't have it.
442             # arch_check() is not critical, so just fake it.
443             return 1 unless $self->can_load_xs;
444             return $self->SUPER::arch_check( map { $self->_normalize_path_name($_) } @_);
445             }
446              
447             my $self = shift;
448             my $file = shift;
449 0     0 1 0  
450 0         0 require Win32;
451 0 0       0 my $short = Win32::GetShortPathName($file);
452 0         0 return defined $short ? lc $short : lc $file;
453 0         0 }
454              
455              
456             =item oneliner
457              
458             These are based on what command.com does on Win98. They may be wrong
459             for other Windows shells, I don't know.
460              
461             =cut
462              
463             my($self, $cmd, $switches) = @_;
464 0     0 1 0 $switches = [] unless defined $switches;
465              
466             # Strip leading and trailing newlines
467             $cmd =~ s{^\n+}{};
468 0 0       0 $cmd =~ s{\n+$}{};
469 0         0  
  0         0  
470             $cmd = $self->quote_literal($cmd);
471             $cmd = $self->escape_newlines($cmd);
472              
473 0     0   0 $switches = join ' ', @$switches;
474 0         0  
475             return qq{\$(ABSPERLRUN) $switches -e $cmd --};
476 0         0 }
477 0         0  
478 0 0       0  
479             my($self, $text, $opts) = @_;
480             $opts->{allow_variables} = 1 unless defined $opts->{allow_variables};
481              
482             # See: http://www.autohotkey.net/~deleyd/parameters/parameters.htm#CPP
483              
484             # Apply the Microsoft C/C++ parsing rules
485             $text =~ s{\\\\"}{\\\\\\\\\\"}g; # \\" -> \\\\\"
486             $text =~ s{(?<!\\)\\"}{\\\\\\"}g; # \" -> \\\"
487             $text =~ s{(?<!\\)"}{\\"}g; # " -> \"
488             $text = qq{"$text"} if $text =~ /[ \t#]/; # hash because gmake 4.2.1
489              
490 0     0 1 0 # Apply the Command Prompt parsing rules (cmd.exe)
491 0 0       0 my @text = split /("[^"]*")/, $text;
492             # We should also escape parentheses, but it breaks one-liners containing
493             # $(MACRO)s in makefiles.
494 0         0 s{([<>|&^@!])}{^$1}g foreach grep { !/^"[^"]*"$/ } @text;
495 0         0 $text = join('', @text);
496              
497 0         0 # dmake expands {{ to { and }} to }.
498 0         0 if( $self->is_make_type('dmake') ) {
499             $text =~ s/{/{{/g;
500 0         0 $text =~ s/}/}}/g;
501             }
502 0         0  
503             $text = $opts->{allow_variables}
504             ? $self->escape_dollarsigns($text) : $self->escape_all_dollarsigns($text);
505              
506             return $text;
507 0     0 1 0 }
508 0 0       0  
509              
510             my($self, $text) = @_;
511              
512             # Escape newlines
513 0         0 $text =~ s{\n}{\\\n}g;
514 0         0  
515 0         0 return $text;
516 0 0       0 }
517              
518              
519 0         0 =item cd
520              
521             dmake can handle Unix style cd'ing but nmake (at least 1.5) cannot. It
522 0         0 wants:
  0         0  
523 0         0  
524             cd dir1\dir2
525             command
526 0 0       0 another_command
527 0         0 cd ..\..
528 0         0  
529             =cut
530              
531             my($self, $dir, @cmds) = @_;
532 0 0       0  
533             return $self->SUPER::cd($dir, @cmds) unless $self->is_make_type('nmake');
534 0         0  
535             my $cmd = join "\n\t", map "$_", @cmds;
536              
537             my $updirs = $self->catdir(map { $self->updir } $self->splitdir($dir));
538              
539 0     0 1 0 # No leading tab and no trailing newline makes for easier embedding.
540             my $make_frag = sprintf <<'MAKE_FRAG', $dir, $cmd, $updirs;
541             cd %s
542 0         0 %s
543             cd %s
544 0         0 MAKE_FRAG
545              
546             chomp $make_frag;
547              
548             return $make_frag;
549             }
550              
551              
552             =item max_exec_len
553              
554             nmake 1.50 limits command length to 2048 characters.
555              
556             =cut
557              
558             my $self = shift;
559              
560             return $self->{_MAX_EXEC_LEN} ||= 2 * 1024;
561 2     2 1 28 }
562              
563 2 100       10  
564             =item os_flavor
565 1         7  
566             Windows is Win32.
567 1         8  
  2         16  
568             =cut
569              
570 1         7 return('Win32');
571             }
572              
573             =item dbgoutflag
574              
575             Returns a CC flag that tells the CC to emit a separate debugging symbol file
576 1         4 when compiling an object file.
577              
578 1         9 =cut
579              
580             $MSVC ? '-Fd$(*).pdb' : '';
581             }
582              
583             =item cflags
584              
585             Defines the PERLDLL symbol if we are configured for static building since all
586             code destined for the perl5xx.dll must be compiled with the PERLDLL symbol
587             defined.
588              
589 0     0 1   =cut
590              
591 0   0       my($self,$libperl)=@_;
592             return $self->{CFLAGS} if $self->{CFLAGS};
593             return '' unless $self->needs_linking();
594              
595             my $base = $self->SUPER::cflags($libperl);
596             foreach (split /\n/, $base) {
597             /^(\S*)\s*=\s*(\S*)$/ and $self->{$1} = $2;
598             };
599             $self->{CCFLAGS} .= " -DPERLDLL" if ($self->{LINKTYPE} eq 'static');
600              
601             return $self->{CFLAGS} = qq{
602 0     0 1   CCFLAGS = $self->{CCFLAGS}
603             OPTIMIZE = $self->{OPTIMIZE}
604             PERLTYPE = $self->{PERLTYPE}
605             };
606              
607             }
608              
609             =item make_type
610              
611             Returns a suitable string describing the type of makefile being written.
612              
613 0 0   0 1   =cut
614              
615             my ($self) = @_;
616             my $make = $self->make;
617             $make = +( File::Spec->splitpath( $make ) )[-1];
618             $make =~ s!\.exe$!!i;
619             if ( $make =~ m![^A-Z0-9]!i ) {
620             ($make) = grep { m!make!i } split m![^A-Z0-9]!i, $make;
621             }
622             return "$make-style";
623             }
624              
625 0     0 1   1;
626 0 0          
627 0 0         =back