1N/Apackage ExtUtils::MM_Win32;
1N/A
1N/Ause strict;
1N/A
1N/A
1N/A=head1 NAME
1N/A
1N/AExtUtils::MM_Win32 - methods to override UN*X behaviour in ExtUtils::MakeMaker
1N/A
1N/A=head1 SYNOPSIS
1N/A
1N/A use ExtUtils::MM_Win32; # Done internally by ExtUtils::MakeMaker if needed
1N/A
1N/A=head1 DESCRIPTION
1N/A
1N/ASee ExtUtils::MM_Unix for a documentation of the methods provided
1N/Athere. This package overrides the implementation of these methods, not
1N/Athe semantics.
1N/A
1N/A=cut
1N/A
1N/Ause Config;
1N/Ause File::Basename;
1N/Ause File::Spec;
1N/Ause ExtUtils::MakeMaker qw( neatvalue );
1N/A
1N/Ause vars qw(@ISA $VERSION $BORLAND $GCC $DMAKE $NMAKE);
1N/A
1N/Arequire ExtUtils::MM_Any;
1N/Arequire ExtUtils::MM_Unix;
1N/A@ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix );
1N/A$VERSION = '1.09';
1N/A
1N/A$ENV{EMXSHELL} = 'sh'; # to run `commands`
1N/A
1N/A$BORLAND = 1 if $Config{'cc'} =~ /^bcc/i;
1N/A$GCC = 1 if $Config{'cc'} =~ /^gcc/i;
1N/A$DMAKE = 1 if $Config{'make'} =~ /^dmake/i;
1N/A$NMAKE = 1 if $Config{'make'} =~ /^nmake/i;
1N/A
1N/A
1N/A=head2 Overridden methods
1N/A
1N/A=over 4
1N/A
1N/A=item B<dlsyms>
1N/A
1N/A=cut
1N/A
1N/Asub dlsyms {
1N/A my($self,%attribs) = @_;
1N/A
1N/A my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {};
1N/A my($vars) = $attribs{DL_VARS} || $self->{DL_VARS} || [];
1N/A my($funclist) = $attribs{FUNCLIST} || $self->{FUNCLIST} || [];
1N/A my($imports) = $attribs{IMPORTS} || $self->{IMPORTS} || {};
1N/A my(@m);
1N/A
1N/A if (not $self->{SKIPHASH}{'dynamic'}) {
1N/A push(@m,"
1N/A$self->{BASEEXT}.def: Makefile.PL
1N/A",
1N/A q! $(PERLRUN) -MExtUtils::Mksymlists \\
1N/A -e "Mksymlists('NAME'=>\"!, $self->{NAME},
1N/A q!\", 'DLBASE' => '!,$self->{DLBASE},
1N/A # The above two lines quoted differently to work around
1N/A # a bug in the 4DOS/4NT command line interpreter. The visible
1N/A # result of the bug was files named q('extension_name',) *with the
1N/A # single quotes and the comma* in the extension build directories.
1N/A q!', 'DL_FUNCS' => !,neatvalue($funcs),
1N/A q!, 'FUNCLIST' => !,neatvalue($funclist),
1N/A q!, 'IMPORTS' => !,neatvalue($imports),
1N/A q!, 'DL_VARS' => !, neatvalue($vars), q!);"
1N/A!);
1N/A }
1N/A join('',@m);
1N/A}
1N/A
1N/A=item replace_manpage_separator
1N/A
1N/AChanges the path separator with .
1N/A
1N/A=cut
1N/A
1N/Asub replace_manpage_separator {
1N/A my($self,$man) = @_;
1N/A $man =~ s,/+,.,g;
1N/A $man;
1N/A}
1N/A
1N/A
1N/A=item B<maybe_command>
1N/A
1N/ASince Windows has nothing as simple as an executable bit, we check the
1N/Afile extension.
1N/A
1N/AThe PATHEXT env variable will be used to get a list of extensions that
1N/Amight indicate a command, otherwise .com, .exe, .bat and .cmd will be
1N/Aused by default.
1N/A
1N/A=cut
1N/A
1N/Asub maybe_command {
1N/A my($self,$file) = @_;
1N/A my @e = exists($ENV{'PATHEXT'})
1N/A ? split(/;/, $ENV{PATHEXT})
1N/A : qw(.com .exe .bat .cmd);
1N/A my $e = '';
1N/A for (@e) { $e .= "\Q$_\E|" }
1N/A chop $e;
1N/A # see if file ends in one of the known extensions
1N/A if ($file =~ /($e)$/i) {
1N/A return $file if -e $file;
1N/A }
1N/A else {
1N/A for (@e) {
1N/A return "$file$_" if -e "$file$_";
1N/A }
1N/A }
1N/A return;
1N/A}
1N/A
1N/A
1N/A=item B<find_tests>
1N/A
1N/AThe Win9x shell does not expand globs and I'll play it safe and assume
1N/Aother Windows variants don't either.
1N/A
1N/ASo we do it for them.
1N/A
1N/A=cut
1N/A
1N/Asub find_tests {
1N/A return join(' ', <t\\*.t>);
1N/A}
1N/A
1N/A
1N/A=item B<init_DIRFILESEP>
1N/A
1N/AUsing \ for Windows.
1N/A
1N/A=cut
1N/A
1N/Asub init_DIRFILESEP {
1N/A my($self) = shift;
1N/A
1N/A # The ^ makes sure its not interpreted as an escape in nmake
1N/A $self->{DIRFILESEP} = $NMAKE ? '^\\' :
1N/A $DMAKE ? '\\\\'
1N/A : '\\';
1N/A}
1N/A
1N/A=item B<init_others>
1N/A
1N/AOverride some of the Unix specific commands with portable
1N/AExtUtils::Command ones.
1N/A
1N/AAlso provide defaults for LD and AR in case the %Config values aren't
1N/Aset.
1N/A
1N/ALDLOADLIBS's default is changed to $Config{libs}.
1N/A
1N/AAdjustments are made for Borland's quirks needing -L to come first.
1N/A
1N/A=cut
1N/A
1N/Asub init_others {
1N/A my ($self) = @_;
1N/A
1N/A # Used in favor of echo because echo won't strip quotes. :(
1N/A $self->{ECHO} ||= $self->oneliner('print qq{@ARGV}', ['-l']);
1N/A $self->{ECHO_N} ||= $self->oneliner('print qq{@ARGV}');
1N/A
1N/A $self->{TOUCH} ||= '$(PERLRUN) -MExtUtils::Command -e touch';
1N/A $self->{CHMOD} ||= '$(PERLRUN) -MExtUtils::Command -e chmod';
1N/A $self->{CP} ||= '$(PERLRUN) -MExtUtils::Command -e cp';
1N/A $self->{RM_F} ||= '$(PERLRUN) -MExtUtils::Command -e rm_f';
1N/A $self->{RM_RF} ||= '$(PERLRUN) -MExtUtils::Command -e rm_rf';
1N/A $self->{MV} ||= '$(PERLRUN) -MExtUtils::Command -e mv';
1N/A $self->{NOOP} ||= 'rem';
1N/A $self->{TEST_F} ||= '$(PERLRUN) -MExtUtils::Command -e test_f';
1N/A $self->{DEV_NULL} ||= '> NUL';
1N/A
1N/A $self->{LD} ||= $Config{ld} || 'link';
1N/A $self->{AR} ||= $Config{ar} || 'lib';
1N/A
1N/A $self->SUPER::init_others;
1N/A
1N/A # Setting SHELL from $Config{sh} can break dmake. Its ok without it.
1N/A delete $self->{SHELL};
1N/A
1N/A $self->{LDLOADLIBS} ||= $Config{libs};
1N/A # -Lfoo must come first for Borland, so we put it in LDDLFLAGS
1N/A if ($BORLAND) {
1N/A my $libs = $self->{LDLOADLIBS};
1N/A my $libpath = '';
1N/A while ($libs =~ s/(?:^|\s)(("?)-L.+?\2)(?:\s|$)/ /) {
1N/A $libpath .= ' ' if length $libpath;
1N/A $libpath .= $1;
1N/A }
1N/A $self->{LDLOADLIBS} = $libs;
1N/A $self->{LDDLFLAGS} ||= $Config{lddlflags};
1N/A $self->{LDDLFLAGS} .= " $libpath";
1N/A }
1N/A
1N/A return 1;
1N/A}
1N/A
1N/A
1N/A=item init_platform (o)
1N/A
1N/AAdd MM_Win32_VERSION.
1N/A
1N/A=item platform_constants (o)
1N/A
1N/A=cut
1N/A
1N/Asub init_platform {
1N/A my($self) = shift;
1N/A
1N/A $self->{MM_Win32_VERSION} = $VERSION;
1N/A}
1N/A
1N/Asub platform_constants {
1N/A my($self) = shift;
1N/A my $make_frag = '';
1N/A
1N/A foreach my $macro (qw(MM_Win32_VERSION))
1N/A {
1N/A next unless defined $self->{$macro};
1N/A $make_frag .= "$macro = $self->{$macro}\n";
1N/A }
1N/A
1N/A return $make_frag;
1N/A}
1N/A
1N/A
1N/A=item special_targets (o)
1N/A
1N/AAdd .USESHELL target for dmake.
1N/A
1N/A=cut
1N/A
1N/Asub special_targets {
1N/A my($self) = @_;
1N/A
1N/A my $make_frag = $self->SUPER::special_targets;
1N/A
1N/A $make_frag .= <<'MAKE_FRAG' if $DMAKE;
1N/A.USESHELL :
1N/AMAKE_FRAG
1N/A
1N/A return $make_frag;
1N/A}
1N/A
1N/A
1N/A=item static_lib (o)
1N/A
1N/AChanges how to run the linker.
1N/A
1N/AThe rest is duplicate code from MM_Unix. Should move the linker code
1N/Ato its own method.
1N/A
1N/A=cut
1N/A
1N/Asub static_lib {
1N/A my($self) = @_;
1N/A return '' unless $self->has_link_code;
1N/A
1N/A my(@m);
1N/A push(@m, <<'END');
1N/A$(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists
1N/A $(RM_RF) $@
1N/AEND
1N/A
1N/A # If this extension has its own library (eg SDBM_File)
1N/A # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
1N/A push @m, <<'MAKE_FRAG' if $self->{MYEXTLIB};
1N/A $(CP) $(MYEXTLIB) $@
1N/AMAKE_FRAG
1N/A
1N/A push @m,
1N/Aq{ $(AR) }.($BORLAND ? '$@ $(OBJECT:^"+")'
1N/A : ($GCC ? '-ru $@ $(OBJECT)'
1N/A : '-out:$@ $(OBJECT)')).q{
1N/A $(CHMOD) $(PERM_RWX) $@
1N/A $(NOECHO) $(ECHO) "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)\extralibs.ld
1N/A};
1N/A
1N/A # Old mechanism - still available:
1N/A push @m, <<'MAKE_FRAG' if $self->{PERL_SRC} && $self->{EXTRALIBS};
1N/A $(NOECHO) $(ECHO) "$(EXTRALIBS)" >> $(PERL_SRC)\ext.libs
1N/AMAKE_FRAG
1N/A
1N/A push @m, "\n", $self->dir_target('$(INST_ARCHAUTODIR)');
1N/A join('', @m);
1N/A}
1N/A
1N/A
1N/A=item dynamic_lib (o)
1N/A
1N/AComplicated stuff for Win32 that I don't understand. :(
1N/A
1N/A=cut
1N/A
1N/Asub dynamic_lib {
1N/A my($self, %attribs) = @_;
1N/A return '' unless $self->needs_linking(); #might be because of a subdir
1N/A
1N/A return '' unless $self->has_link_code;
1N/A
1N/A my($otherldflags) = $attribs{OTHERLDFLAGS} || ($BORLAND ? 'c0d32.obj': '');
1N/A my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || "";
1N/A my($ldfrom) = '$(LDFROM)';
1N/A my(@m);
1N/A
1N/A# one thing for GCC/Mingw32:
1N/A# we try to overcome non-relocateable-DLL problems by generating
1N/A# a (hopefully unique) image-base from the dll's name
1N/A# -- BKS, 10-19-1999
1N/A if ($GCC) {
1N/A my $dllname = $self->{BASEEXT} . "." . $self->{DLEXT};
1N/A $dllname =~ /(....)(.{0,4})/;
1N/A my $baseaddr = unpack("n", $1 ^ $2);
1N/A $otherldflags .= sprintf("-Wl,--image-base,0x%x0000 ", $baseaddr);
1N/A }
1N/A
1N/A push(@m,'
1N/A# This section creates the dynamically loadable $(INST_DYNAMIC)
1N/A# from $(OBJECT) and possibly $(MYEXTLIB).
1N/AOTHERLDFLAGS = '.$otherldflags.'
1N/AINST_DYNAMIC_DEP = '.$inst_dynamic_dep.'
1N/A
1N/A$(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP)
1N/A');
1N/A if ($GCC) {
1N/A push(@m,
1N/A q{ dlltool --def $(EXPORT_LIST) --output-exp dll.exp
1N/A $(LD) -o $@ -Wl,--base-file -Wl,dll.base $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) $(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) dll.exp
1N/A dlltool --def $(EXPORT_LIST) --base-file dll.base --output-exp dll.exp
1N/A $(LD) -o $@ $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) $(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) dll.exp });
1N/A } elsif ($BORLAND) {
1N/A push(@m,
1N/A q{ $(LD) $(LDDLFLAGS) $(OTHERLDFLAGS) }.$ldfrom.q{,$@,,}
1N/A .($DMAKE ? q{$(PERL_ARCHIVE:s,/,\,) $(LDLOADLIBS:s,/,\,) }
1N/A .q{$(MYEXTLIB:s,/,\,),$(EXPORT_LIST:s,/,\,)}
1N/A : q{$(subst /,\,$(PERL_ARCHIVE)) $(subst /,\,$(LDLOADLIBS)) }
1N/A .q{$(subst /,\,$(MYEXTLIB)),$(subst /,\,$(EXPORT_LIST))})
1N/A .q{,$(RESFILES)});
1N/A } else { # VC
1N/A push(@m,
1N/A q{ $(LD) -out:$@ $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) }
1N/A .q{$(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) -def:$(EXPORT_LIST)});
1N/A }
1N/A push @m, '
1N/A $(CHMOD) $(PERM_RWX) $@
1N/A';
1N/A
1N/A push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
1N/A join('',@m);
1N/A}
1N/A
1N/A=item clean
1N/A
1N/AClean out some extra dll.{base,exp} files which might be generated by
1N/Agcc. Otherwise, take out all *.pdb files.
1N/A
1N/A=cut
1N/A
1N/Asub clean
1N/A{
1N/A my ($self) = shift;
1N/A my $s = $self->SUPER::clean(@_);
1N/A my $clean = $GCC ? 'dll.base dll.exp' : '*.pdb';
1N/A $s .= <<END;
1N/Aclean ::
1N/A -\$(RM_F) $clean
1N/A
1N/AEND
1N/A return $s;
1N/A}
1N/A
1N/A=item init_linker
1N/A
1N/A=cut
1N/A
1N/Asub init_linker {
1N/A my $self = shift;
1N/A
1N/A $self->{PERL_ARCHIVE} = "\$(PERL_INC)\\$Config{libperl}";
1N/A $self->{PERL_ARCHIVE_AFTER} = '';
1N/A $self->{EXPORT_LIST} = '$(BASEEXT).def';
1N/A}
1N/A
1N/A
1N/A=item perl_script
1N/A
1N/AChecks for the perl program under several common perl extensions.
1N/A
1N/A=cut
1N/A
1N/Asub perl_script {
1N/A my($self,$file) = @_;
1N/A return $file if -r $file && -f _;
1N/A return "$file.pl" if -r "$file.pl" && -f _;
1N/A return "$file.plx" if -r "$file.plx" && -f _;
1N/A return "$file.bat" if -r "$file.bat" && -f _;
1N/A return;
1N/A}
1N/A
1N/A
1N/A=item xs_o (o)
1N/A
1N/AThis target is stubbed out. Not sure why.
1N/A
1N/A=cut
1N/A
1N/Asub xs_o {
1N/A return ''
1N/A}
1N/A
1N/A
1N/A=item pasthru (o)
1N/A
1N/AAll we send is -nologo to nmake to prevent it from printing its damned
1N/Abanner.
1N/A
1N/A=cut
1N/A
1N/Asub pasthru {
1N/A my($self) = shift;
1N/A return "PASTHRU = " . ($NMAKE ? "-nologo" : "");
1N/A}
1N/A
1N/A
1N/A=item oneliner (o)
1N/A
1N/AThese are based on what command.com does on Win98. They may be wrong
1N/Afor other Windows shells, I don't know.
1N/A
1N/A=cut
1N/A
1N/Asub oneliner {
1N/A my($self, $cmd, $switches) = @_;
1N/A $switches = [] unless defined $switches;
1N/A
1N/A # Strip leading and trailing newlines
1N/A $cmd =~ s{^\n+}{};
1N/A $cmd =~ s{\n+$}{};
1N/A
1N/A $cmd = $self->quote_literal($cmd);
1N/A $cmd = $self->escape_newlines($cmd);
1N/A
1N/A $switches = join ' ', @$switches;
1N/A
1N/A return qq{\$(PERLRUN) $switches -e $cmd};
1N/A}
1N/A
1N/A
1N/Asub quote_literal {
1N/A my($self, $text) = @_;
1N/A
1N/A # I don't know if this is correct, but it seems to work on
1N/A # Win98's command.com
1N/A $text =~ s{"}{\\"}g;
1N/A
1N/A # dmake eats '{' inside double quotes and leaves alone { outside double
1N/A # quotes; however it transforms {{ into { either inside and outside double
1N/A # quotes. It also translates }} into }. The escaping below is not
1N/A # 100% correct.
1N/A if( $DMAKE ) {
1N/A $text =~ s/{/{{/g;
1N/A $text =~ s/}}/}}}/g;
1N/A }
1N/A
1N/A return qq{"$text"};
1N/A}
1N/A
1N/A
1N/Asub escape_newlines {
1N/A my($self, $text) = @_;
1N/A
1N/A # Escape newlines
1N/A $text =~ s{\n}{\\\n}g;
1N/A
1N/A return $text;
1N/A}
1N/A
1N/A
1N/A=item max_exec_len
1N/A
1N/Anmake 1.50 limits command length to 2048 characters.
1N/A
1N/A=cut
1N/A
1N/Asub max_exec_len {
1N/A my $self = shift;
1N/A
1N/A return $self->{_MAX_EXEC_LEN} ||= 2 * 1024;
1N/A}
1N/A
1N/A
1N/A=item os_flavor
1N/A
1N/AWindows is Win32.
1N/A
1N/A=cut
1N/A
1N/Asub os_flavor {
1N/A return('Win32');
1N/A}
1N/A
1N/A
1N/A1;
1N/A__END__
1N/A
1N/A=back
1N/A
1N/A=cut
1N/A
1N/A