dethredic
dethredic

Reputation: 57

Makefile: save errors and print at the end

I have the following Makefile snipt which runs some tests:

MKFILES = $(wildcard $(addprefix $(UNIT_TEST_SRC)/,$(subst $(comma), ,*.mk))))
TESTS = $(MKFILES:.mk=.test)

%.test:%.mk
  @make -f $?

run_tests: $(TESTS)

The above works fine, but I'm trying to change it so that instead of aborting when a test errors, it continues and prints out all failures at the end.

FAILURES := 

%.test:%.mk
  @make -f $? || $(MAKE) [email protected]

.PHONY: %.test.error
%.test.error:
  $(eval FAILURES += $@)

run_tests: $(TESTS)
   @echo "Failures:" $(FAILURES)

It seems like my eval is not surviving the %.test.error scope, If I move the eval to the %.test then it does survive, although that's not what I want.

Is there a way to do this?

Upvotes: 3

Views: 1381

Answers (2)

jfMR
jfMR

Reputation: 24738

In the recipe of the following rule:

%.test:%.mk
   @make -f $? || $(MAKE) [email protected]

make is called, and another new running instance of make is created. It is in that instance where the eval takes place. Therefore, it has no effect for the parent make instance that executed that recipe above.


Instead, you could create true .test.error files when an error occurs:

%.test:%.mk
   @make -f $? || touch [email protected]

and remove them when you are done:

run_tests: $(TESTS)
   @echo "Failures:" $(FAILURES)
   @$(RM) *.test.error

The definition of FAILURES could be then:

FAILURE = $(wildcard *.test.error)

That way, FAILURE will be expanded when run_tests recipe's is executed (i.e.: deferred expansion by using a recursively expanded variable) and therefore it will contain the list of the .test.error files (if any).

Upvotes: 1

HardcoreHenry
HardcoreHenry

Reputation: 6377

When you call $(MAKE) [email protected], it invokes a new instance of make, and FEATURES gets set there. The new value does not get propagated to the parent make.

I might suggest using a temporary file/folder as so:

.PHONY: prep
prep:
    rm -rf failures;
    mkdir failures;

%.test:%.mk: | prep
    @make -f $? || touch failures/[email protected]

run_tests: $(TESTS)
    @echo "Failures:"
    @cd failures && ls || true
    @rm -rf failures

Upvotes: 1

Related Questions