[klibc] kbuild: move klcc to a klcc subdirectory

Sam Ravnborg sam at ravnborg.org
Thu Aug 4 14:08:17 PDT 2005


In a preparation to kbuildtify klibc move klcc down to a klcc subdirectory.
kbuild is used to build klcc, so started to add some kbuild definitions
to the top-level Makefile.

In klibc.config the old names are kept on the left-hand side. This was chosen
so we do not break compatibility with existing klcc users.

Signed-off-by: Sam Ravnborg <sam at ravnborg.org>

---
commit f2a3b9614dd9d426b01d92e0b795739db852b7a1
tree 2bf3dd24818d9e921a0255460ca185b877b9e827
parent 3346986f08271f35630e5c5b4b3af47eb8b874ab
author Sam Ravnborg <sam at mars.(none)> Thu, 04 Aug 2005 23:05:33 +0200
committer Sam Ravnborg <sam at mars.(none)> Thu, 04 Aug 2005 23:05:33 +0200

 Makefile             |   72 +++++++++-----
 klcc.1               |  116 ----------------------
 klcc.in              |  258 --------------------------------------------------
 klcc/Kbuild          |   32 ++++++
 klcc/klcc.1          |  116 ++++++++++++++++++++++
 klcc/klcc.in         |  258 ++++++++++++++++++++++++++++++++++++++++++++++++++
 klcc/makeklcc.pl     |   55 +++++++++++
 makeklcc.pl          |   55 -----------
 scripts/Kbuild.klibc |    4 +
 9 files changed, 512 insertions(+), 454 deletions(-)

diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,51 @@ VERSION := $(shell cat version)
 SUBDIRS = klibc ash ipconfig nfsmount utils kinit gzip
 SRCROOT = .
 
-all:
+# kbuild compatibility
+export srctree  := .
+export objtree  := .
+export KLIBCSRC := klibc
+export KLIBCINC := include
+export KLIBCOBJ := klibc
+
+export ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+
+# Location for installation
+export prefix      = /usr
+export bindir      = $(prefix)/bin
+export libdir      = $(prefix)/lib
+export mandir      = $(prefix)/man
+export INSTALLDIR  = $(prefix)/lib/klibc
+
+# Prefix Make commands wth $(Q) to silence them
+# Use quiet_cmd_xxx, cmd_xxx to create nice output
+# use make V=1 to get verbose output
+ifeq ($(KBUILD_VERBOSE),1)
+  quiet =
+  Q =
+else
+  quiet=quiet_
+  Q = @
+endif
+
+# If the user is running make -s (silent mode), suppress echoing of
+# commands
+
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+  quiet=silent_
+endif
+
+export quiet Q KBUILD_VERBOSE
+
+# Do not print "Entering directory ..."
+MAKEFLAGS += --no-print-directory
+
+# Shorthand to call Kbuild.klibc
+klibc := -f $(srctree)/scripts/Kbuild.klibc obj
+
+# Very first target
+.PHONY: klcc
+all: klcc
 
 rpmbuild = $(shell which rpmbuild 2>/dev/null || which rpm)
 
@@ -13,29 +57,9 @@ klibc.spec: klibc.spec.in version
 rpm: klibc.spec
 	+$(rpmbuild) -bb klibc.spec --target=$(ARCH)
 
-$(CROSS)klibc.config: Makefile
-	rm -f $@
-	echo 'ARCH=$(ARCH)' >> $@
-	echo 'CROSS=$(CROSS)' >> $@
-	echo 'KCROSS=$(KCROSS)' >> $@
-	echo 'CC=$(CC)' >> $@
-	echo 'LD=$(LD)' >> $@
-	echo 'REQFLAGS=$(filter-out -I%,$(REQFLAGS))' >> $@
-	echo 'OPTFLAGS=$(OPTFLAGS)' >> $@
-	echo 'LDFLAGS=$(LDFLAGS)' >> $@
-	echo 'STRIP=$(STRIP)' >> $@
-	echo 'STRIPFLAGS=$(STRIPFLAGS)' >> $@
-	echo 'EMAIN=$(EMAIN)' >> $@
-	echo 'BITSIZE=$(BITSIZE)' >> $@
-	echo 'prefix=$(INSTALLDIR)' >> $@
-	echo 'bindir=$(INSTALLDIR)/$(KCROSS)bin' >> $@
-	echo 'libdir=$(INSTALLDIR)/$(KCROSS)lib' >> $@
-	echo 'includedir=$(INSTALLDIR)/$(KCROSS)include' >> $@
-
-$(CROSS)klcc: klcc.in $(CROSS)klibc.config makeklcc.pl
-	$(PERL) makeklcc.pl klcc.in $(CROSS)klibc.config \
-		$(shell bash -c 'type -p $(PERL)') > $@ || ( rm -f $@ ; exit 1 )
-	chmod a+x $@
+# Build klcc - it is the first target
+klcc:
+	$(Q)$(MAKE) $(klibc)=klcc
 
 %: local-%
 	@set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done
