• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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