Home | History | Annotate | Download | only in scripts
      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