1 package ExtUtils::CBuilder::Platform::Windows::GCC;
6 sub format_compiler_cmd {
7 my ($self, %spec) = @_;
9 foreach my $path ( @{ $spec{includes} || [] },
10 @{ $spec{perlinc} || [] } ) {
14 # split off any -arguments included in cc
15 my @cc = split / (?=-)/, $spec{cc};
17 return [ grep {defined && length} (
29 sub format_linker_cmd {
30 my ($self, %spec) = @_;
31 my $cf = $self->{config};
33 # The Config.pm variable 'libperl' is hardcoded to the full name
34 # of the perl import library (i.e. 'libperl56.a'). GCC will not
35 # find it unless the 'lib' prefix & the extension are stripped.
36 $spec{libperl} =~ s/^(?:lib)?([^.]+).*$/-l$1/;
38 unshift( @{$spec{other_ldflags}}, '-nostartfiles' )
39 if ( $spec{startup} && @{$spec{startup}} );
41 # From ExtUtils::MM_Win32:
43 ## one thing for GCC/Mingw32:
44 ## we try to overcome non-relocateable-DLL problems by generating
45 ## a (hopefully unique) image-base from the dll's name
47 File::Basename::basename( $spec{output} ) =~ /(....)(.{0,4})/;
48 $spec{image_base} = sprintf( "0x%x0000", unpack('n', $1 ^ $2) );
50 %spec = $self->write_linker_script(%spec)
51 if $spec{use_scripts};
53 foreach my $path ( @{$spec{libpath}} ) {
57 my @cmds; # Stores the series of commands needed to build the module.
59 my $DLLTOOL = $cf->{dlltool} || 'dlltool';
62 $DLLTOOL, '--def' , $spec{def_file},
63 '--output-exp' , $spec{explib}
66 # split off any -arguments included in ld
67 my @ld = split / (?=-)/, $spec{ld};
69 push @cmds, [ grep {defined && length} (
72 "-Wl,--base-file,$spec{base_file}" ,
73 "-Wl,--image-base,$spec{image_base}" ,
78 @{$spec{other_ldflags}} ,
82 $spec{map_file} ? ('-Map', $spec{map_file}) : ''
86 $DLLTOOL, '--def' , $spec{def_file},
87 '--output-exp' , $spec{explib},
88 '--base-file' , $spec{base_file}
91 push @cmds, [ grep {defined && length} (
94 "-Wl,--image-base,$spec{image_base}" ,
99 @{$spec{other_ldflags}} ,
103 $spec{map_file} ? ('-Map', $spec{map_file}) : ''
109 sub write_linker_script {
110 my ($self, %spec) = @_;
112 my $script = File::Spec->catfile( $spec{srcdir},
113 $spec{basename} . '.lds' );
115 $self->add_to_cleanup($script);
117 print "Generating script '$script'\n" if !$self->{quiet};
119 my $SCRIPT = IO::File->new( ">$script" )
120 or die( "Could not create script '$script': $!" );
122 print $SCRIPT ( 'SEARCH_DIR(' . $_ . ")\n" )
123 for @{delete $spec{libpath} || []};
125 # gcc takes only one startup file, so the first object in startup is
126 # specified as the startup file and any others are shifted into the
127 # beginning of the list of objects.
128 if ( $spec{startup} && @{$spec{startup}} ) {
129 print $SCRIPT 'STARTUP(' . shift( @{$spec{startup}} ) . ")\n";
130 unshift @{$spec{objects}},
131 @{delete $spec{startup} || []};
134 print $SCRIPT 'INPUT(' . join( ',',
135 @{delete $spec{objects} || []}
138 print $SCRIPT 'INPUT(' . join( ' ',
139 (delete $spec{libperl} || ''),
140 @{delete $spec{perllibs} || []},
143 #it is important to keep the order 1.linker_script - 2.other_ldflags
144 unshift @{$spec{other_ldflags}}, '"' . $script . '"';