]> mj.ucw.cz Git - moe.git/commitdiff
Added libucw build system from Sherlock v3.12.2.
authorMartin Mares <mj@ucw.cz>
Thu, 15 May 2008 09:20:33 +0000 (11:20 +0200)
committerMartin Mares <mj@ucw.cz>
Thu, 15 May 2008 09:20:33 +0000 (11:20 +0200)
No changes have been made except for excluding genhash.c and its Makefile.

build/Makebottom [new file with mode: 0644]
build/Maketop [new file with mode: 0644]
build/genconf [new file with mode: 0755]
build/lib-deps [new file with mode: 0755]
build/lib-flags [new file with mode: 0755]
build/mergedeps [new file with mode: 0755]
build/tester [new file with mode: 0755]

diff --git a/build/Makebottom b/build/Makebottom
new file mode 100644 (file)
index 0000000..b6f716e
--- /dev/null
@@ -0,0 +1,195 @@
+# Bottom part of Makefile for the UCW Libraries
+# (c) 1997--2007 Martin Mares <mj@ucw.cz>
+
+# The run tree
+
+runtree: run/.tree-stamp $(addsuffix /.dir-stamp,$(addprefix $(o)/,$(DIRS)))
+
+run/.tree-stamp: $(o)/config.mk
+       $(M)Creating runtree
+       $(Q)mkdir -p run $(addprefix run/, cf $(EXTRA_RUNDIRS) $(INSTALL_RUNDIRS))
+       $(Q)touch run/.tree-stamp
+
+# Miscellaneous targets
+
+programs: $(PROGS)
+datafiles: $(DATAFILES)
+tests: $(TESTS)
+configs: $(addprefix run/cf/,$(CONFIGS))
+
+tags:
+       etags `find . -name "*.[ch]"`
+
+# Black magic with dependencies. It would be more correct to make "depend.new"
+# a prerequisite for "depend", but "depend.new" often has the same timestamp
+# as "depend" which would confuse make a lot and either force remaking anyway
+# or (as in current versions of GNU make) erroneously skipping the remaking.
+
+-include $(o)/depend
+
+$(o)/depend: force
+       $(Q)if [ -s $(o)/depend.new ] ; then $(s)/build/mergedeps $(o)/depend $(o)/depend.new ; >$(o)/depend.new ; fi
+
+force:
+
+# Rules for directories
+
+%.dir-stamp:
+       $(Q)mkdir -p $(@D) && touch $@
+
+# Rules for configuration files
+
+run/cf/%: custom/cf/% $(o)/config.mk $(s)/build/genconf
+       $(M)CF $<
+       $(Q)$(s)/build/genconf $< $@ $(o)/config.mk
+
+run/cf/%: $(s)/cf/% $(o)/config.mk $(s)/build/genconf
+       $(M)CF $<
+       $(Q)$(s)/build/genconf $< $@ $(o)/config.mk
+
+# Rules for libraries
+
+%.a:
+       $(M)AR $@
+       $(Q)rm -f $@
+       $(Q)ar rcs $@ $^
+ifdef CONFIG_INSTALL_API
+       $(Q)$(call symlink,$@,run/lib)
+endif
+
+%.so:
+       $(M)LD $@
+       $(Q)$(CC) $(LSHARED) $(LDFLAGS) -o $@ $^
+       $(Q)$(call symlink,$@,run/lib)
+
+$(o)/%.pc: $(s)/%.pc $(o)/%.$(LS)
+       $(M)PC $<
+       $(Q)DEPS="$(shell $(s)/build/lib-deps $^)" LIBDIR=$(@D) $(s)/build/genconf $< $@ $(o)/config.mk
+       $(Q)mkdir -p $(o)/pkgconfig
+       $(Q)$(call symlink,$@,$(o)/pkgconfig)
+
+# Rules for public API
+
+ifdef CONFIG_INSTALL_API
+
+API_ROOT:=$(shell pwd)/run
+INSTALL_RUNDIRS+=include lib/pkgconfig
+api: $(API_INCLUDES) $(addprefix run/lib/pkgconfig/,$(addsuffix .pc,$(API_LIBS)))
+
+$(o)/%/.include-stamp:
+       $(Q)$(s)/build/install-includes $(<D) run/include/$(IDST) $(?F)
+       $(Q)touch $@
+
+run/lib/pkgconfig/%.pc:                # RHS supplied in the sub-makefile
+       $(M)PC-API $@
+       $(Q)sed <$< >$@ "s@^libdir=.*@libdir=$(API_ROOT)/lib@;s@^incdir=.*@incdir=$(API_ROOT)/include@"
+
+else
+api:
+endif
+
+# Rules for compiling C
+
+$(o)/%.o: $(s)/%.c $(o)/autoconf.h
+       $(M)CC $<
+       $(Q)DEPENDENCIES_OUTPUT="$(o)/depend.new $@" $(CC) $(CFLAGS) -c -o $@ $<
+
+$(o)/%.o: %.c $(o)/autoconf.h
+       $(M)CC $<
+       $(Q)DEPENDENCIES_OUTPUT="$(o)/depend.new $@" $(CC) $(CFLAGS) -c -o $@ $<
+
+%.o: %.c $(o)/autoconf.h
+       $(M)CC $<
+       $(Q)DEPENDENCIES_OUTPUT="$(o)/depend.new $@" $(CC) $(CFLAGS) -c -o $@ $<
+
+$(o)/%.oo: $(s)/%.c $(o)/autoconf.h
+       $(M)CC-SO $<
+       $(Q)DEPENDENCIES_OUTPUT="$(o)/depend.new $@" $(CC) $(CFLAGS) $(CSHARED) -c -o $@ $<
+
+$(o)/%.oo: %.c $(o)/autoconf.h
+       $(M)CC-SO $<
+       $(Q)DEPENDENCIES_OUTPUT="$(o)/depend.new $@" $(CC) $(CFLAGS) $(CSHARED) -c -o $@ $<
+
+%.oo: %.c $(o)/autoconf.h
+       $(M)CC-SO $<
+       $(Q)DEPENDENCIES_OUTPUT="$(o)/depend.new $@" $(CC) $(CFLAGS) $(CSHARED) -c -o $@ $<
+
+$(o)/%-tt.o: $(s)/%.c $(o)/autoconf.h
+       $(M)CC-TEST $<
+       $(Q)DEPENDENCIES_OUTPUT="$(o)/depend.new $@" $(CC) $(CFLAGS) -DTEST -c -o $@ $<
+
+# Rules for testing
+
+$(o)/%-t: $(o)/%-tt.o $(TESTING_DEPS)
+       $(M)LD-TEST $@
+       $(Q)$(CC) $(LDFLAGS) -o $@ $(shell $(s)/build/lib-flags $^) $(LIBS)
+
+$(o)/%.test: $(s)/%.t $(s)/build/tester
+       $(M)TEST $@
+       $(Q)$(s)/build/tester --rundir=run $(TESTERFLAGS) $< && touch $@
+
+# Rules for binaries
+
+BINDIR=bin
+
+$(o)/%: $(o)/%.o
+       $(M)LD $@
+       $(Q)$(CC) $(LDFLAGS) -o $@ $(shell $(s)/build/lib-flags $^) $(LIBS)
+       $(Q)$(call symlink,$@,run/$(BINDIR))
+
+$(o)/%: $(s)/%.sh $(o)/config.mk $(s)/build/genconf
+       $(M)PP $<
+       $(Q)$(s)/build/genconf $< $@ $(o)/config.mk
+       $(Q)chmod +x $@
+       $(Q)$(call symlink,$@,run/$(BINDIR))
+
+$(o)/%: %.sh $(o)/config.mk $(s)/build/genconf
+       $(M)PP $<
+       $(Q)$(s)/build/genconf $< $@ $(o)/config.mk
+       $(Q)chmod +x $@
+       $(Q)$(call symlink,$@,run/$(BINDIR))
+
+$(o)/%: $(s)/%.pl $(o)/config.mk $(s)/build/genconf
+       $(M)PP $<
+       $(Q)$(s)/build/genconf $< $@ $(o)/config.mk
+       $(Q)chmod +x $@
+       $(Q)$(call symlink,$@,run/$(BINDIR))
+
+$(o)/%: %.pl $(o)/config.mk $(s)/build/genconf
+       $(M)PP $<
+       $(Q)$(s)/build/genconf $< $@ $(o)/config.mk
+       $(Q)chmod +x $@
+       $(Q)$(call symlink,$@,run/$(BINDIR))
+
+PERL_MODULE_DIR=UCW
+
+$(o)/%.pm: $(s)/%.pm
+       $(M)"PM $< -> run/lib/perl5/$(PERL_MODULE_DIR)/$(@F)"
+       $(Q)cp $^ $@
+       $(Q)$(call symlink,$@,run/lib/perl5/$(PERL_MODULE_DIR))
+
+$(o)/%.pm: %.pm
+       $(M)"PM $< -> run/lib/perl/$(PERL_MODULE_DIR)/$(@F)"
+       $(Q)cp $^ $@
+       $(Q)$(call symlink,$@,run/lib/perl5/$(PERL_MODULE_DIR))
+
+# Rules for data files
+
+DATADIR=lib
+
+$(DATAFILES): $(o)/%: $(s)/%
+       $(M)DATA $<
+       $(Q)cp $^ $@
+       $(Q)$(call symlink,$@,run/$(DATADIR))
+
+# Default installation target
+
+default-install:
+       SH_EXTRA_RUNDIRS="$(sort $(EXTRA_RUNDIRS))" SH_INSTALL_RUNDIRS="$(sort $(INSTALL_RUNDIRS))" SH_CONFIGS="$(sort $(CONFIGS))" SH_AUTO_CONFIRM="$(CONFIRM)" $(s)/build/installer $(INSTALL_DIR)
+
+# Don't delete intermediate targets. There shouldn't be any, but due to bugs
+# in GNU Make rules with targets in not-yet-existing directories are ignored
+# when searching for implicit rules and thence targets considered intermediate.
+.SECONDARY:
+
+.PHONY: all clean distclean runtree programs api datafiles force tags configs dust install default-install
diff --git a/build/Maketop b/build/Maketop
new file mode 100644 (file)
index 0000000..cf93e1b
--- /dev/null
@@ -0,0 +1,82 @@
+# Top part of Makefile for the UCW Libraries
+# (c) 1997--2007 Martin Mares <mj@ucw.cz>
+
+# Set to 1 if you want verbose output
+V=0
+
+# Set to 'y' (or 'n') if you want to auto-confirm (auto-reject) all questions in build/installer
+CONFIRM=
+
+# Disable all built-in rules and variables. Speeds up make and simplifies debugging.
+MAKEFLAGS+=-rR
+
+CFLAGS=$(CLANG) $(COPT) $(CDEBUG) $(CWARNS) $(CEXTRA) -I. -I$(o) -I$(s)
+LDFLAGS=$(LOPT) $(LEXTRA)
+
+DIRS=
+PROGS=
+CONFIGS=
+TESTS=
+EXTRA_RUNDIRS=tmp log
+INSTALL_RUNDIRS=bin lib
+API_INCLUDES=
+API_LIBS=
+
+# Various files whose type does not fit into PROGS
+DATAFILES=
+
+ifdef CONFIG_SHARED
+LS=so
+OS=oo
+else
+LS=a
+OS=o
+endif
+
+ifdef CONFIG_DARWIN
+SOEXT=bundle
+else
+SOEXT=so
+endif
+
+# Whenever "make -s" (silent) is run, turn on verbose mode (paradoxical, but gives the right result)
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+V=1
+endif
+
+# Define M (message) and Q (quiet command prefix) macros and also MAKESILENT passed to sub-makes
+ifeq ($(V),1)
+M=@\#
+Q=
+MAKESILENT=
+else
+M=@echo #
+Q=@
+MAKESILENT=-s
+endif
+
+# Clean needs to be a double-colon rule since we want sub-makefiles to be able
+# to define their own cleanup actions.
+dust::
+       rm -f `find . -path "*~" -or -name "\#*\#" -or -name core`
+       rm -f allocs.tmp cscope.out TAGS
+
+clean:: dust
+       rm -rf `find obj -mindepth 1 -maxdepth 1 -not \( -name config.mk -o -name autoconf.h \)`
+       rm -rf tests run/{bin,lib,include,.tree-stamp}
+
+distclean:: clean
+       rm -rf obj run
+
+testclean::
+       rm -f `find obj -name "*.test"`
+
+# Extra default rules (appended to by submakefiles)
+extras::
+
+# Relative symlinks and other pathname manipulation macros
+empty:=
+space:=$(empty) $(empty)
+backref=$(subst $(space),/,$(patsubst %,..,$(subst /,$(space),$(1))))
+tack-on=$(if $(patsubst /%,,$(2)),$(1)/$(2),$(2))
+symlink=ln -sf $(call tack-on,$(call backref,$(2)),$(1)) $(2)/
diff --git a/build/genconf b/build/genconf
new file mode 100755 (executable)
index 0000000..eaf2d1c
--- /dev/null
@@ -0,0 +1,81 @@
+#!/usr/bin/perl
+# Configuration file and script preprocessor
+# (c) 2004--2007 Martin Mares <mj@ucw.cz>
+
+use strict;
+use warnings;
+
+@ARGV == 3 or die "Usage: genconf <src> <dest> <config.mk>";
+
+open CF, $ARGV[2] or die "Unable to open $ARGV[2]";
+my %options = ();
+my %vars = ();
+sub opt {
+       my ($k,$v) = @_;
+       $vars{$k} = $v;
+       $options{$k} = 1 if ($k =~ /^CONFIG_/);
+}
+foreach my $k (keys %ENV) {
+       opt($k, $ENV{$k});
+}
+while (<CF>) {
+       chomp;
+       if (my ($k,$v) = /^(\w+)=(.*)/) {
+               $v =~ s/\s+$//;
+               opt($k, $v);
+       }
+}
+close CF;
+
+sub eval_expr {
+       $_ = shift @_;
+       s/\b(CONFIG_\w+)\b/defined($options{$1}) ? 1 : 0/ge;
+       return eval $_;
+}
+
+open IN, $ARGV[0] or die "Unable to open $ARGV[0]";
+open OUT, ">$ARGV[1]" or die "Unable to create $ARGV[1]";
+my @ifs = ();  # stack of conditions, 1=satisfied, -1=unsatisfied, 0=shadowed
+my $empty = 0; # last line was empty
+while (<IN>) {
+       if (/^#ifdef\s+(\w+)/) {
+               push @ifs, (@ifs && $ifs[$#ifs] <= 0) ? 0 : (defined $options{$1}) ? 1 : -1;
+       } elsif (/^#ifndef\s+(\w+)/) {
+               push @ifs, (@ifs && $ifs[$#ifs] <= 0) ? 0 : (defined $options{$1}) ? -1 : 1;
+       } elsif (/^#if\s(.*)$/) {
+               push @ifs, (@ifs && $ifs[$#ifs] <= 0) ? 0 : (eval_expr $1) ? 1 : -1;
+       } elsif (/^#endif/) {
+               defined pop @ifs || die "Improper nesting of conditionals";
+       } elsif (/^#else/) {
+               my $x = pop @ifs;
+               defined $x || die "Improper nesting of conditionals";
+               push @ifs, $x >= 0 ? 0 : 1;
+       } elsif (/^#elsif\s(.*)$/) {
+               my $x = pop @ifs;
+               defined $x || die "Improper nesting of conditionals";
+               push @ifs, $x >= 0 ? 0 : (eval_expr $1) ? 1 : -1;
+       } else {
+               @ifs && $ifs[$#ifs] <= 0 && next;
+               if (/^$/) {
+                       $empty && next;
+                       $empty = 1;
+               } else { $empty = 0; }
+               if (/^#pipe\s+(.+)/) {
+                       my $cmd = $1;
+                       my $val = `$cmd`;
+                       die "Piped command '$cmd' failed" if $?;
+                       print OUT `$1`;
+               } else {
+                       sub repl ($) {
+                               my $v = shift @_;
+                               exists $vars{$v} or die "Cannot substitute $v: variable not set";
+                               return $vars{$v};
+                       }
+                       s/@(\w+)@/repl($1)/ge;
+                       print OUT;
+               }
+       }
+}
+@ifs && die "Unterminated #ifdef";
+close IN;
+close OUT;
diff --git a/build/lib-deps b/build/lib-deps
new file mode 100755 (executable)
index 0000000..1019bc2
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash
+#
+# A tool which builds a list of dependent libraries from the list
+# of pkg-config files.
+#
+# (c) 2007 Martin Mares <mj@ucw.cz>, placed under GNU LGPL
+#
+
+set -e
+
+shift
+SEEN=
+while [ -n "$1" ] ; do
+       case "$1" in
+               *.pc)   if [ -n "$SEEN" ] ; then echo -n ", " ; fi
+                       echo -n "`basename $1 .pc`"
+                       SEEN=1
+                       ;;
+               *)      ;;
+       esac
+       shift
+done
diff --git a/build/lib-flags b/build/lib-flags
new file mode 100755 (executable)
index 0000000..97d8956
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+#
+# A preprocessor for linker arguments, which replaces references to .pc
+# files by results of the proper calls to pkg-config.
+#
+# (c) 2007 Martin Mares <mj@ucw.cz>, placed under GNU LGPL
+#
+
+set -e
+
+PC=
+while [ -n "$1" ] ; do
+       case "$1" in
+               *.pc)   PC="$PC `basename $1 .pc`"
+                       ;;
+               *)      echo -n " $1"
+                       ;;
+       esac
+       shift
+done
+if [ -n "$PC" ] ; then
+       echo -n " "
+       PKG_CONFIG_PATH="$PKG_CONFIG_PATH:obj/pkgconfig" pkg-config --libs $PC
+fi
diff --git a/build/mergedeps b/build/mergedeps
new file mode 100755 (executable)
index 0000000..e1c467d
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/perl
+
+@ARGV == 2 or die "Usage: mergedeps <base> <update>";
+foreach $a (@ARGV) {
+       open F, "$a" or next;
+       $t = "";
+       while (<F>) {
+               $t .= $_;
+               if (! /\\$/) {
+                       ($t =~ /^(.*):/) || die "Parse error at $t";
+                       $rules{$1} = $t;
+                       $t = "";
+               }
+       }
+       close F;
+}
+open(F,">" . $ARGV[0]) || die "Unable to write output file";
+foreach $a (sort keys %rules) {
+       print F $rules{$a};
+}
+close F;
diff --git a/build/tester b/build/tester
new file mode 100755 (executable)
index 0000000..f66713e
--- /dev/null
@@ -0,0 +1,139 @@
+#!/usr/bin/perl
+# A simple unit testing script
+# (c) 2004--2007 Martin Mares <mj@ucw.cz>
+# (c) 2007 Pavel Charvat <pchar@ucw.cz>
+
+# Tests in the test file have a syntax similar to mail headers,
+# individual test case are separated by blank lines and they can contain
+# the following fields:
+#
+#      Name:   name of the case (default: sequence number since start of file)
+#      Run:    command to run (default: command from the previous test case)
+#              This can be an arbitrary shell pipeline, sequences $0 to $9 are
+#              replaced by file names of In<N> or Out<N> files (see below).
+#      In:     lines to pass to the program as standard input
+#      Out:    lines to expect at the program's standard output
+#      In<N>:  lines to pass to the program as input file <N>
+#      Out<N>: lines to expect from the program in output file <N>
+#              Both In<N> and Out<N> can be specified simultaneously if we
+#              are testing a program which modifies some of its input files.
+#      Exit:   expected exit code of the program (default: 0)
+
+use Getopt::Long;
+
+my $verbose = 0;
+my $rundir = ".";
+GetOptions("verbose!" => \$verbose,
+          "rundir=s" => \$rundir)
+       or die "Usage: tester [--verbose] [--rundir=<dir>] <tests>\n";
+
+my @tests = ();
+my $tt;
+my $append_to;
+
+while (<>) {
+       /^#/ && next;
+       if (/^\s*$/) {
+               $tt = undef;
+               $append_to = undef;
+       } elsif (defined($append_to) && /^\s+(.*)$/) {
+               $$append_to .= "\n$1";
+       } elsif (my ($n,$v) = /^(\w+):\s+(.*)$/) {
+               if (!$tt) {
+                       $tt = {};
+                       push @tests, $tt;
+               }
+               ($tt->{$n}) && die "$n already defined";
+               $tt->{$n} = $v;
+               $append_to = \($tt->{$n});
+       } else {
+               die "Test script syntax error";
+       }
+}
+
+if (! -d "$rundir/tmp") {
+       mkdir "$rundir/tmp" or die "Unable to create $rundir/tmp: $!";
+}
+
+my $i = 0;
+my $errors = 0;
+my $prev_run = undef;
+TEST: foreach $tt (@tests) {
+       $i++;
+       my $name = $tt->{'Name'} || $i;
+       print "Test $name: ";
+       $run = ($tt->{'Run'} || $prev_run) or die "Don't know what to run";
+       $prev_run = $run;
+
+       my @out_files = ();
+       my @out_checks = ();
+       my $redirs = "";
+
+       if (defined $tt->{'In'}) {
+               my $ifi = "tmp/test$i.in";
+               open X, ">$rundir/$ifi" or die "Unable to create $ifi";
+               print X $tt->{'In'}, "\n";
+               close X;
+               $redirs .= " <$ifi";
+       } else {
+               $redirs .= " </dev/null";
+       }
+       if (defined $tt->{'Out'}) {
+               my $ofi = "tmp/test$i.out";
+               unlink "$rundir/$ofi";
+               $redirs .= " >$ofi";
+               push @out_files, $ofi;
+               push @out_checks, $tt->{'Out'};
+       } else {
+               $redirs .= " >/dev/null";
+       }
+       foreach my $arg (0..9) {
+               my $f = "tmp/test$i.$arg";
+               if (defined $tt->{"Out$arg"}) {
+                       unlink "$rundir/$f";
+                       push @out_files, $f;
+                       push @out_checks, $tt->{"Out$arg"};
+               }
+               if (defined $tt->{"In$arg"}) {
+                       open X, ">$rundir/$f" or die "Unable to create $f";
+                       print X $tt->{"In$arg"}, "\n";
+                       close X;
+               }
+       }
+       $run =~ s/\$(\d)/tmp\/test$i.$1/g;
+       print "(running $run) " if $verbose;
+       system "cd $rundir && ( $run ) $redirs";
+       if ($? % 256) {
+               print "FAILED with status code $?\n";
+               $errors++;
+               next;
+       }
+       my $ec = $? / 256;
+       my $expect_ec = $tt->{'Exit'} || 0;
+       if ($ec != $expect_ec) {
+               print "FAILED: unexpected exit code $ec\n";
+               $errors++;
+               next;
+       }
+
+       for (my $i=0; $i<=$#out_files; $i++) {
+               my $ofi = $out_files[$i];
+               open X, "<$rundir/$ofi" or die "Unable to read $ofi";
+               my $out;
+               {
+                       local $/ = undef;
+                       $out = <X>;
+               }
+               close X;
+               if ($out ne $out_checks[$i] . "\n") {
+                       print "FAILED (see $ofi)\n";
+                       $errors++;
+                       next TEST;
+               }
+       }
+
+       system "rm -f $rundir/tmp/test$i.*";
+       print "OK\n";
+}
+
+exit !!$errors;