help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Order-only prereq versus sampling of target up-to-dateness.


From: Kaz Kylheku
Subject: Order-only prereq versus sampling of target up-to-dateness.
Date: Tue, 16 Mar 2021 09:50:29 -0700
User-agent: Roundcube Webmail/0.9.2

It looks like I have a question for a change.

I have this little situation I'm trying to fix:

tests is a target which depends on $(TEST_OK), which expands to a
collection of stamp files. Each stamp file is touched when its
corresponding test succeeds.  When a stamp file is up-to-date
with regard to the program, then that test is not executed.
Thus if we do "make -k tests", all working tests are identified
and "make tests" will not re-run them, unless the program is
rebuilt.

.PHONY: tests
tests: $(TESTS_OK)
   $(V)echo "** tests passed!"

Now I would like the retest target to blow away these files
(which are all in dedicated tst/) directory to force the tests
to be performed.

I had this working under non-parallel make, but it's defying
parallel make. This is what I came up with:

.PHONY: retest
retest: tests
retest: TXR_RETEST := y

The retest target depends on tests, and sets a target-specific
variable called TXR_RETEST.

Then, I made the $(TEST_OK) stamp files depend on a tests.clean
target, order-only:

$(TESTS_OK): | tests.clean

This test.clean will blow away those files, if the retest
target is active (which is known via the target-specific variable):

.PHONY: tests.clean
tests.clean:
   [ $(TXR_RETEST) ] && rm -rf tst || true

When "make retest" is invoked, we always see this fire before
the tests:

   [ y ] && rm -rf tst || true


Unfortunately, under parallel make, the behavior is weird.
When all the tests are up-to-date, make -j retest only forces
some small subset of the tests, considering the rest to be
up-to-date, even though their stamp files have all been
deleted by the above command.

It's as if the removal of the tst directory is racing with the
logic for determining whether the targets are up-to-date.

So that is to say, it's as if the rules

  tests: $(TESTS_OK)

  $(TESTS_OK): | tests.clean

are correctly processing the recipe of the order-only
pre-requisite tests.clean before executing the recipes for the
out-of-date $(TESTS_OK) targets. But the determination of
what $(TEST_OK) target need updating is not being ordered
with respect to the prerequisite; it's being done in parallel.
The assumption is that tests.clean does not do anything
which may invalidate any of the $(TESTS_OK) prerequisites.

This does correctly work for the example situation in the manual,
of using order-only to create a directory:

   $(OBJS): | objdir

   objdir:
      mkdir -p objs  # create directory for $(OBJS)

this is because even if evaluating $(OBJS) proceeds in parallel
with the mkdir, there is no conflict; the mkdir doesn't do anything
to invalidate the evaluation of $(OBJS).

If I'm reading this right, it seems it would be worth it for
the order-only | operator to be a more complete barrier, so that
until the order-only prerequisites of a rule are satisfied,
no other aspect of the rule is evaluated.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]