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