1#!/bin/sh 2# 3# Generate generic POSIX compliant Makefiles. 4# 5# This means that there's a lot of unnecessary text (when using BSD or GNU 6# make, as I'm sure there are in other variants), and a lack of modularity, 7# but as long as you follow the criterion set in locate-test, then the 8# end-result for modifying and/or adding tests can be achieved by merely 9# rerunning this script. 10# 11# This script will remain around until (hopefully someday) POSIX make 12# becomes less braindead. 13# 14# See COPYING for more details. 15# 16# Ngie Cooper, June 2010 17# 18 19generate_locate_test_makefile() { 20 21 local maketype=$1; shift 22 23 echo "Generating $maketype Makefiles" 24 25 locate-test --$maketype | sed -e 's,^./,,g' > make-gen.$maketype 26 27 generate_makefiles make-gen.$maketype $* 28 29 rm -f make-gen.$maketype 30} 31 32generate_makefile() { 33 34 local make_rule_prereq_cache= 35 local make_copy_prereq_cache= 36 local prereq_cache= 37 local tests= 38 local targets= 39 40 local makefile=$1 41 local prereq_dir=$2 42 local compiler_args=$3 43 shift 3 44 45 prereq_cache=$* 46 47 test_prefix=$(basename "$prereq_dir") 48 49 # special case for speculative testcases 50 if [ "$test_prefix" = "speculative" ]; then 51 test_prefix=$(basename $(echo "$prereq_dir" | sed s/speculative//)) 52 test_prefix="${test_prefix}_speculative" 53 fi 54 55 # Add all source files to $make_target_prereq_cache. 56 for prereq in $prereq_cache; do 57 # Stuff that needs to be tested. 58 if echo "$prereq" | grep -Eq '\.(run-test|sh)'; then 59 if [ "$tests" != "" ]; then 60 tests="$tests " 61 fi 62 63 tests="$tests${test_prefix}_$prereq" 64 fi 65 66 # Stuff that needs to be compiled. 67 if echo "$prereq" | grep -Eq '\.(run-test|sh|test)'; then 68 if [ "$targets" != "" ]; then 69 targets="$targets " 70 fi 71 72 targets="$targets${test_prefix}_$prereq" 73 fi 74 75 # Cache for generating compile rules. 76 case "$prereq" in 77 *.sh) 78 # Note that the sh scripts are copied later in order to 79 # have the test_prefix as well 80 if [ "$make_copy_prereq_cache" != "" ]; then 81 make_copy_prereq_cache="$make_copy_prereq_cache " 82 fi 83 make_copy_prereq_cache="$make_copy_prereq_cache$prereq" 84 ;; 85 *) 86 if [ "$make_rule_prereq_cache" != "" ]; then 87 make_rule_prereq_cache="$make_rule_prereq_cache " 88 fi 89 make_rule_prereq_cache="$make_rule_prereq_cache$prereq" 90 ;; 91 esac 92 done 93 94 if [ ! -f "$makefile.1" ]; then 95 96 cat > "$makefile.1" <<EOF 97# 98# Automatically generated by `basename "$0"` -- DO NOT EDIT. 99# 100# Restrictions for `basename "$0"` apply to this file. See COPYING for 101# more details. 102# 103# $AUTHORDATE 104# 105 106# Path variables. 107top_srcdir?= `echo "$prereq_dir" | awk '{ gsub(/[^\/]+/, "..", $0); print }'` 108subdir= $prereq_cache_dir 109srcdir= \$(top_srcdir)/\$(subdir) 110 111prefix?= $PREFIX 112exec_prefix?= \$(prefix) 113INSTALL_DIR= \$(DESTDIR)/\$(exec_prefix)/\$(subdir) 114LOGFILE?= logfile 115 116# Build variables 117CFLAGS+= -I\$(top_srcdir)/include 118 119# XXX: for testfrmw.c -- needs to be moved into a library. 120CFLAGS+= -I\$(srcdir) 121 122EOF 123 124 if [ -f "$GLOBAL_BOILERPLATE" ]; then 125 cat >> "$makefile.1" <<EOF 126# Top-level make definitions 127`cat $GLOBAL_BOILERPLATE` 128EOF 129 fi 130 131 cat >> "$makefile.1" <<EOF 132# Submake make definitions. 133EOF 134 135 for var in CFLAGS LDFLAGS LDLIBS; do 136 if [ -f "${TOP_SRCDIR}/$var" ]; then 137 cat >> "$makefile.1" <<EOF 138${var}+= `cat "${prereq_cache_dir}/${var}" 2>/dev/null` 139EOF 140 fi 141 done 142 143 # Whitespace 144 echo "" >> "$makefile.1" 145 146 fi 147 148 cat >> "$makefile.2" <<EOF 149INSTALL_TARGETS+= ${tests} 150MAKE_TARGETS+= ${targets} 151 152EOF 153 154 if [ ! -f "$makefile.3" ]; then 155 156 cat > "$makefile.3" <<EOF 157all: \$(MAKE_TARGETS) 158 @if [ -d speculative ]; then \$(MAKE) -C speculative all; fi 159 160clean: 161 rm -f \$(MAKE_TARGETS) logfile* run.sh *.core 162 @if [ -d speculative ]; then \$(MAKE) -C speculative clean; fi 163 164install: \$(INSTALL_DIR) run.sh 165 set -e; for file in \$(INSTALL_TARGETS) run.sh; do \\ 166 if [ -f "\$\$file" ] ; then \\ 167 install -m 00755 \$\$file \\ 168 \$(INSTALL_DIR)/\$\$file; \\ 169 fi; \\ 170 done 171 @if [ -d speculative ]; then \$(MAKE) -C speculative install; fi 172 173test: run.sh 174 @./run.sh 175 176\$(INSTALL_DIR): 177 mkdir -p \$@ 178 179EOF 180 181 fi 182 183 if ! grep -q '^run.sh' "$makefile.3"; then 184 cat >> "$makefile.3" <<EOF 185run.sh: 186 @echo '#/bin/sh' > \$@ 187 @echo "\$(top_srcdir)/bin/run-tests.sh \$(subdir) \$(INSTALL_TARGETS)" >> \$@ 188 @chmod +x run.sh 189 190EOF 191 fi 192 193 # Produce _awesome_ target rules for everything that needs it. 194 for prereq in ${make_rule_prereq_cache}; do 195 196 test_name="$prereq" 197 if [ "$suffix" != "" ]; then 198 test_name=`echo "$test_name" | sed -e "s,$suffix,,"` 199 fi 200 201 c_file="$test_name.c" 202 bin_file="${test_prefix}_$prereq" 203 204 case "$suffix" in 205 .run-test) 206 grep -q 'main' "$prereq_dir/$c_file" || echo >&2 "$prereq_dir/$c_file should be test." 207 ;; 208 .test) 209 grep -q 'main' "$prereq_dir/$c_file" && echo >&2 "$prereq_dir/$c_file should be run-test." 210 ;; 211 esac 212 213 COMPILE_STR="\$(CC) $compiler_args \$(CFLAGS) \$(LDFLAGS) -o \$@ \$(srcdir)/$c_file \$(LDLIBS)" 214 215 cat >> "$makefile.3" <<EOF 216$bin_file: \$(srcdir)/$c_file 217 @if $COMPILE_STR > logfile.\$\$\$\$ 2>&1; then \\ 218 cat logfile.\$\$\$\$; \\ 219 echo "\$(subdir)/$test_name compile PASSED"; \\ 220 echo "\$(subdir)/$test_name compile PASSED" >> \$(LOGFILE); \\ 221 else \\ 222 cat logfile.\$\$\$\$; \\ 223 echo "\$(subdir)/$test_name compile FAILED; SKIPPING"; \\ 224 (echo "\$(subdir)/$test_name compile FAILED; SKIPPING"; cat logfile.\$\$\$\$) >> \$(LOGFILE); \\ 225 fi; \\ 226 rm -f logfile.\$\$\$\$ 227 228EOF 229 done 230 231 # Produce copy rules for .sh scripts. 232 for prereq in ${make_copy_prereq_cache}; do 233 src="$prereq" 234 dst="${test_prefix}_$prereq" 235 236 cat >> "$makefile.3" <<EOF 237$dst: \$(srcdir)/$src 238 @cp \$(srcdir)/$src \$@ 239 240EOF 241 done 242} 243 244generate_makefiles() { 245 246 local prereq_cache= 247 248 local make_gen_list=$1 249 local suffix=$2 250 local compiler_args="$3" 251 252 while read filename; do 253 254 prereq_dir=`dirname "$filename"` 255 256 # First run. 257 if [ "$prereq_cache_dir" = "" ] ; then 258 prereq_cache_dir="$prereq_dir" 259 elif [ "$prereq_cache_dir" != "$prereq_dir" ]; then 260 261 generate_makefile "$prereq_cache_dir/Makefile" "$prereq_cache_dir" "$compiler_args" $prereq_cache 262 263 # Prep for the next round.. 264 prereq_cache= 265 prereq_cache_dir="$prereq_dir" 266 267 fi 268 269 # Cache the entries to punt out all of the data at 270 # once for a single Makefile. 271 if [ "$prereq_cache" != "" ] ; then 272 prereq_cache="$prereq_cache " 273 fi 274 prereq_cache="$prereq_cache"`basename "$filename" | sed "s,.c\$,$suffix,g"` 275 276 done < $make_gen_list 277 278 # Dump the last Makefile data cached up. 279 generate_makefile "$prereq_cache_dir/Makefile" $prereq_cache_dir "$compiler_args" $prereq_cache 280 281} 282 283export PATH="$PATH:`dirname "$0"`" 284 285AUTHORDATE=`grep "Ngie Cooper" "$0" | head -n 1 | sed 's,# *,,'` 286PREFIX=`print-prefix.sh` 287EXEC_PREFIX="${PREFIX}/bin" 288TOP_SRCDIR=${TOP_SRCDIR:=`dirname "$0"`/..} 289 290GLOBAL_BOILERPLATE="${TOP_SRCDIR}/.global_boilerplate" 291 292CONFIG_MK="../../include/mk/config-openposix.mk" 293 294rm -f "$GLOBAL_BOILERPLATE" 295 296for var in CFLAGS LDFLAGS LDLIBS; do 297 if [ -f "$TOP_SRCDIR/$var" ]; then 298 cat >> "$GLOBAL_BOILERPLATE" <<EOF 299$var+= `cat "$TOP_SRCDIR/$var"` 300EOF 301 fi 302done 303 304if [ -f "$CONFIG_MK" ]; then 305 cat "$CONFIG_MK" >> "$GLOBAL_BOILERPLATE" 306fi 307 308# For the generic cases. 309generate_locate_test_makefile buildonly '.test' '-c' 310generate_locate_test_makefile runnable '.run-test' 311generate_locate_test_makefile test-tools '' 312 313rm -f "$GLOBAL_BOILERPLATE" 314 315find . -name Makefile.1 -exec dirname {} \; | while read dir; do 316 if [ -f "$dir/Makefile.2" ]; then 317 cat $dir/Makefile.1 $dir/Makefile.2 $dir/Makefile.3 > $dir/Makefile 318 fi 319 rm $dir/Makefile.1 $dir/Makefile.2 $dir/Makefile.3 320done 321