summaryrefslogtreecommitdiff
path: root/klibc/klcc.in
diff options
context:
space:
mode:
Diffstat (limited to 'klibc/klcc.in')
-rw-r--r--klibc/klcc.in207
1 files changed, 207 insertions, 0 deletions
diff --git a/klibc/klcc.in b/klibc/klcc.in
new file mode 100644
index 0000000000..713843c37c
--- /dev/null
+++ b/klibc/klcc.in
@@ -0,0 +1,207 @@
+# -*- perl -*-
+
+# Standard includes
+@includes = ("-I${INSTALLDIR}/${CROSS}include/arch/${ARCH}",
+ "-I${INSTALLDIR}/${CROSS}include/bits${BITSIZE}",
+ "-I${INSTALLDIR}/${CROSS}include");
+
+# Default optimization options (for compiles without -g)
+@optopt = @OPTFLAGS;
+@goptopt = ('-O');
+
+# Options and libraries to pass to ld; shared versus static
+@staticopt = ("$INSTALLDIR/${CROSS}lib/crt0.o");
+@staticlib = ("$INSTALLDIR/${CROSS}lib/libc.a");
+@sharedopt = (@EMAIN, "$INSTALLDIR/${CROSS}lib/interp.o");
+@sharedlib = ('-R', "$INSTALLDIR/lib/${CROSS}libc.so");
+
+# Returns the language (-x option string) for a specific extension.
+sub filename2lang($) {
+ my ($file) = @_;
+
+ return 'c' if ( $file =~ /\.c$/ );
+ return 'c-header' if ( $file =~ /\.h$/ );
+ return 'cpp-output' if ( $file =~ /\.i$/ );
+ return 'c++-cpp-output' if ( $file =~ /\.ii$/ );
+ return 'objective-c' if ( $file =~ /\.m$/ );
+ return 'objc-cpp-output' if ( $file =~ /\.mi$/ );
+ return 'c++' if ( $file =~/\.(cc|cp|cxx|cpp|CPP|c\+\+|C)$/ );
+ return 'c++-header' if ( $file =~ /\.(hh|H)$/ );
+ return 'f77' if ( $file =~ /\.(f|for|FOR)$/ );
+ return 'f77-cpp-input' if ( $file =~ /\.(F|fpp|FPP)$/ );
+ return 'ratfor' if ( $file =~ /\.r$/ );
+
+ # Is this correct?
+ return 'ada' if ( $file =~ /\.(ads|adb)$/ );
+
+ return 'assembler' if ( $file =~ /\.s$/ );
+ return 'assembler-with-cpp' if ( $file =~/ \.S$/ );
+
+ # Linker file; there is no option to gcc to assume something
+ # is a linker file, so we make up our own...
+ return 'obj';
+}
+
+# Produces a series of -x options and files
+sub files_with_lang($$) {
+ my($files, $flang) = @_;
+ my(@as) = ();
+ my($xopt) = 'none';
+ my($need);
+
+ foreach $f ( @{$files} ) {
+ $need = ${$flang}{$f};
+ $need = 'none' if ( $need eq 'obj' );
+ unless ( $xopt eq $need ||
+ ($xopt eq 'none' && filename2lang($f) eq $need) ) {
+ push(@as, '-x', $need);
+ $xopt = $need;
+ }
+ push(@as, $f);
+ }
+
+ return @as;
+}
+
+# Convert a return value from system() to an exit() code
+sub syserr($) {
+ my($e) = @_;
+
+ return ($e & 0x7f) | 0x80 if ( $e & 0xff );
+ return $e >> 8;
+}
+
+# Run a program; printing out the command line if $verbose is set
+sub mysystem(@) {
+ print STDERR join(' ', @_), "\n" if ( $verbose );
+ return system(@_);
+}
+
+#
+# Begin parsing options.
+#
+
+@ccopt = ();
+@ldopt = ();
+
+@files = (); # List of files
+%flang = (); # Languages for files
+
+# This is 'c' for compile only, 'E' for preprocess only,
+# 'S' for compile to assembly.
+$operation = ''; # Compile and link
+
+# Current -x option. If undefined, it means autodetect.
+undef $lang;
+
+$save_temps = 0; # The -save-temps option
+$verbose = 0; # The -v option
+$shared = 0; # Are we compiling shared?
+$debugging = 0; # -g or -p option present?
+$strip = 0; # -s option present?
+undef $output; # -o option present?
+
+while ( defined($a = shift(@ARGV)) ) {
+ if ( $a !~ /^\-/ ) {
+ # Not an option. Must be a filename then.
+ push(@files, $a);
+ $flang{$a} = $lang || filename2lang($a);
+ } elsif ( $a =~ /^-Wl,(.*)$/ ) {
+ # -Wl used to pass options to the linker
+ push(@ldopt, split(/,/, $1));
+ } elsif ( $a =~ /^-([fmwWQdO]|std=|ansi|pedantic)/ ) {
+ # Options to gcc
+ push(@ccopt, $a);
+ } elsif ( $a =~ /^-([DUI])(.*)$/ ) {
+ # Options to gcc, which can take either a conjoined argument
+ # (-DFOO) or a disjoint argument (-D FOO)
+ push(@ccopt, $a);
+ push(@ccopt, shift(@ARGV)) if ( $2 eq '' );
+ } elsif ( $a eq '-include' ) {
+ # Options to gcc which always take a disjoint argument
+ push(@ccopt, $a, shift(@ARGV));
+ } elsif ( $a =~ /^-[gp]/ ) {
+ # Debugging options to gcc *and* ld
+ push(@ccopt, $a);
+ push(@ldopt, $a);
+ $debugging = 1;
+ } elsif ( $a eq '-v' ) {
+ push(@ccopt, $a);
+ $verbose = 1;
+ } elsif ( $a eq '-save-temps' ) {
+ push(@ccopt, $a);
+ $save_temps = 1;
+ } elsif ( $a =~ '^-([cSE])$' ) {
+ push(@ccopt, $a);
+ $operation = $1;
+ } elsif ( $a eq '-shared' ) {
+ $shared = 1;
+ } elsif ( $a eq '-static' ) {
+ $shared = 0;
+ } elsif ( $a eq '-s' ) {
+ $strip = 1;
+ } elsif ( $a eq '-o' ) {
+ $output = shift(@ARGV);
+ } elsif ( $a eq '-nostdinc' ) {
+ push(@ccopt, $a);
+ @includes = ();
+ } elsif ( $a =~ /^(-print|--help)/ ) {
+ # Pseudo-operations; just pass to gcc and don't do anything else
+ push(@ccopt, $a);
+ $operation = 'c' if ( $operation eq '' );
+ } else {
+ die "$0: unknown option: $a\n";
+ }
+}
+
+if ( $debugging ) {
+ @ccopt = (@REQFLAGS, @includes, @goptopt, @ccopt);
+} else {
+ @ccopt = (@REQFLAGS, @includes, @optopt, @ccopt);
+}
+
+if ( $operation ne '' ) {
+ # Just run gcc with the appropriate options
+ @outopt = ('-o', $output) if ( defined($output) );
+ $rv = mysystem($CC, @ccopt, @outopt, files_with_lang(\@files, \%flang));
+} else {
+ @outopt = ('-o', $output || 'a.out');
+
+ @objs = ();
+ @rmobjs = ();
+
+ foreach $f ( @files ) {
+ if ( $flang{$f} eq 'obj' ) {
+ push(@objs, $f);
+ } else {
+ $fo = $f;
+ $fo =~ s/\.[^\/.]+$/\.o/;
+
+ die if ( $f eq $fo ); # safety check
+
+ push(@objs, $fo);
+ push(@rmobjs, $fo) unless ( $save_temps );
+
+ $rv = mysystem($CC, @ccopt, '-c', '-o', $fo, '-x', $flang{$f}, $f);
+
+ if ( $rv ) {
+ unlink(@rmobjs);
+ exit syserr($rv);
+ }
+ }
+ }
+
+ if ( $shared ) {
+ $rv = mysystem($LD, @LDFLAGS, @sharedopt, @ldopt, @outopt, @objs, @sharedlib);
+ } else {
+ $rv = mysystem($LD, @LDFLAGS, @staticopt, @ldopt, @outopt, @objs, @staticlib);
+ }
+
+ unlink(@rmobjs);
+
+ if ( $strip && !$rv ) {
+ $rv = mysystem($STRIP, @STRIPFLAGS, $output);
+ }
+}
+
+exit syserr($rv);