338 lines
7.8 KiB
Bash
Executable File
338 lines
7.8 KiB
Bash
Executable File
#!/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' | sort > 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" <<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
|
|
|
|
if [ ! -z "${tests}" ]; then
|
|
cat >> "$makefile.2" <<EOF
|
|
INSTALL_TARGETS+= ${tests}
|
|
EOF
|
|
fi
|
|
cat >> "$makefile.2" <<EOF
|
|
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
|
|
|
|
# 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" <<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' "$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
|