#!/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 # readonly buildonly_compiler_args="-c" 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 link_libs= 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" <> "$makefile.1" <> "$makefile.1" <> "$makefile.1" </dev/null` EOF fi done # Whitespace echo "" >> "$makefile.1" fi cat >> "$makefile.2" < "$makefile.3" <> "$makefile.3" < \$@ @echo "\$(top_srcdir)/bin/run-tests.sh \$(subdir) \$(INSTALL_TARGETS)" >> \$@ @chmod +x run.sh EOF fi # Only pass along libraries to link if `-c` was not specified in `$compiler_args`. if [ "$compiler_args" = "$buildonly_compiler_args" ]; then link_libs=false else link_libs=true 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" if $link_libs; then COMPILE_STR="$COMPILE_STR \$(LDLIBS)" fi cat >> "$makefile.3" < 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" <> "$GLOBAL_BOILERPLATE" <> "$GLOBAL_BOILERPLATE" fi # For the generic cases. generate_locate_test_makefile buildonly '.test' "$buildonly_compiler_args" 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