home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / Windows.pm < prev    next >
Encoding:
Perl POD Document  |  2003-12-23  |  17.7 KB  |  659 lines

  1. package Module::Build::Platform::Windows;
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use File::Basename;
  7. use File::Spec;
  8.  
  9. use Module::Build::Base;
  10.  
  11. use vars qw(@ISA);
  12. @ISA = qw(Module::Build::Base);
  13.  
  14. sub new {
  15.   my $class = shift;
  16.   my $self = $class->SUPER::new(@_);
  17.   my $cf = $self->{config};
  18.  
  19.   # Inherit from an appropriate compiler driver class
  20.   unshift @ISA, "Module::Build::Platform::Windows::" . $self->compiler_type;
  21.  
  22.   # Find 'pl2bat.bat' utility used for installing perl scripts.
  23.   # This search is probably overkill, as I've never met a MSWin32 perl
  24.   # where these locations differed from each other.
  25.   my @potential_dirs = map { File::Spec->canonpath($_) }
  26.     @${cf}{qw(installscript installbin installsitebin installvendorbin)},
  27.     File::Basename::dirname($self->{properties}{perl});
  28.  
  29.   foreach my $dir (@potential_dirs) {
  30.     my $potential_file = File::Spec->catfile($dir, 'pl2bat.bat');
  31.     if ( -f $potential_file && !-d _ ) {
  32.       $cf->{pl2bat} = $potential_file;
  33.       last;
  34.     }
  35.   }
  36.  
  37.   return $self;
  38. }
  39.  
  40. sub resume {
  41.   my $class = shift;
  42.   my $self = $class->SUPER::resume(@_);
  43.  
  44.   # Inherit from an appropriate compiler driver class
  45.   unshift @ISA, "Module::Build::Platform::Windows::" . $self->compiler_type;
  46.   return $self;
  47. }
  48.  
  49. sub compiler_type {
  50.   my $self = shift;
  51.   my $cc = $self->{config}{cc};
  52.  
  53.   return (  $cc =~ /cl(\.exe)?$/ ? 'MSVC'
  54.       : $cc =~ /bcc32(\.exe)?$/ ? 'BCC'
  55.       : 'GCC');
  56. }
  57.  
  58. sub compile_c {
  59.   my ($self, $file) = @_;
  60.   my $cf = $self->{config};
  61.  
  62.   my ($basename, $srcdir) =
  63.     ( File::Basename::fileparse($file, '\.[^.]+$') )[0,1];
  64.  
  65.   my %spec = (
  66.     srcdir      => $srcdir,
  67.     builddir    => $srcdir,
  68.     basename    => $basename,
  69.     source      => $file,
  70.     output      => File::Spec->catfile($srcdir, $basename) . $cf->{obj_ext},
  71.     cc          => $cf->{cc},
  72.     cflags      => [
  73.                      $self->split_like_shell($cf->{ccflags}),
  74.                      $self->split_like_shell($cf->{cccdlflags}),
  75.                    ],
  76.     optimize    => [ $self->split_like_shell($cf->{optimize})    ],
  77.     defines     => [ '' ],
  78.     includes    => $self->{include_dirs} || [],
  79.     perlinc     => [
  80.                      File::Spec->catdir($cf->{archlib}, 'CORE'),
  81.                      $self->split_like_shell($cf->{incpath}),
  82.                    ],
  83.     use_scripts => 1, # XXX provide user option to change this???
  84.   );
  85.  
  86.   $self->add_to_cleanup($spec{output});
  87.  
  88.   return $spec{output}
  89.     if $self->up_to_date($spec{source}, $spec{output});
  90.  
  91.   $self->normalize_filespecs(
  92.     \$spec{source},
  93.     \$spec{output},
  94.      $spec{includes},
  95.      $spec{perlinc},
  96.   );
  97.  
  98.   my @cmds = $self->format_compiler_cmd(%spec);
  99.   while ( my $cmd = shift @cmds ) {
  100.     $self->do_system( @$cmd )
  101.       or die "error building $cf->{dlext} file from '$file'";
  102.   }
  103.  
  104.   return $spec{output};
  105. }
  106.  
  107. sub need_prelink_c { 1 }
  108.  
  109. sub link_c {
  110.   my ($self, $to, $file_base) = @_;
  111.   my $cf = $self->{config};
  112.  
  113.   my $mylib = File::Spec->catfile(
  114.     $to, File::Basename::basename("$file_base.$cf->{dlext}") );
  115.  
  116.   my %spec = (
  117.     srcdir        => File::Basename::dirname($file_base),
  118.     builddir      => $to,
  119.     startup       => [ ],
  120.     objects       => [ "$file_base$cf->{obj_ext}", @{$self->{objects} || []} ],
  121.     libs          => [ ],
  122.     output        => $mylib,
  123.     ld            => $cf->{ld},
  124.     libperl       => $cf->{libperl},
  125.     perllibs      => [ $self->split_like_shell($cf->{perllibs})  ],
  126.     libpath       => [ $self->split_like_shell($cf->{libpth})    ],
  127.     lddlflags     => [ $self->split_like_shell($cf->{lddlflags}) ],
  128.     other_ldflags => [ $self->split_like_shell($self->{properties}{extra_linker_flags} || '') ],
  129.     use_scripts   => 1, # XXX provide user option to change this???
  130.   );
  131.  
  132.   unless ( $spec{basename} ) {
  133.     ($spec{basename} = $self->{properties}{module_name}) =~ s/.*:://;
  134.   }
  135.  
  136.   $spec{srcdir}   = File::Spec->canonpath( $spec{srcdir}   );
  137.   $spec{builddir} = File::Spec->canonpath( $spec{builddir} );
  138.  
  139.   $spec{output}    ||= File::Spec->catfile( $spec{builddir},
  140.                                             $spec{basename}  . $cf->{dlext}   );
  141.   $spec{implib}    ||= File::Spec->catfile( $spec{builddir},
  142.                                             $spec{basename}  . $cf->{lib_ext} );
  143.   $spec{explib}    ||= File::Spec->catfile( $spec{builddir},
  144.                                             $spec{basename}  . '.exp'  );
  145.   $spec{def_file}  ||= File::Spec->catfile( $spec{srcdir}  ,
  146.                                             $spec{basename}  . '.def'  );
  147.   $spec{base_file} ||= File::Spec->catfile( $spec{srcdir}  ,
  148.                                             $spec{basename}  . '.base' );
  149.  
  150.   $self->add_to_cleanup(
  151.     grep defined,
  152.     @{[ @spec{qw(output implib explib def_file base_file map_file)} ]}
  153.   );
  154.  
  155.   return if $self->up_to_date( $spec{objects}, $spec{output} );
  156.  
  157.   foreach my $opt ( qw(output implib explib def_file map_file base_file) ) {
  158.     $self->normalize_filespecs( \$spec{$opt} );
  159.   }
  160.  
  161.   foreach my $opt ( qw(libpath startup objects) ) {
  162.     $self->normalize_filespecs( $spec{$opt} );
  163.   }
  164.  
  165.   $self->prelink_c( $to, $file_base );
  166.  
  167.   my @cmds = $self->format_linker_cmd(%spec);
  168.   while ( my $cmd = shift @cmds ) {
  169.     $self->do_system( @$cmd );
  170.   }
  171.  
  172.   return $spec{output};
  173. }
  174.  
  175. # canonize & quote paths
  176. sub normalize_filespecs {
  177.   my ($self, @specs) = @_;
  178.   foreach my $spec ( grep defined, @specs ) {
  179.     if ( ref $spec eq 'ARRAY') {
  180.       $self->normalize_filespecs( map {\$_} grep defined, @$spec )
  181.     } elsif ( ref $spec eq 'SCALAR' ) {
  182.       $$spec =~ tr/"//d if $$spec;
  183.       next unless $$spec;
  184.       $$spec = '"' . File::Spec->canonpath($$spec) . '"';
  185.     } else {
  186.       die "Don't know how to normalize " . (ref $spec || $spec) . "\n";
  187.     }
  188.   }
  189. }
  190.  
  191. sub make_executable {
  192.   my $self = shift;
  193.   $self->SUPER::make_executable(@_);
  194.  
  195.   my $pl2bat = $self->{config}{pl2bat};
  196.  
  197.   if ( defined($pl2bat) && length($pl2bat) ) {
  198.     foreach my $script (@_) {
  199.       # Don't run 'pl2bat.bat' for the 'Build' script;
  200.       # there is no easy way to get the resulting 'Build.bat'
  201.       # to delete itself when doing a 'Build realclean'.
  202.       next if ( $script eq $self->{properties}{build_script} );
  203.  
  204.       (my $script_bat = $script) =~ s/\.plx?//i;
  205.       $script_bat .= '.bat' unless $script_bat =~ /\.bat$/i;
  206.  
  207.       my $status = $self->do_system($pl2bat, '<', $script, '>', $script_bat);
  208.       if ( $status && -f $script_bat ) {
  209.         $self->SUPER::make_executable($script_bat);
  210.       } else {
  211.         warn "Unable to convert '$script' to an executable.\n";
  212.       }
  213.     }
  214.   } else {
  215.     warn "Could not find 'pl2bat.bat' utility needed to make scripts executable.\n"
  216.        . "Unable to convert scripts ( " . join(', ', @_) . " ) to executables.\n";
  217.   }
  218. }
  219.  
  220.  
  221. sub manpage_separator {
  222.     return '.';
  223. }
  224.  
  225.  
  226. 1;
  227.  
  228. ########################################################################
  229.  
  230. =begin comment
  231.  
  232. The packages below implement functions for generating properly
  233. formated commandlines for the compiler being used. Each package
  234. defines two primary functions 'format_linker_cmd()' &
  235. 'format_compiler_comand()' that accepts a list of named arguments (a
  236. hash) and returns a list of formated options suitable for invoking the
  237. compiler. By default, if the compiler supports scripting of its
  238. operation then a script file is built containing the options while
  239. those options are removed from the commandline, and a reference to the
  240. script is pushed onto the commandline in their place. Scripting the
  241. compiler in this way helps to avoid the problems associated with long
  242. commandlines under some shells.
  243.  
  244. =end comment
  245.  
  246. =cut
  247.  
  248. ########################################################################
  249. package Module::Build::Platform::Windows::MSVC;
  250.  
  251. sub format_compiler_cmd {
  252.   my ($self, %spec) = @_;
  253.  
  254.   foreach my $path ( @{ $spec{includes} || [] },
  255.                      @{ $spec{perlinc}  || [] } ) {
  256.     $path = '-I' . $path;
  257.   }
  258.  
  259.   %spec = $self->write_compiler_script(%spec)
  260.     if $spec{use_scripts};
  261.  
  262.   return [ grep {defined && length} (
  263.     $spec{cc}, '-c'         ,
  264.     @{$spec{includes}}      ,
  265.     @{$spec{cflags}}        ,
  266.     @{$spec{optimize}}      ,
  267.     @{$spec{defines}}       ,
  268.     @{$spec{perlinc}}       ,
  269.     "-Fo$spec{output}"      ,
  270.     $spec{source}           ,
  271.   ) ];
  272. }
  273.  
  274. sub write_compiler_script {
  275.   my ($self, %spec) = @_;
  276.  
  277.   my $script = File::Spec->catfile( $spec{srcdir},
  278.                                     $spec{basename} . '.ccs' );
  279.  
  280.   $self->add_to_cleanup($script);
  281.  
  282.   print "Generating script '$script'\n";
  283.  
  284.   open( SCRIPT, ">$script" )
  285.     or die( "Could not create script '$script': $!" );
  286.  
  287.   print SCRIPT join( "\n",
  288.     map { ref $_ ? @{$_} : $_ }
  289.     grep defined,
  290.     delete(
  291.       @spec{ qw(includes cflags optimize defines perlinc) } )
  292.   );
  293.  
  294.   close SCRIPT;
  295.  
  296.   push @{$spec{includes}}, '@"' . $script . '"';
  297.  
  298.   return %spec;
  299. }
  300.  
  301. sub format_linker_cmd {
  302.   my ($self, %spec) = @_;
  303.  
  304.   foreach my $path ( @{$spec{libpath}} ) {
  305.     $path = "-libpath:$path";
  306.   }
  307.  
  308.   $spec{def_file}  &&= '-def:'    . $spec{def_file};
  309.   $spec{output}    &&= '-out:'    . $spec{output};
  310.   $spec{implib}    &&= '-implib:' . $spec{implib};
  311.   $spec{map_file}  &&= '-map:'    . $spec{map_file};
  312.  
  313.   %spec = $self->write_linker_script(%spec)
  314.     if $spec{use_scripts};
  315.  
  316.   return [ grep {defined && length} (
  317.     $spec{ld}               ,
  318.     @{$spec{lddlflags}}     ,
  319.     @{$spec{libpath}}       ,
  320.     @{$spec{other_ldflags}} ,
  321.     @{$spec{startup}}       ,
  322.     @{$spec{objects}}       ,
  323.     $spec{map_file}         ,
  324.     $spec{libperl}          ,
  325.     @{$spec{perllibs}}      ,
  326.     $spec{def_file}         ,
  327.     $spec{implib}           ,
  328.     $spec{output}           ,
  329.   ) ];
  330. }
  331.  
  332. sub write_linker_script {
  333.   my ($self, %spec) = @_;
  334.  
  335.   my $script = File::Spec->catfile( $spec{srcdir},
  336.                                     $spec{basename} . '.lds' );
  337.  
  338.   $self->add_to_cleanup($script);
  339.  
  340.   print "Generating script '$script'\n";
  341.  
  342.   open( SCRIPT, ">$script" )
  343.     or die( "Could not create script '$script': $!" );
  344.  
  345.   print SCRIPT join( "\n",
  346.     map { ref $_ ? @{$_} : $_ }
  347.     grep defined,
  348.     delete(
  349.       @spec{ qw(lddlflags libpath other_ldflags
  350.                 startup objects libperl perllibs
  351.                 def_file implib map_file)            } )
  352.   );
  353.  
  354.   close SCRIPT;
  355.  
  356.   push @{$spec{lddlflags}}, '@"' . $script . '"';
  357.  
  358.   return %spec;
  359. }
  360.  
  361. 1;
  362.  
  363. ########################################################################
  364. package Module::Build::Platform::Windows::BCC;
  365.  
  366. sub format_compiler_cmd {
  367.   my ($self, %spec) = @_;
  368.  
  369.   foreach my $path ( @{ $spec{includes} || [] },
  370.                      @{ $spec{perlinc}  || [] } ) {
  371.     $path = '-I' . $path;
  372.   }
  373.  
  374.   %spec = $self->write_compiler_script(%spec)
  375.     if $spec{use_scripts};
  376.  
  377.   return [ grep {defined && length} (
  378.     $spec{cc}, '-c'         ,
  379.     @{$spec{includes}}      ,
  380.     @{$spec{cflags}}        ,
  381.     @{$spec{optimize}}      ,
  382.     @{$spec{defines}}       ,
  383.     @{$spec{perlinc}}       ,
  384.     "-o$spec{output}"       ,
  385.     $spec{source}           ,
  386.   ) ];
  387. }
  388.  
  389. sub write_compiler_script {
  390.   my ($self, %spec) = @_;
  391.  
  392.   my $script = File::Spec->catfile( $spec{srcdir},
  393.                                     $spec{basename} . '.ccs' );
  394.  
  395.   $self->add_to_cleanup($script);
  396.  
  397.   print "Generating script '$script'\n";
  398.  
  399.   open( SCRIPT, ">$script" )
  400.     or die( "Could not create script '$script': $!" );
  401.  
  402.   print SCRIPT join( "\n",
  403.     map { ref $_ ? @{$_} : $_ }
  404.     grep defined,
  405.     delete(
  406.       @spec{ qw(includes cflags optimize defines perlinc) } )
  407.   );
  408.  
  409.   close SCRIPT;
  410.  
  411.   push @{$spec{includes}}, '@"' . $script . '"';
  412.  
  413.   return %spec;
  414. }
  415.  
  416. sub format_linker_cmd {
  417.   my ($self, %spec) = @_;
  418.  
  419.   foreach my $path ( @{$spec{libpath}} ) {
  420.     $path = "-L$path";
  421.   }
  422.  
  423.   push( @{$spec{startup}}, 'c0d32.obj' )
  424.     unless ( $spec{starup} && @{$spec{startup}} );
  425.  
  426.   %spec = $self->write_linker_script(%spec)
  427.     if $spec{use_scripts};
  428.  
  429.   return [ grep {defined && length} (
  430.     $spec{ld}               ,
  431.     @{$spec{lddlflags}}     ,
  432.     @{$spec{libpath}}       ,
  433.     @{$spec{other_ldflags}} ,
  434.     @{$spec{startup}}       ,
  435.     @{$spec{objects}}       , ',',
  436.     $spec{output}           , ',',
  437.     $spec{map_file}         , ',',
  438.     $spec{libperl}          ,
  439.     @{$spec{perllibs}}      , ',',
  440.     $spec{def_file}
  441.   ) ];
  442. }
  443.  
  444. sub write_linker_script {
  445.   my ($self, %spec) = @_;
  446.  
  447.   # To work around Borlands "unique" commandline syntax,
  448.   # two scripts are used:
  449.  
  450.   my $ld_script = File::Spec->catfile( $spec{srcdir},
  451.                                        $spec{basename} . '.lds' );
  452.   my $ld_libs   = File::Spec->catfile( $spec{srcdir},
  453.                                        $spec{basename} . '.lbs' );
  454.  
  455.   $self->add_to_cleanup($ld_script, $ld_libs);
  456.  
  457.   print "Generating scripts '$ld_script' and '$ld_libs'.\n";
  458.  
  459.   # Script 1: contains options & names of object files.
  460.   open( LD_SCRIPT, ">$ld_script" )
  461.     or die( "Could not create linker script '$ld_script': $!" );
  462.  
  463.   print LD_SCRIPT join( " +\n",
  464.     map { @{$_} }
  465.     grep defined,
  466.     delete(
  467.       @spec{ qw(lddlflags libpath other_ldflags startup objects) } )
  468.   );
  469.  
  470.   close LD_SCRIPT;
  471.  
  472.   # Script 2: contains name of libs to link against.
  473.   open( LD_LIBS, ">$ld_libs" )
  474.     or die( "Could not create linker script '$ld_libs': $!" );
  475.  
  476.   print LD_LIBS join( " +\n",
  477.      (delete $spec{libperl}  || ''),
  478.     @{delete $spec{perllibs} || []},
  479.   );
  480.  
  481.   close LD_LIBS;
  482.  
  483.   push @{$spec{lddlflags}}, '@"' . $ld_script  . '"';
  484.   push @{$spec{perllibs}},  '@"' . $ld_libs    . '"';
  485.  
  486.   return %spec;
  487. }
  488.  
  489. 1;
  490.  
  491. ########################################################################
  492. package Module::Build::Platform::Windows::GCC;
  493.  
  494. sub format_compiler_cmd {
  495.   my ($self, %spec) = @_;
  496.  
  497.   foreach my $path ( @{ $spec{includes} || [] },
  498.                      @{ $spec{perlinc}  || [] } ) {
  499.     $path = '-I' . $path;
  500.   }
  501.  
  502.   return [ grep {defined && length} (
  503.     $spec{cc}, '-c'         ,
  504.     @{$spec{includes}}      ,
  505.     @{$spec{cflags}}        ,
  506.     @{$spec{optimize}}      ,
  507.     @{$spec{defines}}       ,
  508.     @{$spec{perlinc}}       ,
  509.     '-o', $spec{output}     ,
  510.     $spec{source}           ,
  511.   ) ];
  512. }
  513.  
  514. sub format_linker_cmd {
  515.   my ($self, %spec) = @_;
  516.  
  517.   # The Config.pm variable 'libperl' is hardcoded to the full name
  518.   # of the perl import library (i.e. 'libperl56.a'). GCC will not
  519.   # find it unless the 'lib' prefix & the extension are stripped.
  520.   $spec{libperl} =~ s/^(?:lib)?([^.]+).*$/-l$1/;
  521.  
  522.   unshift( @{$spec{other_ldflags}}, '-nostartfiles' )
  523.     if ( $spec{startup} && @{$spec{startup}} );
  524.  
  525.   # From ExtUtils::MM_Win32:
  526.   #
  527.   ## one thing for GCC/Mingw32:
  528.   ## we try to overcome non-relocateable-DLL problems by generating
  529.   ##    a (hopefully unique) image-base from the dll's name
  530.   ## -- BKS, 10-19-1999
  531.   File::Basename::basename( $spec{output} ) =~ /(....)(.{0,4})/;
  532.   $spec{image_base} = sprintf( "0x%x0000", unpack('n', $1 ^ $2) );
  533.  
  534.   %spec = $self->write_linker_script(%spec)
  535.     if $spec{use_scripts};
  536.  
  537.   foreach my $path ( @{$spec{libpath}} ) {
  538.     $path = "-L$path";
  539.   }
  540.  
  541.   my @cmds; # Stores the series of commands needed to build the module.
  542.  
  543.   push @cmds, [
  544.     'dlltool', '--def'        , $spec{def_file},
  545.                '--output-exp' , $spec{explib}
  546.   ];
  547.  
  548.   push @cmds, [ grep {defined && length} (
  549.     $spec{ld}                 ,
  550.     '-o', $spec{output}       ,
  551.     "-Wl,--base-file,$spec{base_file}"   ,
  552.     "-Wl,--image-base,$spec{image_base}" ,
  553.     @{$spec{lddlflags}}       ,
  554.     @{$spec{libpath}}         ,
  555.     @{$spec{startup}}         ,
  556.     @{$spec{objects}}         ,
  557.     @{$spec{other_ldflags}}   ,
  558.     $spec{libperl}            ,
  559.     @{$spec{perllibs}}        ,
  560.     $spec{explib}             ,
  561.     $spec{map_file} ? ('-Map', $spec{map_file}) : ''
  562.   ) ];
  563.  
  564.   push @cmds, [
  565.     'dlltool', '--def'        , $spec{def_file},
  566.                '--output-exp' , $spec{explib},
  567.                '--base-file'  , $spec{base_file}
  568.   ];
  569.  
  570.   push @cmds, [ grep {defined && length} (
  571.     $spec{ld}                 ,
  572.     '-o', $spec{output}       ,
  573.     "-Wl,--image-base,$spec{image_base}" ,
  574.     @{$spec{lddlflags}}       ,
  575.     @{$spec{libpath}}         ,
  576.     @{$spec{startup}}         ,
  577.     @{$spec{objects}}         ,
  578.     @{$spec{other_ldflags}}   ,
  579.     $spec{libperl}            ,
  580.     @{$spec{perllibs}}        ,
  581.     $spec{explib}             ,
  582.     $spec{map_file} ? ('-Map', $spec{map_file}) : ''
  583.   ) ];
  584.  
  585.   return @cmds;
  586. }
  587.  
  588. sub write_linker_script {
  589.   my ($self, %spec) = @_;
  590.  
  591.   my $script = File::Spec->catfile( $spec{srcdir},
  592.                                     $spec{basename} . '.lds' );
  593.  
  594.   $self->add_to_cleanup($script);
  595.  
  596.   print "Generating script '$script'\n";
  597.  
  598.   open( SCRIPT, ">$script" )
  599.     or die( "Could not create script '$script': $!" );
  600.  
  601.   print( SCRIPT 'SEARCH_DIR(' . $_ . ")\n" )
  602.     for @{delete $spec{libpath} || []};
  603.  
  604.   # gcc takes only one startup file, so the first object in startup is
  605.   # specified as the startup file and any others are shifted into the
  606.   # beginning of the list of objects.
  607.   if ( $spec{startup} && @{$spec{startup}} ) {
  608.     print SCRIPT 'STARTUP(' . shift( @{$spec{startup}} ) . ")\n";
  609.     unshift @{$spec{objects}},
  610.       @{delete $spec{startup} || []};
  611.   }
  612.  
  613.   print SCRIPT 'INPUT(' . join( ',',
  614.     @{delete $spec{objects}  || []}
  615.   ) . ")\n";
  616.  
  617.   print SCRIPT 'INPUT(' . join( ' ',
  618.      (delete $spec{libperl}  || ''),
  619.     @{delete $spec{perllibs} || []},
  620.   ) . ")\n";
  621.  
  622.   close SCRIPT;
  623.  
  624.   push @{$spec{other_ldflags}}, '"' . $script . '"';
  625.  
  626.   return %spec;
  627. }
  628.  
  629. 1;
  630.  
  631. __END__
  632.  
  633. =head1 NAME
  634.  
  635. Module::Build::Platform::Windows - Builder class for Windows platforms
  636.  
  637. =head1 DESCRIPTION
  638.  
  639. This module implements the Windows-specific parts of Module::Build.
  640. Most of the Windows-specific stuff has to do with compiling and
  641. linking C code.  Currently we support the 3 compilers perl itself
  642. supports: MSVC, BCC, and GCC.
  643.  
  644. This module inherits from C<Module::Build::Base>, so any functionality
  645. not implemented here will be implemented there.  The interfaces are
  646. defined by the L<Module::Build> documentation.
  647.  
  648. =head1 AUTHOR
  649.  
  650. Ken Williams <ken@mathforum.org>
  651.  
  652. Most of the code here was written by Randy W. Sims <RandyS@ThePierianSpring.org>.
  653.  
  654. =head1 SEE ALSO
  655.  
  656. perl(1), Module::Build(3), ExtUtils::MakeMaker(3)
  657.  
  658. =cut
  659.