1 package ExtUtils::MM_Win32;
6 ExtUtils::MM_Win32 - methods to override UN*X behaviour in ExtUtils::MakeMaker
10 use ExtUtils::MM_Win32; # Done internally by ExtUtils::MakeMaker if needed
14 See ExtUtils::MM_Unix for a documentation of the methods provided
15 there. This package overrides the implementation of these methods, not
25 use ExtUtils::MakeMaker qw( neatvalue );
27 use vars qw(@ISA $VERSION $BORLAND $GCC $DMAKE $NMAKE $PERLMAKE);
29 require ExtUtils::MM_Any;
30 require ExtUtils::MM_Unix;
31 @ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix );
34 $ENV{EMXSHELL} = 'sh'; # to run `commands`
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 $PERLMAKE = 1 if $Config{'make'} =~ /^pmake/i;
43 my($self,%attribs) = @_;
45 my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {};
46 my($vars) = $attribs{DL_VARS} || $self->{DL_VARS} || [];
47 my($funclist) = $attribs{FUNCLIST} || $self->{FUNCLIST} || [];
48 my($imports) = $attribs{IMPORTS} || $self->{IMPORTS} || {};
50 (my $boot = $self->{NAME}) =~ s/:/_/g;
52 if (not $self->{SKIPHASH}{'dynamic'}) {
54 $self->{BASEEXT}.def: Makefile.PL
56 q! $(PERLRUN) -MExtUtils::Mksymlists \\
57 -e "Mksymlists('NAME'=>\"!, $self->{NAME},
58 q!\", 'DLBASE' => '!,$self->{DLBASE},
59 # The above two lines quoted differently to work around
60 # a bug in the 4DOS/4NT command line interpreter. The visible
61 # result of the bug was files named q('extension_name',) *with the
62 # single quotes and the comma* in the extension build directories.
63 q!', 'DL_FUNCS' => !,neatvalue($funcs),
64 q!, 'FUNCLIST' => !,neatvalue($funclist),
65 q!, 'IMPORTS' => !,neatvalue($imports),
66 q!, 'DL_VARS' => !, neatvalue($vars), q!);"
72 sub replace_manpage_separator {
80 my @e = exists($ENV{'PATHEXT'})
81 ? split(/;/, $ENV{PATHEXT})
82 : qw(.com .exe .bat .cmd);
84 for (@e) { $e .= "\Q$_\E|" }
86 # see if file ends in one of the known extensions
87 if ($file =~ /($e)$/i) {
88 return $file if -e $file;
92 return "$file$_" if -e "$file$_";
100 my($self, $ver, $names, $dirs, $trace) = @_;
105 print "Looking for perl $ver by these names:
111 foreach $dir (@$dirs){
112 next unless defined $dir; # $self->{PERL_SRC} may be undefined
113 foreach $name (@$names){
115 if (File::Spec->file_name_is_absolute($name)) { # /foo/bar
117 } elsif (File::Spec->canonpath($name) eq
118 File::Spec->canonpath(basename($name))) # foo
120 $abs = File::Spec->catfile($dir, $name);
122 $abs = File::Spec->canonpath(
123 File::Spec->catfile(File::Spec->curdir, $name)
126 print "Checking $abs\n" if ($trace >= 2);
127 next unless $self->maybe_command($abs);
128 print "Executing $abs\n" if ($trace >= 2);
129 (my($safe_abs) = $abs) =~ s{(\s)}{\\$1}g;
130 $val = `$safe_abs -e "require $ver;" 2>&1`;
132 print "Using PERL=$abs\n" if $trace;
134 } elsif ($trace >= 2) {
135 print "Result: `$val'\n";
139 print STDOUT "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n";
140 0; # false and not empty
146 $self->SUPER::init_others;
147 $self->{'TOUCH'} = '$(PERLRUN) -MExtUtils::Command -e touch';
148 $self->{'CHMOD'} = '$(PERLRUN) -MExtUtils::Command -e chmod';
149 $self->{'CP'} = '$(PERLRUN) -MExtUtils::Command -e cp';
150 $self->{'RM_F'} = '$(PERLRUN) -MExtUtils::Command -e rm_f';
151 $self->{'RM_RF'} = '$(PERLRUN) -MExtUtils::Command -e rm_rf';
152 $self->{'MV'} = '$(PERLRUN) -MExtUtils::Command -e mv';
153 $self->{'NOOP'} = 'rem';
154 $self->{'TEST_F'} = '$(PERLRUN) -MExtUtils::Command -e test_f';
155 $self->{'LD'} = $Config{'ld'} || 'link';
156 $self->{'AR'} = $Config{'ar'} || 'lib';
157 $self->{'LDLOADLIBS'} ||= $Config{'libs'};
158 # -Lfoo must come first for Borland, so we put it in LDDLFLAGS
160 my $libs = $self->{'LDLOADLIBS'};
162 while ($libs =~ s/(?:^|\s)(("?)-L.+?\2)(?:\s|$)/ /) {
163 $libpath .= ' ' if length $libpath;
166 $self->{'LDLOADLIBS'} = $libs;
167 $self->{'LDDLFLAGS'} ||= $Config{'lddlflags'};
168 $self->{'LDDLFLAGS'} .= " $libpath";
170 $self->{'DEV_NULL'} = '> NUL';
176 Initializes lots of constants and .SUFFIXES and .PHONY
185 AR_STATIC_ARGS NAME DISTNAME NAME_SYM VERSION
186 VERSION_SYM XS_VERSION
187 INST_BIN INST_LIB INST_ARCHLIB INST_SCRIPT
189 PREFIX SITEPREFIX VENDORPREFIX
190 INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDORLIB
191 INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDORARCH
192 INSTALLBIN INSTALLSITEBIN INSTALLVENDORBIN INSTALLSCRIPT
193 PERL_LIB PERL_ARCHLIB
194 SITELIBEXP SITEARCHEXP
196 FIRST_MAKEFILE MAKE_APERL_FILE PERLMAINCC PERL_SRC
197 PERL_INC PERL FULLPERL PERLRUN FULLPERLRUN PERLRUNINST
198 FULLPERLRUNINST ABSPERL ABSPERLRUN ABSPERLRUNINST
202 next unless defined $self->{$tmp};
203 push @m, "$tmp = $self->{$tmp}\n";
207 VERSION_MACRO = VERSION
208 DEFINE_VERSION = -D\$(VERSION_MACRO)=\\\"\$(VERSION)\\\"
209 XS_VERSION_MACRO = XS_VERSION
210 XS_DEFINE_VERSION = -D\$(XS_VERSION_MACRO)=\\\"\$(XS_VERSION)\\\"
214 MAKEMAKER = $INC{'ExtUtils/MakeMaker.pm'}
215 MM_VERSION = $ExtUtils::MakeMaker::VERSION
219 # FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle).
220 # BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle)
221 # PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
222 # DLBASE = Basename part of dynamic library. May be just equal BASEEXT.
226 FULLEXT BASEEXT PARENT_NAME DLBASE VERSION_FROM INC DEFINE OBJECT
229 next unless defined $self->{$tmp};
230 push @m, "$tmp = $self->{$tmp}\n";
234 # Handy lists of source code files:
235 XS_FILES= ".join(" \\\n\t", sort keys %{$self->{XS}})."
236 C_FILES = ".join(" \\\n\t", @{$self->{C}})."
237 O_FILES = ".join(" \\\n\t", @{$self->{O_FILES}})."
238 H_FILES = ".join(" \\\n\t", @{$self->{H}})."
239 MAN1PODS = ".join(" \\\n\t", sort keys %{$self->{MAN1PODS}})."
240 MAN3PODS = ".join(" \\\n\t", sort keys %{$self->{MAN3PODS}})."
245 INSTALLMAN1DIR INSTALLSITEMAN1DIR INSTALLVENDORMAN1DIR
247 INSTALLMAN3DIR INSTALLSITEMAN3DIR INSTALLVENDORMAN3DIR
249 next unless defined $self->{$tmp};
250 push @m, "$tmp = $self->{$tmp}\n";
258 .NO_CONFIG_REC: Makefile
259 } if $ENV{CLEARCASE_ROOT};
261 # why not q{} ? -- emacs
263 # work around a famous dec-osf make(1) feature(?):
266 .SUFFIXES: .xs .c .C .cpp .cxx .cc \$(OBJ_EXT)
268 # Nick wanted to get rid of .PRECIOUS. I don't remember why. I seem to
269 # recall, that some make implementations will delete the Makefile when we
270 # rebuild it. Because we call false(1) when we rebuild it. So make(1) is
271 # not completely wrong when it does so. Our milage may vary.
272 # .PRECIOUS: Makefile # seems to be not necessary anymore
274 .PHONY: all config static dynamic test linkext manifest
276 # Where is the Config information that we are using/depend on
277 CONFIGDEP = \$(PERL_ARCHLIB)\\Config.pm \$(PERL_INC)\\config.h
280 my @parentdir = split(/::/, $self->{PARENT_NAME});
282 # Where to put things:
283 INST_LIBDIR = }. File::Spec->catdir('$(INST_LIB)',@parentdir) .q{
284 INST_ARCHLIBDIR = }. File::Spec->catdir('$(INST_ARCHLIB)',@parentdir) .q{
286 INST_AUTODIR = }. File::Spec->catdir('$(INST_LIB)','auto','$(FULLEXT)') .q{
287 INST_ARCHAUTODIR = }. File::Spec->catdir('$(INST_ARCHLIB)','auto','$(FULLEXT)') .q{
290 if ($self->has_link_code()) {
292 INST_STATIC = $(INST_ARCHAUTODIR)\$(BASEEXT)$(LIB_EXT)
293 INST_DYNAMIC = $(INST_ARCHAUTODIR)\$(DLBASE).$(DLEXT)
294 INST_BOOT = $(INST_ARCHAUTODIR)\$(BASEEXT).bs
304 $tmp = $self->export_list;
308 $tmp = $self->perl_archive;
314 TO_INST_PM = }.join(" \\\n\t", sort keys %{$self->{PM}}).q{
316 PM_TO_BLIB = }.join(" \\\n\t", %{$self->{PM}}).q{
325 Defines how to produce the *.a (or equivalent) files.
331 # Come to think of it, if there are subdirs with linkcode, we still have no INST_STATIC
332 # return '' unless $self->needs_linking(); #might be because of a subdir
334 return '' unless $self->has_link_code;
338 $(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)\.exists
341 # If this extension has its own library (eg SDBM_File)
342 # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
343 push(@m, "\t$self->{CP} \$(MYEXTLIB) \$\@\n") if $self->{MYEXTLIB};
346 q{ $(AR) }.($BORLAND ? '$@ $(OBJECT:^"+")'
347 : ($GCC ? '-ru $@ $(OBJECT)'
348 : '-out:$@ $(OBJECT)')).q{
349 }.$self->{NOECHO}.q{echo "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)\extralibs.ld
353 # Old mechanism - still available:
355 push @m, "\t$self->{NOECHO}".q{echo "$(EXTRALIBS)" >> $(PERL_SRC)\ext.libs}."\n\n"
356 if $self->{PERL_SRC};
358 push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
364 Defines targets for bootstrap files.
369 my($self, %attribs) = @_;
372 ' unless $self->has_link_code();
375 BOOTSTRAP = '."$self->{BASEEXT}.bs".'
377 # As Mkbootstrap might not write a file (if none is required)
378 # we use touch to prevent make continually trying to remake it.
379 # The DynaLoader only reads a non-empty file.
380 $(BOOTSTRAP): '."$self->{MAKEFILE} $self->{BOOTDEP}".' $(INST_ARCHAUTODIR)\.exists
381 '.$self->{NOECHO}.'echo "Running Mkbootstrap for $(NAME) ($(BSLOADLIBS))"
382 '.$self->{NOECHO}.'$(PERLRUN) \
383 -MExtUtils::Mkbootstrap \
384 -e "Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');"
385 '.$self->{NOECHO}.'$(TOUCH) $(BOOTSTRAP)
388 $(INST_BOOT): $(BOOTSTRAP) $(INST_ARCHAUTODIR)\.exists
389 '."$self->{NOECHO}$self->{RM_RF}".' $(INST_BOOT)
390 -'.$self->{CP}.' $(BOOTSTRAP) $(INST_BOOT)
395 =item dynamic_lib (o)
397 Defines how to produce the *.so (or equivalent) files.
402 my($self, %attribs) = @_;
403 return '' unless $self->needs_linking(); #might be because of a subdir
405 return '' unless $self->has_link_code;
407 my($otherldflags) = $attribs{OTHERLDFLAGS} || ($BORLAND ? 'c0d32.obj': '');
408 my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || "";
409 my($ldfrom) = '$(LDFROM)';
412 # one thing for GCC/Mingw32:
413 # we try to overcome non-relocateable-DLL problems by generating
414 # a (hopefully unique) image-base from the dll's name
417 my $dllname = $self->{BASEEXT} . "." . $self->{DLEXT};
418 $dllname =~ /(....)(.{0,4})/;
419 my $baseaddr = unpack("n", $1 ^ $2);
420 $otherldflags .= sprintf("-Wl,--image-base,0x%x0000 ", $baseaddr);
424 # This section creates the dynamically loadable $(INST_DYNAMIC)
425 # from $(OBJECT) and possibly $(MYEXTLIB).
426 OTHERLDFLAGS = '.$otherldflags.'
427 INST_DYNAMIC_DEP = '.$inst_dynamic_dep.'
429 $(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)\.exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP)
433 q{ dlltool --def $(EXPORT_LIST) --output-exp dll.exp
434 $(LD) -o $@ -Wl,--base-file -Wl,dll.base $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) $(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) dll.exp
435 dlltool --def $(EXPORT_LIST) --base-file dll.base --output-exp dll.exp
436 $(LD) -o $@ $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) $(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) dll.exp });
439 q{ $(LD) $(LDDLFLAGS) $(OTHERLDFLAGS) }.$ldfrom.q{,$@,,}
440 .($DMAKE ? q{$(PERL_ARCHIVE:s,/,\,) $(LDLOADLIBS:s,/,\,) }
441 .q{$(MYEXTLIB:s,/,\,),$(EXPORT_LIST:s,/,\,)}
442 : q{$(subst /,\,$(PERL_ARCHIVE)) $(subst /,\,$(LDLOADLIBS)) }
443 .q{$(subst /,\,$(MYEXTLIB)),$(subst /,\,$(EXPORT_LIST))})
447 q{ $(LD) -out:$@ $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) }
448 .q{$(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) -def:$(EXPORT_LIST)});
454 push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
461 my $s = $self->SUPER::clean(@_);
462 my $clean = $GCC ? 'dll.base dll.exp' : '*.pdb';
476 return '$(PERL_INC)\\'.$Config{'libperl'};
482 return "$self->{BASEEXT}.def";
487 Takes one argument, a file name, and returns the file name, if the
488 argument is likely to be a perl script. On MM_Unix this is true for
489 any ordinary, readable file.
494 my($self,$file) = @_;
495 return $file if -r $file && -f _;
496 return "$file.pl" if -r "$file.pl" && -f _;
497 return "$file.bat" if -r "$file.bat" && -f _;
503 Defines target that copies all files in the hash PM to their
504 destination and autosplits them. See L<ExtUtils::Install/DESCRIPTION>
510 my($autodir) = File::Spec->catdir('$(INST_LIB)','auto');
512 pm_to_blib: $(TO_INST_PM)
513 }.$self->{NOECHO}.q{$(PERLRUNINST) -MExtUtils::Install \
515 ($NMAKE ? 'qw[ <<pmfiles.dat ],'
516 : $DMAKE ? 'qw[ $(mktmp,pmfiles.dat $(PM_TO_BLIB:s,\\,\\\\,)\n) ],'
517 : '{ qw[$(PM_TO_BLIB)] },'
518 ).q{'}.$autodir.q{','$(PM_FILTER)')"
522 } : '') . "\t".$self->{NOECHO}.q{$(TOUCH) $@
527 =item tool_autosplit (override)
529 Use Win32 quoting on command line.
534 my($self, %attribs) = @_;
536 $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN};
538 # Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
539 AUTOSPLITFILE = $(PERLRUN) -MAutoSplit }.$asl.q{ -e "autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1);"
543 =item tools_other (o)
547 Defines SHELL, LD, TOUCH, CP, MV, RM_F, RM_RF, CHMOD, UMASK_NULL in
548 the Makefile. Also defines the perl programs MKPATH,
549 WARN_IF_OLD_PACKLIST, MOD_INSTALL. DOC_INSTALL, and UNINSTALL.
556 my $bin_sh = $Config{sh} || 'cmd /c';
559 } unless $DMAKE; # dmake determines its own shell
561 for (qw/ CHMOD CP LD MV NOOP RM_F RM_RF TEST_F TOUCH UMASK_NULL DEV_NULL/ ) {
562 push @m, "$_ = $self->{$_}\n";
566 # The following is a portable way to say mkdir -p
567 # To see which directories are created, change the if 0 to if 1
568 MKPATH = $(PERLRUN) -MExtUtils::Command -e mkpath
570 # This helps us to minimize the effect of the .exists files A yet
571 # better solution would be to have a stable file in the perl
572 # distribution with a timestamp of zero. But this solution doesn't
573 # need any changes to the core distribution and works with older perls
574 EQUALIZE_TIMESTAMP = $(PERLRUN) -MExtUtils::Command -e eqtime
578 return join "", @m if $self->{PARENT};
581 # Here we warn users that an old packlist file was found somewhere,
582 # and that they should call some uninstall routine
583 WARN_IF_OLD_PACKLIST = $(PERL) -lwe "exit unless -f $$ARGV[0];" \\
584 -e "print 'WARNING: I have found an old package in';" \\
585 -e "print ' ', $$ARGV[0], '.';" \\
586 -e "print 'Please make sure the two installations are not conflicting';"
591 MOD_INSTALL = $(PERL) -I$(INST_LIB) -I$(PERL_LIB) -MExtUtils::Install \
592 -e "install({ @ARGV },'$(VERBINST)',0,'$(UNINST)');"
594 DOC_INSTALL = $(PERL) -e "$$\=\"\n\n\";" \
595 -e "print '=head2 ', scalar(localtime), ': C<', shift, '>', ' L<', $$arg=shift, '|', $$arg, '>';" \
596 -e "print '=over 4';" \
597 -e "while (defined($$key = shift) and defined($$val = shift)) { print '=item *';print 'C<', \"$$key: $$val\", '>'; }" \
600 UNINSTALL = $(PERL) -MExtUtils::Install \
601 -e "uninstall($$ARGV[0],1,1); print \"\nUninstall is deprecated. Please check the";" \
602 -e "print \" packlist above carefully.\n There may be errors. Remove the\";" \
603 -e "print \" appropriate files manually.\n Sorry for the inconveniences.\n\""
611 Defines suffix rules to go from XS to object files directly. This is
612 only intended for broken make implementations.
616 sub xs_o { # many makes are too dumb to use xs_c then c_o
621 =item top_targets (o)
623 Defines the targets all, subdirs, config, and O_FILES
628 # --- Target Sections ---
634 all :: pure_all manifypods
635 '.$self->{NOECHO}.'$(NOOP)
637 unless $self->{SKIPHASH}{'all'};
640 pure_all :: config pm_to_blib subdirs linkext
641 '.$self->{NOECHO}.'$(NOOP)
643 subdirs :: $(MYEXTLIB)
644 '.$self->{NOECHO}.'$(NOOP)
646 config :: '.$self->{MAKEFILE}.' $(INST_LIBDIR)\.exists
647 '.$self->{NOECHO}.'$(NOOP)
649 config :: $(INST_ARCHAUTODIR)\.exists
650 '.$self->{NOECHO}.'$(NOOP)
652 config :: $(INST_AUTODIR)\.exists
653 '.$self->{NOECHO}.'$(NOOP)
656 push @m, $self->dir_target(qw[$(INST_AUTODIR) $(INST_LIBDIR) $(INST_ARCHAUTODIR)]);
658 if (%{$self->{MAN1PODS}}) {
660 config :: \$(INST_MAN1DIR)\\.exists
661 $self->{NOECHO}\$(NOOP)
664 push @m, $self->dir_target(qw[$(INST_MAN1DIR)]);
666 if (%{$self->{MAN3PODS}}) {
668 config :: \$(INST_MAN3DIR)\\.exists
669 $self->{NOECHO}\$(NOOP)
672 push @m, $self->dir_target(qw[$(INST_MAN3DIR)]);
676 $(O_FILES): $(H_FILES)
677 ' if @{$self->{O_FILES} || []} && @{$self->{H} || []};
681 perldoc ExtUtils::MakeMaker
689 We don't want manpage process.
695 return "\nmanifypods :\n\t$self->{NOECHO}\$(NOOP)\n";
700 Same as MM_Unix version (changes command-line quoting).
709 $(PERLRUN) -MExtUtils::Manifest=maniread \\
710 -e "@all = keys %{ maniread() };" \\
711 -e "print(\"Executing $(CI) @all\n\"); system(\"$(CI) @all\");" \\
712 -e "print(\"Executing $(RCS_LABEL) ...\n\"); system(\"$(RCS_LABEL) @all\");"
719 Same as MM_Unix version (changes command-line quoting).
727 dist : $(DIST_DEFAULT)
728 }.$self->{NOECHO}.q{$(PERL) -le "print \"Warning: Makefile possibly out of date with $$vf\" if " \
729 -e "-e ($$vf=\"$(VERSION_FROM)\") and -M $$vf < -M \"}.$self->{MAKEFILE}.q{\";"
731 tardist : $(DISTVNAME).tar$(SUFFIX)
733 zipdist : $(DISTVNAME).zip
735 $(DISTVNAME).tar$(SUFFIX) : distdir
738 $(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME)
739 $(RM_RF) $(DISTVNAME)
740 $(COMPRESS) $(DISTVNAME).tar
743 $(DISTVNAME).zip : distdir
745 $(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME)
746 $(RM_RF) $(DISTVNAME)
749 uutardist : $(DISTVNAME).tar$(SUFFIX)
750 uuencode $(DISTVNAME).tar$(SUFFIX) \\
751 $(DISTVNAME).tar$(SUFFIX) > \\
752 $(DISTVNAME).tar$(SUFFIX)_uu
756 $(SHAR) $(DISTVNAME) > $(DISTVNAME).shar
757 $(RM_RF) $(DISTVNAME)
765 Defines the string that is passed to recursive make calls in
772 return "PASTHRU = " . ($NMAKE ? "-nologo" : "");