| #!/bin/sh |
| # |
| # Generate generic POSIX compliant Makefiles. |
| # |
| # This means that there's a lot of unnecessary text (when using BSD or GNU |
| # make, as I'm sure there are in other variants), and a lack of modularity, |
| # but as long as you follow the criterion set in locate-test, then the |
| # end-result for modifying and/or adding tests can be achieved by merely |
| # rerunning this script. |
| # |
| # This script will remain around until (hopefully someday) POSIX make |
| # becomes less braindead. |
| # |
| # See COPYING for more details. |
| # |
| # Ngie Cooper, June 2010 |
| # |
| |
| generate_locate_test_makefile() { |
| |
| local maketype=$1; shift |
| |
| echo "Generating $maketype Makefiles" |
| |
| locate-test --$maketype | sed -e 's,^./,,g' > make-gen.$maketype |
| |
| generate_makefiles make-gen.$maketype $* |
| |
| rm -f make-gen.$maketype |
| } |
| |
| generate_makefile() { |
| |
| local make_rule_prereq_cache= |
| local make_copy_prereq_cache= |
| local prereq_cache= |
| local tests= |
| local targets= |
| |
| local makefile=$1 |
| local prereq_dir=$2 |
| local compiler_args=$3 |
| shift 3 |
| |
| prereq_cache=$* |
| |
| test_prefix=$(basename "$prereq_dir") |
| |
| # special case for speculative testcases |
| if [ "$test_prefix" = "speculative" ]; then |
| test_prefix=$(basename $(echo "$prereq_dir" | sed s/speculative//)) |
| test_prefix="${test_prefix}_speculative" |
| fi |
| |
| # Add all source files to $make_target_prereq_cache. |
| for prereq in $prereq_cache; do |
| # Stuff that needs to be tested. |
| if echo "$prereq" | grep -Eq '\.(run-test|sh)'; then |
| if [ "$tests" != "" ]; then |
| tests="$tests " |
| fi |
| |
| tests="$tests${test_prefix}_$prereq" |
| fi |
| |
| # Stuff that needs to be compiled. |
| if echo "$prereq" | grep -Eq '\.(run-test|sh|test)'; then |
| if [ "$targets" != "" ]; then |
| targets="$targets " |
| fi |
| |
| targets="$targets${test_prefix}_$prereq" |
| fi |
| |
| # Cache for generating compile rules. |
| case "$prereq" in |
| *.sh) |
| # Note that the sh scripts are copied later in order to |
| # have the test_prefix as well |
| if [ "$make_copy_prereq_cache" != "" ]; then |
| make_copy_prereq_cache="$make_copy_prereq_cache " |
| fi |
| make_copy_prereq_cache="$make_copy_prereq_cache$prereq" |
| ;; |
| *) |
| if [ "$make_rule_prereq_cache" != "" ]; then |
| make_rule_prereq_cache="$make_rule_prereq_cache " |
| fi |
| make_rule_prereq_cache="$make_rule_prereq_cache$prereq" |
| ;; |
| esac |
| done |
| |
| if [ ! -f "$makefile.1" ]; then |
| |
| cat > "$makefile.1" <<EOF |
| # |
| # Automatically generated by `basename "$0"` -- DO NOT EDIT. |
| # |
| # Restrictions for `basename "$0"` apply to this file. See COPYING for |
| # more details. |
| # |
| # $AUTHORDATE |
| # |
| |
| # Path variables. |
| top_srcdir?= `echo "$prereq_dir" | awk '{ gsub(/[^\/]+/, "..", $0); print }'` |
| subdir= $prereq_cache_dir |
| srcdir= \$(top_srcdir)/\$(subdir) |
| |
| prefix?= $PREFIX |
| exec_prefix?= \$(prefix) |
| INSTALL_DIR= \$(DESTDIR)/\$(exec_prefix)/\$(subdir) |
| LOGFILE?= logfile |
| |
| # Build variables |
| CFLAGS+= -I\$(top_srcdir)/include |
| |
| # XXX: for testfrmw.c -- needs to be moved into a library. |
| CFLAGS+= -I\$(srcdir) |
| |
| EOF |
| |
| if [ -f "$GLOBAL_BOILERPLATE" ]; then |
| cat >> "$makefile.1" <<EOF |
| # Top-level make definitions |
| `cat $GLOBAL_BOILERPLATE` |
| EOF |
| fi |
| |
| cat >> "$makefile.1" <<EOF |
| # Submake make definitions. |
| EOF |
| |
| for var in CFLAGS LDFLAGS LDLIBS; do |
| if [ -f "${TOP_SRCDIR}/$var" ]; then |
| cat >> "$makefile.1" <<EOF |
| ${var}+= `cat "${prereq_cache_dir}/${var}" 2>/dev/null` |
| EOF |
| fi |
| done |
| |
| # Whitespace |
| echo "" >> "$makefile.1" |
| |
| fi |
| |
| cat >> "$makefile.2" <<EOF |
| INSTALL_TARGETS+= ${tests} |
| MAKE_TARGETS+= ${targets} |
| |
| EOF |
| |
| if [ ! -f "$makefile.3" ]; then |
| |
| cat > "$makefile.3" <<EOF |
| all: \$(MAKE_TARGETS) |
| @if [ -d speculative ]; then \$(MAKE) -C speculative all; fi |
| |
| clean: |
| rm -f \$(MAKE_TARGETS) logfile* run.sh *.core |
| @if [ -d speculative ]; then \$(MAKE) -C speculative clean; fi |
| |
| install: \$(INSTALL_DIR) run.sh |
| set -e; for file in \$(INSTALL_TARGETS) run.sh; do \\ |
| if [ -f "\$\$file" ] ; then \\ |
| install -m 00755 \$\$file \\ |
| \$(INSTALL_DIR)/\$\$file; \\ |
| fi; \\ |
| done |
| @if [ -d speculative ]; then \$(MAKE) -C speculative install; fi |
| |
| test: run.sh |
| @./run.sh |
| |
| \$(INSTALL_DIR): |
| mkdir -p \$@ |
| |
| EOF |
| |
| fi |
| |
| if ! grep -q '^run.sh' "$makefile.3"; then |
| cat >> "$makefile.3" <<EOF |
| run.sh: |
| @echo '#/bin/sh' > \$@ |
| @echo "\$(top_srcdir)/bin/run-tests.sh \$(subdir) \$(INSTALL_TARGETS)" >> \$@ |
| @chmod +x run.sh |
| |
| EOF |
| fi |
| |
| # Produce _awesome_ target rules for everything that needs it. |
| for prereq in ${make_rule_prereq_cache}; do |
| |
| test_name="$prereq" |
| if [ "$suffix" != "" ]; then |
| test_name=`echo "$test_name" | sed -e "s,$suffix,,"` |
| fi |
| |
| c_file="$test_name.c" |
| bin_file="${test_prefix}_$prereq" |
| |
| case "$suffix" in |
| .run-test) |
| grep -q 'main' "$prereq_dir/$c_file" || echo >&2 "$prereq_dir/$c_file should be test." |
| ;; |
| .test) |
| grep -q 'main' "$prereq_dir/$c_file" && echo >&2 "$prereq_dir/$c_file should be run-test." |
| ;; |
| esac |
| |
| COMPILE_STR="\$(CC) $compiler_args \$(CFLAGS) \$(LDFLAGS) -o \$@ \$(srcdir)/$c_file \$(LDLIBS)" |
| |
| cat >> "$makefile.3" <<EOF |
| $bin_file: \$(srcdir)/$c_file |
| @if $COMPILE_STR > logfile.\$\$\$\$ 2>&1; then \\ |
| cat logfile.\$\$\$\$; \\ |
| echo "\$(subdir)/$test_name compile PASSED"; \\ |
| echo "\$(subdir)/$test_name compile PASSED" >> \$(LOGFILE); \\ |
| else \\ |
| cat logfile.\$\$\$\$; \\ |
| echo "\$(subdir)/$test_name compile FAILED; SKIPPING"; \\ |
| (echo "\$(subdir)/$test_name compile FAILED; SKIPPING"; cat logfile.\$\$\$\$) >> \$(LOGFILE); \\ |
| fi; \\ |
| rm -f logfile.\$\$\$\$ |
| |
| EOF |
| done |
| |
| # Produce copy rules for .sh scripts. |
| for prereq in ${make_copy_prereq_cache}; do |
| src="$prereq" |
| dst="${test_prefix}_$prereq" |
| |
| cat >> "$makefile.3" <<EOF |
| $dst: \$(srcdir)/$src |
| @cp \$(srcdir)/$src \$@ |
| |
| EOF |
| done |
| } |
| |
| generate_makefiles() { |
| |
| local prereq_cache= |
| |
| local make_gen_list=$1 |
| local suffix=$2 |
| local compiler_args="$3" |
| |
| while read filename; do |
| |
| prereq_dir=`dirname "$filename"` |
| |
| # First run. |
| if [ "$prereq_cache_dir" = "" ] ; then |
| prereq_cache_dir="$prereq_dir" |
| elif [ "$prereq_cache_dir" != "$prereq_dir" ]; then |
| |
| generate_makefile "$prereq_cache_dir/Makefile" "$prereq_cache_dir" "$compiler_args" $prereq_cache |
| |
| # Prep for the next round.. |
| prereq_cache= |
| prereq_cache_dir="$prereq_dir" |
| |
| fi |
| |
| # Cache the entries to punt out all of the data at |
| # once for a single Makefile. |
| if [ "$prereq_cache" != "" ] ; then |
| prereq_cache="$prereq_cache " |
| fi |
| prereq_cache="$prereq_cache"`basename "$filename" | sed "s,.c\$,$suffix,g"` |
| |
| done < $make_gen_list |
| |
| # Dump the last Makefile data cached up. |
| generate_makefile "$prereq_cache_dir/Makefile" $prereq_cache_dir "$compiler_args" $prereq_cache |
| |
| } |
| |
| export PATH="$PATH:`dirname "$0"`" |
| |
| AUTHORDATE=`grep "Ngie Cooper" "$0" | head -n 1 | sed 's,# *,,'` |
| PREFIX=`print-prefix.sh` |
| EXEC_PREFIX="${PREFIX}/bin" |
| TOP_SRCDIR=${TOP_SRCDIR:=`dirname "$0"`/..} |
| |
| GLOBAL_BOILERPLATE="${TOP_SRCDIR}/.global_boilerplate" |
| |
| CONFIG_MK="../../include/mk/config-openposix.mk" |
| |
| rm -f "$GLOBAL_BOILERPLATE" |
| |
| for var in CFLAGS LDFLAGS LDLIBS; do |
| if [ -f "$TOP_SRCDIR/$var" ]; then |
| cat >> "$GLOBAL_BOILERPLATE" <<EOF |
| $var+= `cat "$TOP_SRCDIR/$var"` |
| EOF |
| fi |
| done |
| |
| if [ -f "$CONFIG_MK" ]; then |
| cat "$CONFIG_MK" >> "$GLOBAL_BOILERPLATE" |
| fi |
| |
| # For the generic cases. |
| generate_locate_test_makefile buildonly '.test' '-c' |
| generate_locate_test_makefile runnable '.run-test' |
| generate_locate_test_makefile test-tools '' |
| |
| rm -f "$GLOBAL_BOILERPLATE" |
| |
| find . -name Makefile.1 -exec dirname {} \; | while read dir; do |
| if [ -f "$dir/Makefile.2" ]; then |
| cat $dir/Makefile.1 $dir/Makefile.2 $dir/Makefile.3 > $dir/Makefile |
| fi |
| rm $dir/Makefile.1 $dir/Makefile.2 $dir/Makefile.3 |
| done |