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