File Coverage

lib/ExtUtils/MM_Win32.pm
Criterion Covered Total %
statement 31 233 13.3
branch 5 126 3.9
condition 0 44 0.0
subroutine 8 43 18.6
pod 33 34 97.0
total 77 480 16.0


line stmt bran cond sub pod time code
1             package ExtUtils::MM_Win32;
2              
3 2     2   50919 use strict;
  2         4  
  2         87  
4 2     2   8 use warnings;
  2         3  
  2         96  
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 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   429 use ExtUtils::MakeMaker::Config;
  2         6  
  2         23  
23 2     2   15 use File::Basename;
  2         11  
  2         188  
24 2     2   16 use File::Spec;
  2         3  
  2         48  
25 2     2   867 use ExtUtils::MakeMaker qw(neatvalue _sprintf562);
  2         8  
  2         10944  
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.78';
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       13 my $BORLAND = $config->{cc} =~ /\bbcc/i ? 1 : 0;
41 2 50       6 my $GCC = $config->{cc} =~ /\bgcc\b/i ? 1 : 0;
42 2 50       13 my $MSVC = $config->{cc} =~ /\b(?:cl|icl)/i ? 1 : 0; # MSVC can come as clarm.exe, icl=Intel C
43              
44 2         9 return ( $BORLAND, $GCC, $MSVC );
45             }
46              
47              
48             =head2 Overridden methods
49              
50             =over 4
51              
52             =item B
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
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
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 it's 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             my @LIBS_VARNAMES = qw(EXTRALIBS BSLOADLIBS LDLOADLIBS LD_RUN_PATH);
169             sub init_others {
170 0     0 1 0 my $self = shift;
171              
172 0   0     0 $self->{LD} ||= 'link';
173 0   0     0 $self->{AR} ||= 'lib';
174              
175 0         0 $self->SUPER::init_others;
176             # If Config.pm defines a set of default libs,
177             # add them to EXTRALIBS, BSLOADLIBS and LDLOADLIBS, unless the user
178             # specified :nodefault or gave no LIBS
179 0 0 0     0 if (grep /\S/ && !/:nodefault/i, @{$self->{LIBS}}) {
  0         0  
180 0         0 my @libs = $self->extliblist($Config{perllibs});
181 0         0 for my $ind (0..$#LIBS_VARNAMES) {
182 0 0       0 next unless my $to_add = $libs[$ind];
183 0         0 my $varname = $LIBS_VARNAMES[$ind];
184 0 0       0 $self->{$varname} .= ' ' if $self->{$varname};
185 0         0 $self->{$varname} .= $to_add;
186             }
187             }
188              
189 0   0     0 $self->{LDLOADLIBS} ||= $Config{libs};
190             # -Lfoo must come first for Borland, so we put it in LDDLFLAGS
191 0 0       0 if ($BORLAND) {
192 0         0 my $libs = $self->{LDLOADLIBS};
193 0         0 my $libpath = '';
194 0         0 while ($libs =~ s/(?:^|\s)(("?)-L.+?\2)(?:\s|$)/ /) {
195 0 0       0 $libpath .= ' ' if length $libpath;
196 0         0 $libpath .= $1;
197             }
198 0         0 $self->{LDLOADLIBS} = $libs;
199 0   0     0 $self->{LDDLFLAGS} ||= $Config{lddlflags};
200 0         0 $self->{LDDLFLAGS} .= " $libpath";
201             }
202              
203 0         0 return;
204             }
205              
206              
207             =item init_platform
208              
209             Add MM_Win32_VERSION.
210              
211             =item platform_constants
212              
213             =cut
214              
215             sub init_platform {
216 0     0 1 0 my($self) = shift;
217              
218 0         0 $self->{MM_Win32_VERSION} = $VERSION;
219              
220 0         0 return;
221             }
222              
223             sub platform_constants {
224 0     0 1 0 my($self) = shift;
225 0         0 my $make_frag = '';
226              
227 0         0 foreach my $macro (qw(MM_Win32_VERSION))
228             {
229 0 0       0 next unless defined $self->{$macro};
230 0         0 $make_frag .= "$macro = $self->{$macro}\n";
231             }
232              
233 0         0 return $make_frag;
234             }
235              
236             =item specify_shell
237              
238             Set SHELL to $ENV{COMSPEC} only if make is type 'gmake'.
239              
240             =cut
241              
242             sub specify_shell {
243 0     0 1 0 my $self = shift;
244 0 0       0 return '' unless $self->is_make_type('gmake');
245 0         0 "\nSHELL = $ENV{COMSPEC}\n";
246             }
247              
248             =item constants
249              
250             Add MAXLINELENGTH for dmake before all the constants are output.
251              
252             =cut
253              
254             sub constants {
255 0     0 1 0 my $self = shift;
256              
257 0         0 my $make_text = $self->SUPER::constants;
258 0 0       0 return $make_text unless $self->is_make_type('dmake');
259              
260             # dmake won't read any single "line" (even those with escaped newlines)
261             # larger than a certain size which can be as small as 8k. PM_TO_BLIB
262             # on large modules like DateTime::TimeZone can create lines over 32k.
263             # So we'll crank it up to a WHOPPING 64k.
264             #
265             # This has to come here before all the constants and not in
266             # platform_constants which is after constants.
267 0   0     0 my $size = $self->{MAXLINELENGTH} || 800000;
268 0         0 my $prefix = qq{
269             # Get dmake to read long commands like PM_TO_BLIB
270             MAXLINELENGTH = $size
271              
272             };
273              
274 0         0 return $prefix . $make_text;
275             }
276              
277             =item dep_constants
278              
279             Makes dependencies that work for nmake.
280              
281             =cut
282              
283             sub dep_constants {
284 0     0 1 0 my ($self) = @_;
285 0 0       0 return $self->SUPER::dep_constants if !$self->is_make_type('nmake');
286 0         0 my @m = ();
287 0         0 for my $macro (qw(PERL_ARCHLIBDEP PERL_INCDEP)) {
288 0 0       0 next unless defined $self->{$macro};
289             # pathnames can have sharp signs in them; escape them so
290             # make doesn't think it is a comment-start character.
291 0         0 $self->{$macro} =~ s/#/\\#/g;
292             $self->{$macro} = $self->quote_dep($self->{$macro})
293 0 0       0 if $ExtUtils::MakeMaker::macro_dep{$macro};
294 0         0 push @m, "$macro = $self->{$macro}\n";
295             }
296 0         0 push @m, qq{
297             \n# Dependencies info
298             PERL_ARCHIVEDEP = "$self->{PERL_ARCHIVE}"
299             };
300             push @m, qq{
301             # Where is the Config information that we are using/depend on
302             CONFIGDEP = "\$(PERL_ARCHLIB)\$(DFSEP)Config.pm" "\$(PERL_INC)\$(DFSEP)config.h"
303 0 0       0 } if -e $self->catfile($self->{PERL_INC}, 'config.h');
304 0         0 join '', @m;
305             }
306              
307             sub _perl_header_files_fragment {
308 0     0   0 my ($self, $separator) = @_;
309 0 0       0 return $self->SUPER::_perl_header_files_fragment($separator)
310             if !$self->is_make_type('nmake');
311 0         0 return join("\\\n",
312             "PERL_HDRS = ",
313             map sprintf(" \"\$(PERL_INC)\\%s\" ", $_),
314             $self->_perl_header_files
315             ) . "\n\n"
316             . "\$(OBJECT) : \$(PERL_HDRS)\n";
317             }
318              
319             sub tool_xsubpp_emit {
320 0     0 0 0 my ($self, $xsdir, $tmdeps, $tmargs) = @_;
321 0 0       0 return $self->SUPER::tool_xsubpp_emit($xsdir, $tmdeps, $tmargs)
322             if !$self->is_make_type('nmake');
323 0         0 return qq{
324             XSUBPPDIR = $xsdir
325             XSUBPP = "\$(XSUBPPDIR)\$(DFSEP)xsubpp"
326             XSUBPPRUN = \$(PERLRUN) \$(XSUBPP)
327             XSPROTOARG = $self->{XSPROTOARG}
328             XSUBPPDEPS = @$tmdeps \$(XSUBPP)
329             XSUBPPARGS = @$tmargs
330             XSUBPP_EXTRA_ARGS =
331             };
332             }
333              
334             =item special_targets
335              
336             Add .USESHELL target for dmake.
337              
338             =cut
339              
340             sub special_targets {
341 0     0 1 0 my($self) = @_;
342              
343 0         0 my $make_frag = $self->SUPER::special_targets;
344              
345 0 0       0 $make_frag .= <<'MAKE_FRAG' if $self->is_make_type('dmake');
346             .USESHELL :
347             MAKE_FRAG
348              
349 0         0 return $make_frag;
350             }
351              
352             =item static_lib_pure_cmd
353              
354             Defines how to run the archive utility
355              
356             =cut
357              
358             sub static_lib_pure_cmd {
359 0     0 1 0 my ($self, $from) = @_;
360 0 0       0 $from =~ s/(\$\(\w+)(\))/$1:^"+"$2/g if $BORLAND;
361 0 0       0 sprintf qq{\t\$(AR) %s\n}, ($BORLAND ? '$@ ' . $from
    0          
362             : ($GCC ? '-ru $@ ' . $from
363             : '-out:$@ ' . $from));
364             }
365              
366             =item dynamic_lib
367              
368             Methods are overridden here: not dynamic_lib itself, but the utility
369             ones that do the OS-specific work.
370              
371             =cut
372              
373             sub xs_make_dynamic_lib {
374 0     0 1 0 my ($self, $attribs, $from, $to, $todir, $ldfrom, $exportlist) = @_;
375 0         0 my @m = sprintf '%s : %s $(MYEXTLIB) %s$(DFSEP).exists %s $(PERL_ARCHIVEDEP) $(INST_DYNAMIC_DEP)'."\n", $to, $from, $todir, $exportlist;
376 0 0       0 if ($GCC) {
    0          
377             # per https://rt.cpan.org/Ticket/Display.html?id=78395 no longer
378             # uses dlltool - relies on post 2002 MinGW
379             # 1 2
380 0         0 push @m, _sprintf562 <<'EOF', $exportlist, $ldfrom;
381             $(LD) %1$s -o $@ $(LDDLFLAGS) %2$s $(OTHERLDFLAGS) $(MYEXTLIB) "$(PERL_ARCHIVE)" $(LDLOADLIBS) -Wl,--enable-auto-image-base
382             EOF
383             } elsif ($BORLAND) {
384 0 0       0 my $ldargs = $self->is_make_type('dmake')
385             ? q{"$(PERL_ARCHIVE:s,/,\,)" $(LDLOADLIBS:s,/,\,) $(MYEXTLIB:s,/,\,),}
386             : q{"$(subst /,\,$(PERL_ARCHIVE))" $(subst /,\,$(LDLOADLIBS)) $(subst /,\,$(MYEXTLIB)),};
387 0         0 my $subbed;
388 0 0       0 if ($exportlist eq '$(EXPORT_LIST)') {
389 0 0       0 $subbed = $self->is_make_type('dmake')
390             ? q{$(EXPORT_LIST:s,/,\,)}
391             : q{$(subst /,\,$(EXPORT_LIST))};
392             } else {
393             # in XSMULTI, exportlist is per-XS, so have to sub in perl not make
394 0         0 ($subbed = $exportlist) =~ s#/#\\#g;
395             }
396 0         0 push @m, sprintf <<'EOF', $ldfrom, $ldargs . $subbed;
397             $(LD) $(LDDLFLAGS) $(OTHERLDFLAGS) %s,$@,,%s,$(RESFILES)
398             EOF
399             } else { # VC
400 0         0 push @m, sprintf <<'EOF', $ldfrom, $exportlist;
401             $(LD) -out:$@ $(LDDLFLAGS) %s $(OTHERLDFLAGS) $(MYEXTLIB) "$(PERL_ARCHIVE)" $(LDLOADLIBS) -def:%s
402             EOF
403             # Embed the manifest file if it exists
404 0         0 push(@m, q{ if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
405             if exist $@.manifest del $@.manifest});
406             }
407 0         0 push @m, "\n\t\$(CHMOD) \$(PERM_RWX) \$\@\n";
408              
409 0         0 join '', @m;
410             }
411              
412             sub xs_dynamic_lib_macros {
413 0     0 1 0 my ($self, $attribs) = @_;
414 0   0     0 my $otherldflags = $attribs->{OTHERLDFLAGS} || ($BORLAND ? 'c0d32.obj': '');
415 0   0     0 my $inst_dynamic_dep = $attribs->{INST_DYNAMIC_DEP} || "";
416 0         0 sprintf <<'EOF', $otherldflags, $inst_dynamic_dep;
417             # This section creates the dynamically loadable objects from relevant
418             # objects and possibly $(MYEXTLIB).
419             OTHERLDFLAGS = %s
420             INST_DYNAMIC_DEP = %s
421             EOF
422             }
423              
424             =item extra_clean_files
425              
426             Clean out some extra dll.{base,exp} files which might be generated by
427             gcc. Otherwise, take out all *.pdb files.
428              
429             =cut
430              
431             sub extra_clean_files {
432 0     0 1 0 my $self = shift;
433              
434 0 0       0 return $GCC ? (qw(dll.base dll.exp)) : ('*.pdb');
435             }
436              
437             =item init_linker
438              
439             =cut
440              
441             sub init_linker {
442 0     0 1 0 my $self = shift;
443              
444 0         0 $self->{PERL_ARCHIVE} = "\$(PERL_INC)\\$Config{libperl}";
445 0         0 $self->{PERL_ARCHIVEDEP} = "\$(PERL_INCDEP)\\$Config{libperl}";
446 0         0 $self->{PERL_ARCHIVE_AFTER} = '';
447 0         0 $self->{EXPORT_LIST} = '$(BASEEXT).def';
448             }
449              
450              
451             =item perl_script
452              
453             Checks for the perl program under several common perl extensions.
454              
455             =cut
456              
457             sub perl_script {
458 0     0 1 0 my($self,$file) = @_;
459 0 0 0     0 return $file if -r $file && -f _;
460 0 0 0     0 return "$file.pl" if -r "$file.pl" && -f _;
461 0 0 0     0 return "$file.plx" if -r "$file.plx" && -f _;
462 0 0 0     0 return "$file.bat" if -r "$file.bat" && -f _;
463 0         0 return;
464             }
465              
466             sub can_dep_space {
467 0     0 1 0 my ($self) = @_;
468 0 0       0 return 1 if !$self->is_make_type('dmake'); # GNU & n-make are fine
469 0 0       0 return 0 unless $self->can_load_xs;
470 0         0 require Win32;
471 0         0 require File::Spec;
472 0         0 my ($vol, $dir) = File::Spec->splitpath($INC{'ExtUtils/MakeMaker.pm'});
473             # can_dep_space via GetShortPathName, if short paths are supported
474 0         0 my $canary = Win32::GetShortPathName(File::Spec->catpath($vol, $dir, 'MakeMaker.pm'));
475 0         0 (undef, undef, my $file) = File::Spec->splitpath($canary);
476 0 0       0 return (length $file > 11) ? 0 : 1;
477             }
478              
479             =item quote_dep
480              
481             =cut
482              
483             sub quote_dep {
484 0     0 1 0 my ($self, $arg) = @_;
485 0 0       0 return $arg if $arg !~ / /;
486 0 0       0 return $self->SUPER::quote_dep($arg) if $self->is_make_type('gmake');
487 0 0       0 return qq{"$arg"} if $self->is_make_type('nmake');
488 0         0 require Win32; # dmake, get 8.3 name
489 0         0 $arg = Win32::GetShortPathName($arg);
490 0 0 0     0 die <
491             Tried to use make dependency with space for dmake:
492             '$arg'
493             Fallback to short pathname failed.
494             EOF
495 0         0 $arg;
496             }
497              
498              
499             =item xs_obj_opt
500              
501             Override to fixup -o flags for MSVC.
502              
503             =cut
504              
505             sub xs_obj_opt {
506 0     0 1 0 my ($self, $output_file) = @_;
507 0 0       0 ($MSVC ? "/Fo" : "-o ") . $output_file;
508             }
509              
510              
511             =item pasthru
512              
513             All we send is -nologo to nmake to prevent it from printing its damned
514             banner.
515              
516             =cut
517              
518             sub pasthru {
519 0     0 1 0 my($self) = shift;
520 0         0 my $old = $self->SUPER::pasthru;
521 0 0       0 return $old unless $self->is_make_type('nmake');
522 0         0 $old =~ s/(PASTHRU\s*=\s*)/$1 -nologo /;
523 0         0 $old;
524             }
525              
526              
527             =item arch_check (override)
528              
529             Normalize all arguments for consistency of comparison.
530              
531             =cut
532              
533             sub arch_check {
534 0     0 1 0 my $self = shift;
535              
536             # Win32 is an XS module, minperl won't have it.
537             # arch_check() is not critical, so just fake it.
538 0 0       0 return 1 unless $self->can_load_xs;
539 0         0 return $self->SUPER::arch_check( map { $self->_normalize_path_name($_) } @_);
  0         0  
540             }
541              
542             sub _normalize_path_name {
543 0     0   0 my $self = shift;
544 0         0 my $file = shift;
545              
546 0         0 require Win32;
547 0         0 my $short = Win32::GetShortPathName($file);
548 0 0       0 return defined $short ? lc $short : lc $file;
549             }
550              
551              
552             =item oneliner
553              
554             These are based on what command.com does on Win98. They may be wrong
555             for other Windows shells, I don't know.
556              
557             =cut
558              
559             sub oneliner {
560 0     0 1 0 my($self, $cmd, $switches) = @_;
561 0 0       0 $switches = [] unless defined $switches;
562              
563             # Strip leading and trailing newlines
564 0         0 $cmd =~ s{^\n+}{};
565 0         0 $cmd =~ s{\n+$}{};
566              
567 0         0 $cmd = $self->quote_literal($cmd);
568 0         0 $cmd = $self->escape_newlines($cmd);
569              
570 0         0 $switches = join ' ', @$switches;
571              
572 0         0 return qq{\$(ABSPERLRUN) $switches -e $cmd --};
573             }
574              
575              
576             sub quote_literal {
577 0     0 1 0 my($self, $text, $opts) = @_;
578 0 0       0 $opts->{allow_variables} = 1 unless defined $opts->{allow_variables};
579              
580             # See: http://www.autohotkey.net/~deleyd/parameters/parameters.htm#CPP
581              
582             # Apply the Microsoft C/C++ parsing rules
583 0         0 $text =~ s{\\\\"}{\\\\\\\\\\"}g; # \\" -> \\\\\"
584 0         0 $text =~ s{(? \\\"
585 0         0 $text =~ s{(? \"
586 0 0       0 $text = qq{"$text"} if $text =~ /[ \t#]/; # hash because gmake 4.2.1
587              
588             # Apply the Command Prompt parsing rules (cmd.exe)
589 0         0 my @text = split /("[^"]*")/, $text;
590             # We should also escape parentheses, but it breaks one-liners containing
591             # $(MACRO)s in makefiles.
592 0         0 s{([<>|&^@!])}{^$1}g foreach grep { !/^"[^"]*"$/ } @text;
  0         0  
593 0         0 $text = join('', @text);
594              
595             # dmake expands {{ to { and }} to }.
596 0 0       0 if( $self->is_make_type('dmake') ) {
597 0         0 $text =~ s/{/{{/g;
598 0         0 $text =~ s/}/}}/g;
599             }
600              
601             $text = $opts->{allow_variables}
602 0 0       0 ? $self->escape_dollarsigns($text) : $self->escape_all_dollarsigns($text);
603              
604 0         0 return $text;
605             }
606              
607              
608             sub escape_newlines {
609 0     0 1 0 my($self, $text) = @_;
610              
611             # Escape newlines
612 0         0 $text =~ s{\n}{\\\n}g;
613              
614 0         0 return $text;
615             }
616              
617              
618             =item cd
619              
620             dmake can handle Unix style cd'ing but nmake (at least 1.5) cannot. It
621             wants:
622              
623             cd dir1\dir2
624             command
625             another_command
626             cd ..\..
627              
628             =cut
629              
630             sub cd {
631 2     2 1 45 my($self, $dir, @cmds) = @_;
632              
633 2 100       13 return $self->SUPER::cd($dir, @cmds) unless $self->is_make_type('nmake');
634              
635 1         9 my $cmd = join "\n\t", map "$_", @cmds;
636              
637 1         13 my $updirs = $self->catdir(map { $self->updir } $self->splitdir($dir));
  2         24  
638              
639             # No leading tab and no trailing newline makes for easier embedding.
640 1         5 my $make_frag = sprintf <<'MAKE_FRAG', $dir, $cmd, $updirs;
641             cd %s
642             %s
643             cd %s
644             MAKE_FRAG
645              
646 1         4 chomp $make_frag;
647              
648 1         11 return $make_frag;
649             }
650              
651              
652             =item max_exec_len
653              
654             nmake 1.50 limits command length to 2048 characters.
655              
656             =cut
657              
658             sub max_exec_len {
659 0     0 1   my $self = shift;
660              
661 0   0       return $self->{_MAX_EXEC_LEN} ||= 2 * 1024;
662             }
663              
664              
665             =item os_flavor
666              
667             Windows is Win32.
668              
669             =cut
670              
671             sub os_flavor {
672 0     0 1   return('Win32');
673             }
674              
675             =item dbgoutflag
676              
677             Returns a CC flag that tells the CC to emit a separate debugging symbol file
678             when compiling an object file.
679              
680             =cut
681              
682             sub dbgoutflag {
683 0 0   0 1   $MSVC ? '-Fd$(*).pdb' : '';
684             }
685              
686             =item cflags
687              
688             Defines the PERLDLL symbol if we are configured for static building since all
689             code destined for the perl5xx.dll must be compiled with the PERLDLL symbol
690             defined.
691              
692             =cut
693              
694             sub cflags {
695 0     0 1   my($self,$libperl)=@_;
696 0 0         return $self->{CFLAGS} if $self->{CFLAGS};
697 0 0         return '' unless $self->needs_linking();
698              
699 0           my $base = $self->SUPER::cflags($libperl);
700 0           foreach (split /\n/, $base) {
701 0 0         /^(\S*)\s*=\s*(\S*)$/ and $self->{$1} = $2;
702             };
703 0 0         $self->{CCFLAGS} .= " -DPERLDLL" if ($self->{LINKTYPE} eq 'static');
704              
705 0           return $self->{CFLAGS} = qq{
706             CCFLAGS = $self->{CCFLAGS}
707             OPTIMIZE = $self->{OPTIMIZE}
708             PERLTYPE = $self->{PERLTYPE}
709             };
710              
711             }
712              
713             =item make_type
714              
715             Returns a suitable string describing the type of makefile being written.
716              
717             =cut
718              
719             sub make_type {
720 0     0 1   my ($self) = @_;
721 0           my $make = $self->make;
722 0           $make = +( File::Spec->splitpath( $make ) )[-1];
723 0           $make =~ s!\.exe$!!i;
724 0 0         if ( $make =~ m![^A-Z0-9]!i ) {
725 0           ($make) = grep { m!make!i } split m![^A-Z0-9]!i, $make;
  0            
726             }
727 0           return "$make-style";
728             }
729              
730             1;
731             __END__