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