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 19 generate_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 32 generate_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. 107 top_srcdir?= `echo "$prereq_dir" | awk '{ gsub(/[^\/]+/, "..", $0); print }'` 108 subdir= $prereq_cache_dir 109 srcdir= \$(top_srcdir)/\$(subdir) 110 111 prefix?= $PREFIX 112 exec_prefix?= \$(prefix) 113 INSTALL_DIR= \$(DESTDIR)/\$(exec_prefix)/\$(subdir) 114 LOGFILE?= logfile 115 116 # Build variables 117 CFLAGS+= -I\$(top_srcdir)/include 118 119 # XXX: for testfrmw.c -- needs to be moved into a library. 120 CFLAGS+= -I\$(srcdir) 121 122 EOF 123 124 if [ -f "$GLOBAL_BOILERPLATE" ]; then 125 cat >> "$makefile.1" <<EOF 126 # Top-level make definitions 127 `cat $GLOBAL_BOILERPLATE` 128 EOF 129 fi 130 131 cat >> "$makefile.1" <<EOF 132 # Submake make definitions. 133 EOF 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` 139 EOF 140 fi 141 done 142 143 # Whitespace 144 echo "" >> "$makefile.1" 145 146 fi 147 148 cat >> "$makefile.2" <<EOF 149 INSTALL_TARGETS+= ${tests} 150 MAKE_TARGETS+= ${targets} 151 152 EOF 153 154 if [ ! -f "$makefile.3" ]; then 155 156 cat > "$makefile.3" <<EOF 157 all: \$(MAKE_TARGETS) 158 @if [ -d speculative ]; then \$(MAKE) -C speculative all; fi 159 160 clean: 161 rm -f \$(MAKE_TARGETS) logfile* run.sh *.core 162 @if [ -d speculative ]; then \$(MAKE) -C speculative clean; fi 163 164 install: \$(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 173 test: run.sh 174 @./run.sh 175 176 \$(INSTALL_DIR): 177 mkdir -p \$@ 178 179 EOF 180 181 fi 182 183 if ! grep -q '^run.sh' "$makefile.3"; then 184 cat >> "$makefile.3" <<EOF 185 run.sh: 186 @echo '#/bin/sh' > \$@ 187 @echo "\$(top_srcdir)/bin/run-tests.sh \$(subdir) \$(INSTALL_TARGETS)" >> \$@ 188 @chmod +x run.sh 189 190 EOF 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 228 EOF 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 240 EOF 241 done 242 } 243 244 generate_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 283 export PATH="$PATH:`dirname "$0"`" 284 285 AUTHORDATE=`grep "Ngie Cooper" "$0" | head -n 1 | sed 's,# *,,'` 286 PREFIX=`print-prefix.sh` 287 EXEC_PREFIX="${PREFIX}/bin" 288 TOP_SRCDIR=${TOP_SRCDIR:=`dirname "$0"`/..} 289 290 GLOBAL_BOILERPLATE="${TOP_SRCDIR}/.global_boilerplate" 291 292 CONFIG_MK="../../include/mk/config-openposix.mk" 293 294 rm -f "$GLOBAL_BOILERPLATE" 295 296 for var in CFLAGS LDFLAGS LDLIBS; do 297 if [ -f "$TOP_SRCDIR/$var" ]; then 298 cat >> "$GLOBAL_BOILERPLATE" <<EOF 299 $var+= `cat "$TOP_SRCDIR/$var"` 300 EOF 301 fi 302 done 303 304 if [ -f "$CONFIG_MK" ]; then 305 cat "$CONFIG_MK" >> "$GLOBAL_BOILERPLATE" 306 fi 307 308 # For the generic cases. 309 generate_locate_test_makefile buildonly '.test' '-c' 310 generate_locate_test_makefile runnable '.run-test' 311 generate_locate_test_makefile test-tools '' 312 313 rm -f "$GLOBAL_BOILERPLATE" 314 315 find . -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 320 done 321