Reputation: 33
I have a number of makefiles that build and run tests. I would like to create a script that makes each one and notes whether the tests passed or failed. Though I can determine test status within each make file, I am having trouble finding a way to communicate that status to the caller of the make
command.
My first thought is to somehow affect the return value of the make
command, though this does not seem possible. Can I do this? Is there some other form of communication I can use to express the test status to the bash script that will be calling make
? Perhaps by using environment variables?
Thanks
Edit: It seems that I cannot set the return code for make, so for the time being I will have to make the tests, run them in the calling script instead of the makefile, note the results, and then manually run a make clean
. I appreciate everyone's assistance.
Upvotes: 0
Views: 3405
Reputation: 189679
The default behavior of make
is to return failure and abandon any remaining targets if something failed.
for directory in */; do
if ( cd "$directory" && make ); then
echo "$0: Make in $directory succeeded" >&2
else
echo "$0: Make in $directory failed" >&2
fi
done
Upvotes: 1
Reputation: 15493
Simply ensure each test leaves its result in a file unique to that test. Least friction will be to create test.pass
if thes test passes, otherwise create test.fail
. At the end of the test run gather up all the files and generate a report.
This scheme has two advantages that I can see:
-jn
flag, don't you? (hint: it's the whole point of make))Assuming the tests are called test-blah where blah is any string, and that you have a list of tests in ${tests}
(after all, you have just built them, so it's not an unreasonable assumption).
A sketch:
fail = ${@:%.pass=%.fail}
test-passes := $(addsuffix .pass,${tests})
${test-passes}: test-%.pass: test-%
rm -f ${fail}
touch $@
$* || mv $@ ${fail}
.PHONY: all
all: ${test-passes}
all:
# Count the .pass files, and the .fail files
echo '$(words $(wildcard *.pass)) passes'
echo '$(words $(wildcard *.fail)) failures'
In more detail:
test-passes := $(addsuffix .pass,${tests})
${tests}
contains test-1 test-2
(say), then ${test-passes}
will be test-1.pass test-2.pass
${test-passes}: test-%.pass: test-%
test-1.pass
depends on the file test-1
. Similarly for test-2.pass
.test-1.pass
does not exist, or is older than the executable test-1
, then make will run the recipe.
rm -f ${fail}
${fail}
expands to the target with pass replaced by fail, or test-1.fail
in this case. The -f
ensures the rm returns no error in the case that the file does not exist.touch $@
— create the .pass file$< || mv $@ ${fail}
test-1.fail
is put in its place.PHONY: all
— The all target is symbolic and is not a fileall: ${test-passes}
echo '$(words $(wildcard *.pass)) passes'
$(wildcard)
into a list of pass files, and then counts the files with $(words)
. The shell gets the command echo 4 passes
(say)You run this with
$ make -j9 all
Make will keep 9 jobs running at once — lovely if you have 8 CPUs.
Upvotes: 0
Reputation: 21000
Make will only return one of the following according to the source
#define MAKE_SUCCESS 0
#define MAKE_TROUBLE 1
#define MAKE_FAILURE 2
MAKE_SUCCESS
and MAKE_FAILURE
should be self-explanatory; MAKE_TROUBLE
is only returned when running make with the -q
option.
That's pretty much all you get from make, there doesn't seem to be any way to set the return code.
Upvotes: 1