Autoconstipate the build setup, and generate dependencies.
authorH. Peter Anvin <hpa@zytor.com>
Fri, 11 Jan 2008 03:41:03 +0000 (19:41 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Fri, 11 Jan 2008 03:45:30 +0000 (19:45 -0800)
Add autoconstipation framework (from mkzfree) and dependency
generation (from nasm).

12 files changed:
MCONFIG.in [new file with mode: 0644]
Makefile
aclocal.m4 [new file with mode: 0644]
configure.in [new file with mode: 0644]
elf.c
mapfile.c
mkdep.pl [new file with mode: 0755]
nbi.c
reloc/reloc_linux.c
segment.c
wraplinux.h
xmalloc.c

diff --git a/MCONFIG.in b/MCONFIG.in
new file mode 100644 (file)
index 0000000..d46ca5d
--- /dev/null
@@ -0,0 +1,13 @@
+CC                     = @CC@
+CFLAGS                 = @CFLAGS@
+LDFLAGS                        = @LDFLAGS@
+
+SED                    = @SED@
+PERL                   = perl
+
+CC_FOR_TARGET          = gcc -m32
+LD_FOR_TARGET          = ld -m elf_i386
+OBJCOPY_FOR_TARGET     = objcopy
+CFLAGS_FOR_TARGET      = -I. -g -Os -march=i386 -mregparm=3 \
+                         -fPIC -ffreestanding
+LDFLAGS_FOR_TARGET     =
index ecc2fa3..cba6b3d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,4 @@
-CC                     = gcc
-CFLAGS                 = -g -O2 -W -Wall -D_GNU_SOURCE
-LDFLAGS                        =
-
-CC_FOR_TARGET          = gcc -m32
-LD_FOR_TARGET          = ld -m elf_i386
-OBJCOPY_FOR_TARGET     = objcopy
-CFLAGS_FOR_TARGET      = -I. -g -Os -march=i386 -mregparm=3 \
-                         -fPIC -ffreestanding
-LDFLAGS_FOR_TARGET     =
+-include               MCONFIG
 
 RELOC_OBJS             = $(patsubst %.c,%.o,$(wildcard reloc/*.c)) \
                          $(patsubst %.S,%.o,$(wildcard reloc/*.S))
@@ -40,3 +31,54 @@ wraplinux: main.o linux.o reloc.o elf.o nbi.o segment.o mapfile.o xmalloc.o
 
 clean:
        rm -f wraplinux *.o reloc/*.o reloc/*.bin reloc/*.elf
+
+#
+# Autoconf
+#
+config:        MCONFIG
+
+MCONFIG: configure MCONFIG.in config.h.in
+       ./configure
+
+config.h: MCONFIG
+       : Generated by side effect
+
+config.h.in: configure.in
+       rm -f config.h.in
+       autoheader
+
+configure: configure.in aclocal.m4
+       autoconf
+       rm -f MCONFIG config.cache config.log config.status config.h
+
+#
+# Version header
+#
+VERSION = $(shell cat version)
+
+version.h: version
+       echo "#define WRAPLINUX_VERSION \"$(VERSION)\"" > version.h
+
+wraplinux.spec: wraplinux.spec.in version
+       $(SED) -e 's/@@VERSION@@/$(VERSION)/g' < $< > $@
+
+#
+# Dependencies
+#
+depend:
+       $(PERL) mkdep.pl -M Makefile -- . reloc
+
+#-- Everything below is generated by mkdep.pl - do not edit --#
+elf.o: elf.c config.h elf32.h elfcommon.h le.h segment.h wraplinux.h
+linux.o: linux.c config.h elf32.h elfcommon.h le.h segment.h setup.h \
+ wraplinux.h
+main.o: main.c config.h elf32.h elfcommon.h segment.h wraplinux.h
+mapfile.o: mapfile.c config.h elf32.h elfcommon.h segment.h wraplinux.h
+nbi.o: nbi.c config.h elf32.h elfcommon.h le.h nbi.h segment.h wraplinux.h
+reloc.o: reloc.S
+reloc/a20.o: reloc/a20.S
+reloc/memmove.o: reloc/memmove.S
+reloc/reloc_init.o: reloc/reloc_init.S
+reloc/reloc_linux.o: reloc/reloc_linux.c reloc/reloc.h setup.h
+segment.o: segment.c config.h elf32.h elfcommon.h segment.h wraplinux.h
+xmalloc.o: xmalloc.c config.h elf32.h elfcommon.h segment.h wraplinux.h
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644 (file)
index 0000000..a3d8427
--- /dev/null
@@ -0,0 +1,35 @@
+dnl --------------------------------------------------------------------------
+dnl PA_ADD_CFLAGS()
+dnl
+dnl Attempt to add the given option to CFLAGS, if it doesn't break compilation
+dnl --------------------------------------------------------------------------
+AC_DEFUN(PA_ADD_CFLAGS,
+[AC_MSG_CHECKING([if $CC accepts $1])
+ pa_add_cflags__old_cflags="$CFLAGS"
+ CFLAGS="$CFLAGS $1"
+ AC_TRY_LINK([#include <stdio.h>],
+ [printf("Hello, World!\n");],
+ AC_MSG_RESULT([yes]),
+ AC_MSG_RESULT([no])
+ CFLAGS="$pa_add_cflags__old_cflags")])
+
+dnl ------------------------------------------------------------------------
+dnl  PA_WITH_BOOL
+dnl
+dnl  PA_WITH_BOOL(option, default, help, enable, disable)
+dnl
+dnl  Provides a more convenient way to specify --with-option and
+dnl  --without-option, with a default.  default should be either 0 or 1.
+dnl ------------------------------------------------------------------------
+AC_DEFUN(PA_WITH_BOOL,
+[AC_ARG_WITH([$1], [$3],
+if test ["$withval"] != no; then
+[$4]
+else
+[$5]
+fi,
+if test [$2] -ne 0; then
+[$4]
+else
+[$5]
+fi)])
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..1eaf439
--- /dev/null
@@ -0,0 +1,46 @@
+dnl
+dnl autoconf input file to generate MCONFIG
+dnl
+
+AC_PREREQ(2.59)
+AC_INIT(MCONFIG.in)
+AC_PREFIX_DEFAULT(/usr)
+
+AC_PROG_CC
+AC_AIX
+AC_GNU_SOURCE
+AC_ISC_POSIX
+AC_MINIX
+AC_SYS_LARGEFILE
+AC_C_CONST
+AC_C_INLINE
+
+PA_ADD_CFLAGS(-Wall)
+PA_ADD_CFLAGS(-W)
+PA_ADD_CFLAGS(-Wpointer-arith)
+PA_ADD_CFLAGS(-Wbad-function-cast)
+PA_ADD_CFLAGS(-Wcast-equal)
+PA_ADD_CFLAGS(-Wstrict-prototypes)
+PA_ADD_CFLAGS(-Wmissing-prototypes)
+PA_ADD_CFLAGS(-Wmissing-declarations)
+PA_ADD_CFLAGS(-Wnested-externs)
+PA_ADD_CFLAGS(-Winline)
+PA_ADD_CFLAGS(-Wshadow)
+PA_ADD_CFLAGS(-Wcast-align)
+PA_ADD_CFLAGS(-pipe)
+
+AC_CHECK_HEADERS(inttypes.h)
+AC_CHECK_HEADERS(sysexits.h)
+AC_CHECK_HEADERS(getopt.h)
+
+AC_SEARCH_LIBS(getopt_long, [getopt getopt_long])
+AC_CHECK_FUNCS(getopt_long)
+AH_TEMPLATE([HAVE_GETOPT_LONG],
+       [Define to 1 if you have the `getopt_long' function])
+
+AC_PROG_SED
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+
+AC_CONFIG_HEADER(config.h)
+AC_OUTPUT(MCONFIG)
diff --git a/elf.c b/elf.c
index aed35f1..0836343 100644 (file)
--- a/elf.c
+++ b/elf.c
@@ -16,6 +16,8 @@
  * Take a linked list of segments and output it as an ELF32 image
  */
 
+#include "wraplinux.h"
+
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
index 370175e..5894626 100644 (file)
--- a/mapfile.c
+++ b/mapfile.c
  * size up to at least a dword boundary.
  */
 
+#include "wraplinux.h"
+
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/mman.h>
+#include <sys/stat.h>
 
 void *mapfile(int fd, size_t *len, int writable)
 {
diff --git a/mkdep.pl b/mkdep.pl
new file mode 100755 (executable)
index 0000000..0b87608
--- /dev/null
+++ b/mkdep.pl
@@ -0,0 +1,202 @@
+#!/usr/bin/perl
+#
+# Script to create Makefile-style dependencies.
+#
+# Usage: perl mkdep.pl [-s path-separator] [-o obj-ext] dir... > deps
+#
+
+use File::Spec;
+use File::Basename;
+use Fcntl;
+
+$barrier = "#-- Everything below is generated by mkdep.pl - do not edit --#\n";
+
+#
+# Scan files for dependencies
+#
+sub scandeps($) {
+    my($file) = @_;
+    my($line, $nf);
+    my(@xdeps) = ();
+    my(@mdeps) = ();
+
+    sysopen(FILE, $file, O_RDONLY)
+       or return;              # If not openable, assume generated
+
+    while ( defined($line = <FILE>) ) {
+       chomp $line;
+       $line =~ s:/\*.*\*/::g;
+       $line =~ s://.*$::;
+       if ( $line =~ /^\s*\#\s*include\s+\"(.*)\"\s*$/ ) {
+           $nf = $1;
+           push(@mdeps, $nf);
+           push(@xdeps, $nf) unless ( defined($deps{$nf}) );
+       }
+    }
+    close(FILE);
+    $deps{$file} = [@mdeps];
+
+    foreach $file ( @xdeps ) {
+       scandeps($file);
+    }
+}
+
+# %deps contains direct dependencies.  This subroutine resolves
+# indirect dependencies that result.
+sub alldeps($) {
+    my($file) = @_;
+    my(%adeps);
+    my($dep,$idep);
+
+    foreach $dep ( @{$deps{$file}} ) {
+       $adeps{$dep} = 1;
+       foreach $idep ( alldeps($dep) ) {
+           $adeps{$idep} = 1;
+       }
+    }
+    return sort(keys(%adeps));
+}
+
+# This converts a filename from host syntax to target syntax
+# This almost certainly works only on relative filenames...
+sub convert_file($$) {
+    my($file,$sep) = @_;
+    my(@fspec) = (basename($file));
+    while ( ($file = dirname($file)) ne File::Spec->curdir() &&
+           $file ne File::Spec->rootdir() ) {
+       unshift(@fspec, basename($file));
+    }
+
+    if ( $sep eq '' ) {
+       # This means kill path completely.  Used with Makes who do
+       # path searches, but doesn't handle output files in subdirectories,
+       # like OpenWatcom WMAKE.
+       return $fspec[scalar(@fspec)-1];
+    } else {
+       return join($sep, @fspec);
+    }
+}
+
+#
+# Insert dependencies into a Makefile
+#
+sub insert_deps($) {
+    my($file) = @_;
+    $nexttemp++;               # Unique serial number for each temp file
+    my($tmp) = File::Spec->catfile(dirname($file), 'tmp.'.$nexttemp);
+
+    sysopen(IN, $file, O_RDONLY)
+       or die "$0: Cannot open input: $file\n";
+    sysopen(OUT, $tmp, O_WRONLY|O_CREAT|O_TRUNC, 0666)
+       or die "$0: Cannot open output: $tmp\n";
+
+    my($line,$parm,$val);
+    my($obj) = '.o';           # Defaults
+    my($sep) = '/';
+    my($cont) = "\\";
+    my($maxline) = 78;         # Seems like a reasonable default
+    my @exclude = ();          # Don't exclude anything
+
+    while ( defined($line = <IN>) ) {
+       if ( $line =~ /^\s*\#\s*@([a-z0-9-]+):\s*\"([^\"]*)\"/ ) {
+           $parm = $1;  $val = $2;
+           if ( $parm eq 'object-ending' ) {
+               $obj = $val;
+           } elsif ( $parm eq 'path-separator' ) {
+               $sep = $val;
+           } elsif ( $parm eq 'line-width' ) {
+               $maxline = $val+0;
+           } elsif ( $parm eq 'continuation' ) {
+               $cont = $val;
+           } elsif ( $parm eq 'exclude' ) {
+               @exclude = split(/\,/, $val);
+           }
+       } elsif ( $line eq $barrier ) {
+           last;               # Stop reading input at barrier line
+       }
+       print OUT $line;
+    }
+    close(IN);
+
+    my $e, %do_exclude;
+    foreach $e (@exclude) {
+       $do_exclude{$e} = 1;
+    }
+
+    my $dfile, $ofile, $str, $sl, $len;
+    my @deps, $dep;
+
+    print OUT $barrier;
+
+    foreach $dfile ( sort(keys(%deps)) ) {
+       if ( $dfile =~ /\.[CcS]$/ ) {
+           $ofile = $dfile; $ofile =~ s/\.[CcS]$//;
+           $str = convert_file($ofile,$sep).$obj.':';
+           $len = length($str);
+           print OUT $str;
+           foreach $dep ($dfile, alldeps($dfile)) {
+               unless ($do_exclude{$dep}) {
+                   $str = convert_file($dep,$sep);
+                   $sl = length($str)+1;
+                   if ( $len+$sl > $maxline-2 ) {
+                       print OUT ' ', $cont, "\n ", $str;
+                       $len = $sl;
+                   } else {
+                       print OUT ' ', $str;
+                       $len += $sl;
+                   }
+               }
+           }
+           print OUT "\n";
+       }
+    }
+    close(OUT);
+
+    (unlink($file) && rename($tmp, $file))
+       or die "$0: Failed to change $tmp -> $file\n";
+}
+
+#
+# Main program
+#
+
+%deps = ();
+@files = ();
+@mkfiles = ();
+$mkmode = 0;
+
+while ( defined($arg = shift(@ARGV)) ) {
+    if ( $arg eq '-m' ) {
+       $arg = shift(@ARGV);
+       push(@mkfiles, $arg);
+    } elsif ( $arg eq '-M' ) {
+       $mkmode = 1;            # Futher filenames are output Makefile names
+    } elsif ( $arg eq '--' && $mkmode ) {
+       $mkmode = 0;
+    } elsif ( $arg =~ /^-/ ) {
+       die "Unknown option: $arg\n";
+    } else {
+       if ( $mkmode ) {
+           push(@mkfiles, $arg);
+       } else {
+           push(@files, $arg);
+       }
+    }
+}
+
+foreach $dir ( @files ) {
+    opendir(DIR, $dir) or die "$0: Cannot open directory: $dir";
+
+    while ( $file = readdir(DIR) ) {
+       $path = ($dir eq File::Spec->curdir())
+           ? $file : File::Spec->catfile($dir,$file);
+       if ( $file =~ /\.[CcS]$/ ) {
+           scandeps($path);
+       }
+    }
+    closedir(DIR);
+}
+
+foreach $mkfile ( @mkfiles ) {
+    insert_deps($mkfile);
+}
diff --git a/nbi.c b/nbi.c
index 6f5cfac..9634a13 100644 (file)
--- a/nbi.c
+++ b/nbi.c
@@ -16,6 +16,8 @@
  * Take a linked list of segments and output it as an NBI image
  */
 
+#include "wraplinux.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index a2b0d2c..b86cfe2 100644 (file)
@@ -35,7 +35,7 @@
  * as small as possible.
  */
 
-#include "reloc.h"
+#include "reloc/reloc.h"
 #include "setup.h"
 
 static uint32_t initrd_len, initrd_addr;
index dc8e330..c08e417 100644 (file)
--- a/segment.c
+++ b/segment.c
@@ -17,6 +17,8 @@
  * Eventually add support here for merging segments
  */
 
+#include "wraplinux.h"
+
 #include <stdlib.h>
 #include <alloca.h>
 #include "segment.h"
index 707ac70..80f3d75 100644 (file)
 #ifndef WRAPLINUX_H
 #define WRAPLINUX_H
 
-#include <stddef.h>
+#include "config.h"
+
+#include <inttypes.h>
+#include <stdlib.h>
 #include <stdio.h>
+#include <sysexits.h>
+
 #include "segment.h"
 
 extern const char *program;
index 6d57a59..55f559d 100644 (file)
--- a/xmalloc.c
+++ b/xmalloc.c
@@ -5,13 +5,11 @@
  *
  */
 
+#include "wraplinux.h"
+
 #include <errno.h>
 #include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
 #include <string.h>
-#include <sysexits.h>
-#include "wraplinux.h"
 
 void *xmalloc(size_t size)
 {