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