Contents of /tags/mkinitrd-6_1_8/klibc/klcc/klcc.in
Parent Directory | Revision Log
Revision 916 -
(show annotations)
(download)
Wed Oct 28 00:17:50 2009 UTC (14 years, 11 months ago) by niro
File size: 7158 byte(s)
Wed Oct 28 00:17:50 2009 UTC (14 years, 11 months ago) by niro
File size: 7158 byte(s)
tagged 'mkinitrd-6_1_8'
1 | # -*- perl -*- |
2 | |
3 | use IPC::Open3; |
4 | |
5 | # Standard includes |
6 | @includes = ("-I${prefix}/${KCROSS}include/arch/${ARCH}", |
7 | "-I${prefix}/${KCROSS}include/bits${BITSIZE}", |
8 | "-I${prefix}/${KCROSS}include"); |
9 | |
10 | # Default optimization options (for compiles without -g) |
11 | @optopt = @OPTFLAGS; |
12 | @goptopt = ('-O'); |
13 | |
14 | # Standard library directories |
15 | @stdlibpath = ("-L${prefix}/${KCROSS}lib"); |
16 | |
17 | # Options and libraries to pass to ld; shared versus static |
18 | @staticopt = ("${prefix}/${KCROSS}lib/crt0.o"); |
19 | @staticlib = ("${prefix}/${KCROSS}lib/libc.a"); |
20 | @sharedopt = (@EMAIN, "${prefix}/${KCROSS}lib/interp.o"); |
21 | @sharedlib = ('-R', "${prefix}/${KCROSS}lib/libc.so"); |
22 | |
23 | # Returns the language (-x option string) for a specific extension. |
24 | sub filename2lang($) { |
25 | my ($file) = @_; |
26 | |
27 | return 'c' if ( $file =~ /\.c$/ ); |
28 | return 'c-header' if ( $file =~ /\.h$/ ); |
29 | return 'cpp-output' if ( $file =~ /\.i$/ ); |
30 | return 'c++-cpp-output' if ( $file =~ /\.ii$/ ); |
31 | return 'objective-c' if ( $file =~ /\.m$/ ); |
32 | return 'objc-cpp-output' if ( $file =~ /\.mi$/ ); |
33 | return 'c++' if ( $file =~/\.(cc|cp|cxx|cpp|CPP|c\+\+|C)$/ ); |
34 | return 'c++-header' if ( $file =~ /\.(hh|H)$/ ); |
35 | return 'f77' if ( $file =~ /\.(f|for|FOR)$/ ); |
36 | return 'f77-cpp-input' if ( $file =~ /\.(F|fpp|FPP)$/ ); |
37 | return 'ratfor' if ( $file =~ /\.r$/ ); |
38 | |
39 | # Is this correct? |
40 | return 'ada' if ( $file =~ /\.(ads|adb)$/ ); |
41 | |
42 | return 'assembler' if ( $file =~ /\.s$/ ); |
43 | return 'assembler-with-cpp' if ( $file =~/\.S$/ ); |
44 | |
45 | # Linker file; there is no option to gcc to assume something |
46 | # is a linker file, so we make up our own... |
47 | return 'obj'; |
48 | } |
49 | |
50 | # Produces a series of -x options and files |
51 | sub files_with_lang($$) { |
52 | my($files, $flang) = @_; |
53 | my(@as) = (); |
54 | my($xopt) = 'none'; |
55 | my($need); |
56 | |
57 | foreach $f ( @{$files} ) { |
58 | $need = ${$flang}{$f}; |
59 | |
60 | # Skip object files |
61 | if ( $need ne 'obj' ) { |
62 | unless ( $xopt eq $need || $need eq 'stdin') { |
63 | push(@as, '-x', $need); |
64 | $xopt = $need; |
65 | } |
66 | push(@as, $f); |
67 | } |
68 | } |
69 | |
70 | return @as; |
71 | } |
72 | |
73 | # Convert a return value from system() to an exit() code |
74 | sub syserr($) { |
75 | my($e) = @_; |
76 | |
77 | return ($e & 0x7f) | 0x80 if ( $e & 0xff ); |
78 | return $e >> 8; |
79 | } |
80 | |
81 | # Run a program; printing out the command line if $verbose is set |
82 | sub mysystem(@) { |
83 | print STDERR join(' ', @_), "\n" if ( $verbose ); |
84 | my $cmd = shift; |
85 | open(INPUT, "<&STDIN"); # dup STDIN filehandle to INPUT |
86 | my $childpid = open3("<&INPUT", ">&STDOUT", ">&STDERR", $cmd, @_); |
87 | waitpid ($childpid, 0); |
88 | return $?; |
89 | } |
90 | |
91 | # |
92 | # Initialization |
93 | # |
94 | open(NULL, '+<', '/dev/null') or die "$0: cannot open /dev/null\n"; |
95 | |
96 | # |
97 | # Begin parsing options. |
98 | # |
99 | |
100 | @ccopt = (); |
101 | @ldopt = (); |
102 | @libs = (); |
103 | |
104 | @files = (); # List of files |
105 | %flang = (); # Languages for files |
106 | |
107 | # This is 'c' for compile only, 'E' for preprocess only, |
108 | # 'S' for compile to assembly. |
109 | $operation = ''; # Compile and link |
110 | |
111 | # Current -x option. If undefined, it means autodetect. |
112 | undef $lang; |
113 | |
114 | $save_temps = 0; # The -save-temps option |
115 | $verbose = 0; # The -v option |
116 | $shared = 0; # Are we compiling shared? |
117 | $debugging = 0; # -g or -p option present? |
118 | $strip = 0; # -s option present? |
119 | undef $output; # -o option present? |
120 | |
121 | while ( defined($a = shift(@ARGV)) ) { |
122 | if ( $a !~ /^\-/ ) { |
123 | # Not an option. Must be a filename then. |
124 | push(@files, $a); |
125 | $flang{$a} = $lang || filename2lang($a); |
126 | } elsif ( $a eq '-' ) { |
127 | # gcc gets its input from stdin |
128 | push(@files, $a); |
129 | # prevent setting -x |
130 | $flang{$a} = 'stdin' |
131 | } elsif ( $a =~ /^-print-klibc-(.*)$/ ) { |
132 | # This test must precede -print |
133 | if ( defined($conf{$1}) ) { |
134 | print ${$conf{$1}}, "\n"; |
135 | exit 0; |
136 | } else { |
137 | die "$0: unknown option: $a\n"; |
138 | } |
139 | } elsif ( $a =~ /^(-print|-dump|--help|--version)/ ) { |
140 | # These share prefixes with some other options, so put this test early! |
141 | # Pseudo-operations; just pass to gcc and don't do anything else |
142 | push(@ccopt, $a); |
143 | $operation = 'c' if ( $operation eq '' ); |
144 | } elsif ( $a =~ /^-Wl,(.*)$/ ) { |
145 | # -Wl used to pass options to the linker |
146 | push(@ldopt, split(/,/, $1)); |
147 | } elsif ( $a =~ /^-([fmwWQdO]|std=|ansi|pedantic|M[GPD]|MMD)/ ) { |
148 | # Options to gcc |
149 | push(@ccopt, $a); |
150 | } elsif ( $a =~ /^-([DUI]|M[FQT])(.*)$/ ) { |
151 | # Options to gcc, which can take either a conjoined argument |
152 | # (-DFOO) or a disjoint argument (-D FOO) |
153 | push(@ccopt, $a); |
154 | push(@ccopt, shift(@ARGV)) if ( $2 eq '' ); |
155 | } elsif ( $a eq '-include' ) { |
156 | # Options to gcc which always take a disjoint argument |
157 | push(@ccopt, $a, shift(@ARGV)); |
158 | } elsif ( $a eq '-M' || $a eq '-MM' ) { |
159 | # gcc options, that force preprocessing mode |
160 | push(@ccopt, $a); |
161 | $operation = 'E'; |
162 | } elsif ( $a =~ /^-[gp]/ || $a eq '-p' ) { |
163 | # Debugging options to gcc |
164 | push(@ccopt, $a); |
165 | $debugging = 1; |
166 | } elsif ( $a eq '-v' ) { |
167 | push(@ccopt, $a); |
168 | $verbose = 1; |
169 | } elsif ( $a eq '-save-temps' ) { |
170 | push(@ccopt, $a); |
171 | $save_temps = 1; |
172 | } elsif ( $a =~ '^-([cSE])$' ) { |
173 | push(@ccopt, $a); |
174 | $operation = $1; |
175 | } elsif ( $a eq '-shared' ) { |
176 | $shared = 1; |
177 | } elsif ( $a eq '-static' ) { |
178 | $shared = 0; |
179 | } elsif ( $a eq '-s' ) { |
180 | $strip = 1; |
181 | } elsif ( $a eq '-o' ) { |
182 | $output = shift(@ARGV); |
183 | } elsif ( $a =~ /^\-x(.*)$/ ) { |
184 | # -x can be conjoined or disjoined |
185 | $lang = $1; |
186 | if ( $lang eq '' ) { |
187 | $lang = shift(@ARGV); |
188 | } |
189 | } elsif ( $a eq '-nostdinc' ) { |
190 | push(@ccopt, $a); |
191 | @includes = (); |
192 | } elsif ( $a =~ /^-([lL])(.*)$/ ) { |
193 | # Libraries |
194 | push(@libs, $a); |
195 | push(@libs, shift(@ARGV)) if ( $2 eq '' ); |
196 | } else { |
197 | die "$0: unknown option: $a\n"; |
198 | } |
199 | } |
200 | |
201 | if ( $debugging ) { |
202 | @ccopt = (@REQFLAGS, @includes, @goptopt, @ccopt); |
203 | } else { |
204 | @ccopt = (@REQFLAGS, @includes, @optopt, @ccopt); |
205 | } |
206 | |
207 | if ( $operation ne '' ) { |
208 | # Just run gcc with the appropriate options |
209 | @outopt = ('-o', $output) if ( defined($output) ); |
210 | $rv = mysystem($CC, @ccopt, @outopt, files_with_lang(\@files, \%flang)); |
211 | } else { |
212 | if ( scalar(@files) == 0 ) { |
213 | die "$0: No input files!\n"; |
214 | } |
215 | |
216 | @outopt = ('-o', $output || 'a.out'); |
217 | |
218 | @objs = (); |
219 | @rmobjs = (); |
220 | |
221 | foreach $f ( @files ) { |
222 | if ( $flang{$f} eq 'obj' ) { |
223 | push(@objs, $f); |
224 | } else { |
225 | $fo = $f; |
226 | $fo =~ s/\.[^\/.]+$/\.o/; |
227 | |
228 | die if ( $f eq $fo ); # safety check |
229 | |
230 | push(@objs, $fo); |
231 | push(@rmobjs, $fo) unless ( $save_temps ); |
232 | |
233 | $rv = mysystem($CC, @ccopt, '-c', '-o', $fo, '-x', $flang{$f}, $f); |
234 | |
235 | if ( $rv ) { |
236 | unlink(@rmobjs); |
237 | exit syserr($rv); |
238 | } |
239 | } |
240 | } |
241 | |
242 | # Get the libgcc pathname for the *current* gcc |
243 | open(LIBGCC, '-|', $CC, @ccopt, '-print-libgcc-file-name') |
244 | or die "$0: cannot get libgcc filename\n"; |
245 | $libgcc = <LIBGCC>; |
246 | chomp $libgcc; |
247 | close(LIBGCC); |
248 | |
249 | if ( $shared ) { |
250 | $rv = mysystem($LD, @LDFLAGS, @sharedopt, @ldopt, @outopt, @objs, |
251 | @libs, @stdlibpath, '--start-group', @sharedlib, |
252 | $libgcc, '--end-group'); |
253 | } else { |
254 | $rv = mysystem($LD, @LDFLAGS, @staticopt, @ldopt, @outopt, @objs, |
255 | @libs, @stdlibpath, '--start-group', @staticlib, |
256 | $libgcc, '--end-group'); |
257 | } |
258 | |
259 | unlink(@rmobjs); |
260 | |
261 | if ( $strip && !$rv ) { |
262 | $rv = mysystem($STRIP, @STRIPFLAGS, $output); |
263 | } |
264 | } |
265 | |
266 | exit syserr($rv); |