diff --git a/klcc.1 b/klcc.1
deleted file mode 100644
--- a/klcc.1
+++ /dev/null
@@ -1,116 +0,0 @@
-.\" $Id: klcc.1,v 1.3 2005/04/19 23:27:46 hpa Exp $
-.\" -----------------------------------------------------------------------
-.\"   
-.\"   Copyright 2005 H. Peter Anvin - All Rights Reserved
-.\"
-.\"   Permission is hereby granted, free of charge, to any person
-.\"   obtaining a copy of this software and associated documentation
-.\"   files (the "Software"), to deal in the Software without
-.\"   restriction, including without limitation the rights to use,
-.\"   copy, modify, merge, publish, distribute, sublicense, and/or
-.\"   sell copies of the Software, and to permit persons to whom
-.\"   the Software is furnished to do so, subject to the following
-.\"   conditions:
-.\"   
-.\"   The above copyright notice and this permission notice shall
-.\"   be included in all copies or substantial portions of the Software.
-.\"   
-.\"   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-.\"   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-.\"   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-.\"   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-.\"   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-.\"   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-.\"   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-.\"   OTHER DEALINGS IN THE SOFTWARE.
-.\"
-.\" -----------------------------------------------------------------------
-
-.TH klcc "1" "1 March 2005" "klibc" "H. Peter Anvin"
-.SH NAME
-klcc \- compile a program against klibc
-.SH SYNOPSIS
-.B klcc
-[\fIgcc options\fP]
-[\fB\-o\fP \fIoutfile\fP]
-\fIinfile...\fP
-.SH DESCRIPTION
-.PP
-.B klcc
-is a wrapper around
-.BR gcc (1)
-and
-.BR ld (1)
-which compiles and links a program against the
-.B klibc
-tiny C library.  It supports most
-.B gcc
-options.
-.PP
-Unlike
-.BR gcc ,
-.B klcc
-compiles with optimization on by default.  Furthermore, the
-optimization level used depends on whether or not
-.B \-g
-is specified, since
-.B klcc
-frequently uses options in the normal case which makes debugging
-impossible.  Therefore, compile without
-.BR \-g ,
-.BR \-O ,
-.B \-f
-or
-.B \-m
-option to use the default optimization level; this will generally
-result in the smallest binaries.  You may want to use
-.B \-s
-when linking, however.  Use
-.B \-O0
-to compile without any optimization whatsoever; this may not work depending
-on the version of
-.B gcc
-used.
-.PP
-Use the
-.B \-shared
-or
-.B \-static
-option to compile for and link against shared or static klibc.  Note
-that shared klibc only supports running against the exact same klibc
-binary as the binary was linked with.
-.PP
-In addition to standard
-.B gcc
-options,
-.B klcc
-supports options of the form \fB\-print-klibc-\fP\fIoption\fP,
-which prints the corresponding klibc configuration option.
-.SH AUTHOR
-Written by H. Peter Anvin <hpa at zytor.com>.
-.SH COPYRIGHT
-Copyright \(co 2005 H. Peter Anvin \- All Rights Reserved
-.PP
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom
-the Software is furnished to do so, subject to the following
-conditions:
-.PP
-The above copyright notice and this permission notice shall
-be included in all copies or substantial portions of the Software.
-.PP
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-.SH "SEE ALSO"
-.BR gcc (1)
-
diff --git a/klcc.in b/klcc.in
deleted file mode 100644
--- a/klcc.in
+++ /dev/null
@@ -1,258 +0,0 @@
-# -*- perl -*-
-
-use IPC::Open3;
-
-# Standard includes
- at includes = ("-I${prefix}/${KCROSS}include/arch/${ARCH}",
-	     "-I${prefix}/${KCROSS}include/bits${BITSIZE}",
-	     "-I${prefix}/${KCROSS}include");
-
-# Default optimization options (for compiles without -g)
- at optopt =  @OPTFLAGS;
- at goptopt = ('-O');
-
-# Standard library directories
- at stdlibpath = ("-L${prefix}/${KCROSS}lib");
-
-# Options and libraries to pass to ld; shared versus static
- at staticopt = ("${prefix}/${KCROSS}lib/crt0.o");
- at staticlib = ("${prefix}/${KCROSS}lib/libc.a");
- at sharedopt = (@EMAIN, "${prefix}/${KCROSS}lib/interp.o");
- at sharedlib = ('-R', "${prefix}/${KCROSS}lib/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};
-
-	# Skip object files
-	if ( $need ne 'obj' ) {
-	    unless ( $xopt eq $need || $need eq 'stdin') {
-		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 );
-    my $cmd = shift;
-    open(INPUT, "<&STDIN");	# dup STDIN filehandle to INPUT
-    my $childpid = open3("<&INPUT", ">&STDOUT", ">&STDERR", $cmd, @_);
-    waitpid ($childpid, 0);
-    return $?;
-}
-
-#
-# Initialization
-# 
-open(NULL, '+<', '/dev/null') or die "$0: cannot open /dev/null\n";
-
-#
-# Begin parsing options.
-#
-
- at ccopt = ();
- at ldopt = ();
- at libs  = ();
-
- at 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 eq '-' ) {
-	# gcc gets its input from stdin
-	push(@files, $a);
-	# prevent setting -x
-	$flang{$a} = 'stdin'
-    } elsif ( $a =~ /^-print-klibc-(.*)$/ ) {
-	# This test must precede -print
-	if ( defined($conf{$1}) ) {
-	    print ${$conf{$1}}, "\n";
-	    exit 0;
-	} else {
-	    die "$0: unknown option: $a\n";
-	}
-    } elsif ( $a =~ /^(-print|-dump|--help|--version)/ ) {
-	# These share prefixes with some other options, so put this test early!
-	# Pseudo-operations; just pass to gcc and don't do anything else
-	push(@ccopt, $a);
-	$operation = 'c' if ( $operation eq '' );
-    } elsif ( $a =~ /^-Wl,(.*)$/ ) {
-	# -Wl used to pass options to the linker
-	push(@ldopt, split(/,/, $1));
-    } elsif ( $a =~ /^-([fmwWQdO]|std=|ansi|pedantic|M[GPD]|MMD)/ ) {
-	# Options to gcc
-	push(@ccopt, $a);
-    } elsif ( $a =~ /^-([DUI]|M[FQT])(.*)$/ ) {
-	# 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 eq '-M' || $a eq '-MM' ) {
-	# gcc options, that force preprocessing mode
-	push(@ccopt, $a);
-	$operation = 'E';
-    } elsif ( $a =~ /^-[gp]/ || $a eq '-p' ) {
-	# Debugging options to gcc
-	push(@ccopt, $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 '-x' ) {
-	$lang = shift(@ARGV);
-    } elsif ( $a eq '-nostdinc' ) {
-	push(@ccopt, $a);
-	@includes = ();
-    } elsif ( $a =~ /^-([lL])(.*)$/ ) {
-	# Libraries
-	push(@libs, $a);
-	push(@libs, shift(@ARGV)) if ( $2 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 {
-    if ( scalar(@files) == 0 ) {
-	die "$0: No input files!\n";
-    }
-
-    @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);
-	    }
-	}
-    }
-
-    # Get the libgcc pathname for the *current* gcc
-    open(LIBGCC, '-|', $CC, @ccopt, '-print-libgcc-file-name')
-	or die "$0: cannot get libgcc filename\n";
-    $libgcc = <LIBGCC>;
-    chomp $libgcc;
-    close(LIBGCC);
-
-    if ( $shared ) {
-	$rv = mysystem($LD, @LDFLAGS, @sharedopt, @ldopt, @outopt, @objs, @libs, @stdlibpath, @sharedlib, $libgcc);
-    } else {
-	$rv = mysystem($LD, @LDFLAGS, @staticopt, @ldopt, @outopt, @objs, @libs, @stdlibpath, @staticlib, $libgcc);
-    }
-
-    unlink(@rmobjs);
-
-    if ( $strip && !$rv ) {
-	$rv = mysystem($STRIP, @STRIPFLAGS, $output);
-    }
-}
-
-exit syserr($rv);
diff --git a/klcc/Kbuild b/klcc/Kbuild
new file mode 100644
--- /dev/null
+++ b/klcc/Kbuild
@@ -0,0 +1,32 @@
+#
+# Build klcc
+#
+
+always := $(KLIBCCROSS)klcc
+
+$(obj)/$(KLIBCCROSS)klibc.config: $(src)/Kbuild \
+				  $(srctree)/Makefile \
+                                  $(srctree)/scripts/Kbuild.klibc
+	rm -f $@
+	echo 'ARCH=$(ARCH)' >> $@
+	echo 'CROSS=$(KLIBCCROSS)' >> $@
+	echo 'KCROSS=$(KCROSS)' >> $@
+	echo 'CC=$(KLIBCCC)' >> $@
+	echo 'LD=$(KLIBCLD)' >> $@
+	echo 'REQFLAGS=$(filter-out -I%,$(KLIBCREQFLAGS))' >> $@
+	echo 'OPTFLAGS=$(KLIBCOPTFLAGS)' >> $@
+	echo 'LDFLAGS=$(KLIBCLDFLAGS)' >> $@
+	echo 'STRIP=$(KLIBCSTRIP)' >> $@
+	echo 'STRIPFLAGS=$(KLIBCSTRIPFLAGS)' >> $@
+	echo 'EMAIN=$(KLIBCEMAIN)' >> $@
+	echo 'BITSIZE=$(KLIBCBITSIZE)' >> $@
+	echo 'prefix=$(INSTALLDIR)' >> $@
+	echo 'bindir=$(INSTALLDIR)/$(KCROSS)bin' >> $@
+	echo 'libdir=$(INSTALLDIR)/$(KCROSS)lib' >> $@
+	echo 'includedir=$(INSTALLDIR)/$(KCROSS)include' >> $@
+
+$(obj)/$(KLIBCCROSS)klcc: $(src)/makeklcc.pl $(src)/klcc.in \
+                          $(obj)/$(KLIBCCROSS)klibc.config
+	$(PERL) $< $(srctree)/$(src)/klcc.in $(obj)/$(KLIBCCROSS)klibc.config \
+		$(shell bash -c 'type -p $(PERL)') > $@ || ( rm -f $@ ; exit 1 )
+	chmod a+x $@
diff --git a/klcc/klcc.1 b/klcc/klcc.1
new file mode 100644
--- /dev/null
+++ b/klcc/klcc.1
@@ -0,0 +1,116 @@
+.\" $Id: klcc.1,v 1.3 2005/04/19 23:27:46 hpa Exp $
+.\" -----------------------------------------------------------------------
+.\"   
+.\"   Copyright 2005 H. Peter Anvin - All Rights Reserved
+.\"
+.\"   Permission is hereby granted, free of charge, to any person
+.\"   obtaining a copy of this software and associated documentation
+.\"   files (the "Software"), to deal in the Software without
+.\"   restriction, including without limitation the rights to use,
+.\"   copy, modify, merge, publish, distribute, sublicense, and/or
+.\"   sell copies of the Software, and to permit persons to whom
+.\"   the Software is furnished to do so, subject to the following
+.\"   conditions:
+.\"   
+.\"   The above copyright notice and this permission notice shall
+.\"   be included in all copies or substantial portions of the Software.
+.\"   
+.\"   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+.\"   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+.\"   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+.\"   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+.\"   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+.\"   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+.\"   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\"   OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" -----------------------------------------------------------------------
+
+.TH klcc "1" "1 March 2005" "klibc" "H. Peter Anvin"
+.SH NAME
+klcc \- compile a program against klibc
+.SH SYNOPSIS
+.B klcc
+[\fIgcc options\fP]
+[\fB\-o\fP \fIoutfile\fP]
+\fIinfile...\fP
+.SH DESCRIPTION
+.PP
+.B klcc
+is a wrapper around
+.BR gcc (1)
+and
+.BR ld (1)
+which compiles and links a program against the
+.B klibc
+tiny C library.  It supports most
+.B gcc
+options.
+.PP
+Unlike
+.BR gcc ,
+.B klcc
+compiles with optimization on by default.  Furthermore, the
+optimization level used depends on whether or not
+.B \-g
+is specified, since
+.B klcc
+frequently uses options in the normal case which makes debugging
+impossible.  Therefore, compile without
+.BR \-g ,
+.BR \-O ,
+.B \-f
+or
+.B \-m
+option to use the default optimization level; this will generally
+result in the smallest binaries.  You may want to use
+.B \-s
+when linking, however.  Use
+.B \-O0
+to compile without any optimization whatsoever; this may not work depending
+on the version of
+.B gcc
+used.
+.PP
+Use the
+.B \-shared
+or
+.B \-static
+option to compile for and link against shared or static klibc.  Note
+that shared klibc only supports running against the exact same klibc
+binary as the binary was linked with.
+.PP
+In addition to standard
+.B gcc
+options,
+.B klcc
+supports options of the form \fB\-print-klibc-\fP\fIoption\fP,
+which prints the corresponding klibc configuration option.
+.SH AUTHOR
+Written by H. Peter Anvin <hpa at zytor.com>.
+.SH COPYRIGHT
+Copyright \(co 2005 H. Peter Anvin \- All Rights Reserved
+.PP
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following
+conditions:
+.PP
+The above copyright notice and this permission notice shall
+be included in all copies or substantial portions of the Software.
+.PP
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+.SH "SEE ALSO"
+.BR gcc (1)
+
diff --git a/klcc/klcc.in b/klcc/klcc.in
new file mode 100644
--- /dev/null
+++ b/klcc/klcc.in
@@ -0,0 +1,258 @@
+# -*- perl -*-
+
+use IPC::Open3;
+
+# Standard includes
+ at includes = ("-I${prefix}/${KCROSS}include/arch/${ARCH}",
+	     "-I${prefix}/${KCROSS}include/bits${BITSIZE}",
+	     "-I${prefix}/${KCROSS}include");
+
+# Default optimization options (for compiles without -g)
+ at optopt =  @OPTFLAGS;
+ at goptopt = ('-O');
+
+# Standard library directories
+ at stdlibpath = ("-L${prefix}/${KCROSS}lib");
+
+# Options and libraries to pass to ld; shared versus static
+ at staticopt = ("${prefix}/${KCROSS}lib/crt0.o");
+ at staticlib = ("${prefix}/${KCROSS}lib/libc.a");
+ at sharedopt = (@EMAIN, "${prefix}/${KCROSS}lib/interp.o");
+ at sharedlib = ('-R', "${prefix}/${KCROSS}lib/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};
+
+	# Skip object files
+	if ( $need ne 'obj' ) {
+	    unless ( $xopt eq $need || $need eq 'stdin') {
+		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 );
+    my $cmd = shift;
+    open(INPUT, "<&STDIN");	# dup STDIN filehandle to INPUT
+    my $childpid = open3("<&INPUT", ">&STDOUT", ">&STDERR", $cmd, @_);
+    waitpid ($childpid, 0);
+    return $?;
+}
+
+#
+# Initialization
+# 
+open(NULL, '+<', '/dev/null') or die "$0: cannot open /dev/null\n";
+
+#
+# Begin parsing options.
+#
+
+ at ccopt = ();
+ at ldopt = ();
+ at libs  = ();
+
+ at 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 eq '-' ) {
+	# gcc gets its input from stdin
+	push(@files, $a);
+	# prevent setting -x
+	$flang{$a} = 'stdin'
+    } elsif ( $a =~ /^-print-klibc-(.*)$/ ) {
+	# This test must precede -print
+	if ( defined($conf{$1}) ) {
+	    print ${$conf{$1}}, "\n";
+	    exit 0;
+	} else {
+	    die "$0: unknown option: $a\n";
+	}
+    } elsif ( $a =~ /^(-print|-dump|--help|--version)/ ) {
+	# These share prefixes with some other options, so put this test early!
+	# Pseudo-operations; just pass to gcc and don't do anything else
+	push(@ccopt, $a);
+	$operation = 'c' if ( $operation eq '' );
+    } elsif ( $a =~ /^-Wl,(.*)$/ ) {
+	# -Wl used to pass options to the linker
+	push(@ldopt, split(/,/, $1));
+    } elsif ( $a =~ /^-([fmwWQdO]|std=|ansi|pedantic|M[GPD]|MMD)/ ) {
+	# Options to gcc
+	push(@ccopt, $a);
+    } elsif ( $a =~ /^-([DUI]|M[FQT])(.*)$/ ) {
+	# 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 eq '-M' || $a eq '-MM' ) {
+	# gcc options, that force preprocessing mode
+	push(@ccopt, $a);
+	$operation = 'E';
+    } elsif ( $a =~ /^-[gp]/ || $a eq '-p' ) {
+	# Debugging options to gcc
+	push(@ccopt, $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 '-x' ) {
+	$lang = shift(@ARGV);
+    } elsif ( $a eq '-nostdinc' ) {
+	push(@ccopt, $a);
+	@includes = ();
+    } elsif ( $a =~ /^-([lL])(.*)$/ ) {
+	# Libraries
+	push(@libs, $a);
+	push(@libs, shift(@ARGV)) if ( $2 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 {
+    if ( scalar(@files) == 0 ) {
+	die "$0: No input files!\n";
+    }
+
+    @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);
+	    }
+	}
+    }
+
+    # Get the libgcc pathname for the *current* gcc
+    open(LIBGCC, '-|', $CC, @ccopt, '-print-libgcc-file-name')
+	or die "$0: cannot get libgcc filename\n";
+    $libgcc = <LIBGCC>;
+    chomp $libgcc;
+    close(LIBGCC);
+
+    if ( $shared ) {
+	$rv = mysystem($LD, @LDFLAGS, @sharedopt, @ldopt, @outopt, @objs, @libs, @stdlibpath, @sharedlib, $libgcc);
+    } else {
+	$rv = mysystem($LD, @LDFLAGS, @staticopt, @ldopt, @outopt, @objs, @libs, @stdlibpath, @staticlib, $libgcc);
+    }
+
+    unlink(@rmobjs);
+
+    if ( $strip && !$rv ) {
+	$rv = mysystem($STRIP, @STRIPFLAGS, $output);
+    }
+}
+
+exit syserr($rv);
diff --git a/klcc/makeklcc.pl b/klcc/makeklcc.pl
new file mode 100755
--- /dev/null
+++ b/klcc/makeklcc.pl
@@ -0,0 +1,55 @@
+#!/usr/bin/perl
+#
+# Combine klibc.config, klcc.in to produce a klcc script
+#
+# Usage: makeklcc klcc.in klibc.config perlpath
+#
+
+use File::Spec;
+
+($klccin, $klibcconf, $perlpath) = @ARGV;
+
+sub pathsearch($) {
+    my($file) = @_;
+    my(@path);
+    my($p,$pp);
+
+    if ( $file =~ /\// ) {
+	return File::Spec->rel2abs($file);
+    }
+    
+    foreach $p ( split(/\:/, $ENV{'PATH'}) ) {
+	$pp = File::Spec->rel2abs(File::Spec->catpath(undef, $p, $file));
+	return $pp if ( -x $pp );
+    }
+
+    return undef;
+}
+
+print "#!${perlpath}\n";
+
+open(KLIBCCONF, '<', $klibcconf) or die "$0: cannot open $klibcconf: $!\n";
+while ( defined($l = <KLIBCCONF>) ) {
+    chomp $l;
+    if ( $l =~ /^([^=]+)\=(.*)$/ ) {
+	$n = $1;  $s = $2;
+
+	if ( $n eq 'CC' || $n eq 'LD' || $n eq 'STRIP' ) {
+	    $s1 = pathsearch($s);
+	    die "$0: Cannot find $n: $s\n" unless ( defined($s1) );
+	    $s = $s1;
+	}
+
+	print "\$$n = \"\Q$s\E\";\n";
+	print "\@$n = qw($s);\n";
+	print "\$conf{\'\L$n\E\'} = \\\$$n;\n";
+    }
+}
+close(KLIBCCONF);
+
+open(KLCCIN, '<', $klccin) or die "$0: cannot open $klccin: $!\n";
+while ( defined($l = <KLCCIN>) ) {
+    print $l;
+}
+close(KLCCIN);
+
diff --git a/makeklcc.pl b/makeklcc.pl
deleted file mode 100755
--- a/makeklcc.pl
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/perl
-#
-# Combine klibc.config, klcc.in to produce a klcc script
-#
-# Usage: makeklcc klcc.in klibc.config perlpath
-#
-
-use File::Spec;
-
-($klccin, $klibcconf, $perlpath) = @ARGV;
-
-sub pathsearch($) {
-    my($file) = @_;
-    my(@path);
-    my($p,$pp);
-
-    if ( $file =~ /\// ) {
-	return File::Spec->rel2abs($file);
-    }
-    
-    foreach $p ( split(/\:/, $ENV{'PATH'}) ) {
-	$pp = File::Spec->rel2abs(File::Spec->catpath(undef, $p, $file));
-	return $pp if ( -x $pp );
-    }
-
-    return undef;
-}
-
-print "#!${perlpath}\n";
-
-open(KLIBCCONF, '<', $klibcconf) or die "$0: cannot open $klibcconf: $!\n";
-while ( defined($l = <KLIBCCONF>) ) {
-    chomp $l;
-    if ( $l =~ /^([^=]+)\=(.*)$/ ) {
-	$n = $1;  $s = $2;
-
-	if ( $n eq 'CC' || $n eq 'LD' || $n eq 'STRIP' ) {
-	    $s1 = pathsearch($s);
-	    die "$0: Cannot find $n: $s\n" unless ( defined($s1) );
-	    $s = $s1;
-	}
-
-	print "\$$n = \"\Q$s\E\";\n";
-	print "\@$n = qw($s);\n";
-	print "\$conf{\'\L$n\E\'} = \\\$$n;\n";
-    }
-}
-close(KLIBCCONF);
-
-open(KLCCIN, '<', $klccin) or die "$0: cannot open $klccin: $!\n";
-while ( defined($l = <KLCCIN>) ) {
-    print $l;
-}
-close(KLCCIN);
-
diff --git a/scripts/Kbuild.klibc b/scripts/Kbuild.klibc
--- a/scripts/Kbuild.klibc
+++ b/scripts/Kbuild.klibc
@@ -51,6 +51,7 @@ KLIBCOPTFLAGS     :=
 KLIBCWARNFLAGS    := -W -Wall -Wno-sign-compare
 KLIBCSHAREDFLAGS  := 
 KLIBCBITSIZE      :=
+KLIBCLDFLAGS      :=
 
 # Arch specific definitions for klibc
 include $(KLIBCSRC)/arch/$(ARCH)/MCONFIG
@@ -62,9 +63,10 @@ KLIBCOPTFLAGS     += $(OPTFLAGS)
 KLIBCWARNFLAGS    += $(WARNFLAGS) -W -Wall -Wno-sign-compare
 KLIBCSHAREDFLAGS  += $(SHAREDFLAGS)
 KLIBCBITSIZE      := $(strip $(KLIBCBITSIZE) $(BITSIZE))
-
+KLIBCLDFLAGS      += $(LDFLAGS)
 KLIBCROSS        := $(CROSS_COMPILE)
 
+# binutils
 KLIBCLD          := $(KLIBCROSS)ld
 KLIBCCC          := $(KLIBCROSS)gcc
 KLIBCAR          := $(KLIBCROSS)ar



More information about the klibc mailing list