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