xref: /openbsd-src/gnu/usr.bin/perl/dist/ExtUtils-CBuilder/lib/ExtUtils/CBuilder/Platform/Windows/GCC.pm (revision 3d61058aa5c692477b6d18acfbbdb653a9930ff9)
1package ExtUtils::CBuilder::Platform::Windows::GCC;
2
3our $VERSION = '0.280240'; # VERSION
4
5use warnings;
6use strict;
7
8sub format_compiler_cmd {
9  my ($self, %spec) = @_;
10
11  foreach my $path ( @{ $spec{includes} || [] },
12                     @{ $spec{perlinc}  || [] } ) {
13    $path = '-I' . $path;
14  }
15
16  # split off any -arguments included in cc
17  my @cc = split / (?=-)/, $spec{cc};
18
19  return [ grep {defined && length} (
20    @cc, '-c'               ,
21    @{$spec{includes}}      ,
22    @{$spec{cflags}}        ,
23    @{$spec{optimize}}      ,
24    @{$spec{defines}}       ,
25    @{$spec{perlinc}}       ,
26    '-o', $spec{output}     ,
27    $spec{source}           ,
28  ) ];
29}
30
31sub format_linker_cmd {
32  my ($self, %spec) = @_;
33  my $cf = $self->{config};
34
35  # The Config.pm variable 'libperl' is hardcoded to the full name
36  # of the perl import library (i.e. 'libperl56.a'). GCC will not
37  # find it unless the 'lib' prefix & the extension are stripped.
38  $spec{libperl} =~ s/^(?:lib)?([^.]+).*$/-l$1/;
39
40  unshift( @{$spec{other_ldflags}}, '-nostartfiles' )
41    if ( $spec{startup} && @{$spec{startup}} );
42
43  %spec = $self->write_linker_script(%spec)
44    if $spec{use_scripts};
45
46  foreach my $path ( @{$spec{libpath}} ) {
47    $path = "-L$path";
48  }
49
50  # split off any -arguments included in ld
51  my @ld = split / (?=-)/, $spec{ld};
52
53  return [ grep {defined && length} (
54    @ld                       ,
55    $spec{def_file}           ,
56    '-o', $spec{output}       ,
57    "-Wl,--enable-auto-image-base" ,
58    @{$spec{lddlflags}}       ,
59    @{$spec{libpath}}         ,
60    @{$spec{startup}}         ,
61    @{$spec{objects}}         ,
62    @{$spec{other_ldflags}}   ,
63    $spec{libperl}            ,
64    @{$spec{perllibs}}        ,
65    $spec{map_file} ? ('-Map', $spec{map_file}) : ''
66  ) ];
67}
68
69sub write_linker_script {
70  my ($self, %spec) = @_;
71
72  my $script = File::Spec->catfile( $spec{srcdir},
73                                    $spec{basename} . '.lds' );
74
75  $self->add_to_cleanup($script);
76
77  print "Generating script '$script'\n" if !$self->{quiet};
78
79  my $SCRIPT = IO::File->new( ">$script" )
80    or die( "Could not create script '$script': $!" );
81
82  print $SCRIPT ( 'SEARCH_DIR(' . $_ . ")\n" )
83    for @{delete $spec{libpath} || []};
84
85  # gcc takes only one startup file, so the first object in startup is
86  # specified as the startup file and any others are shifted into the
87  # beginning of the list of objects.
88  if ( $spec{startup} && @{$spec{startup}} ) {
89    print $SCRIPT 'STARTUP(' . shift( @{$spec{startup}} ) . ")\n";
90    unshift @{$spec{objects}},
91      @{delete $spec{startup} || []};
92  }
93
94  print $SCRIPT 'INPUT(' . join( ',',
95    @{delete $spec{objects}  || []}
96  ) . ")\n";
97
98  print $SCRIPT 'INPUT(' . join( ' ',
99     (delete $spec{libperl}  || ''),
100    @{delete $spec{perllibs} || []},
101  ) . ")\n";
102
103  #it is important to keep the order 1.linker_script - 2.other_ldflags
104  unshift @{$spec{other_ldflags}}, '"' . $script . '"';
105
106  return %spec;
107}
108
1091;
110
111
112