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