help-make
[Top][All Lists]
Advanced

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

Re: Make's assumption that files it does not create do not change


From: Kaz Kylheku
Subject: Re: Make's assumption that files it does not create do not change
Date: Tue, 12 Apr 2022 14:58:58 -0700
User-agent: Roundcube Webmail/1.4.13

On 2022-04-12 08:18, Sébastien Hinderer wrote:
Dear all,


I forgot to address the issue hinted at in the subject: additional
files being changed in recipes that are not targets.

Newer GNU Make has "grouped targets" for this expressed using &:.

I implemented that feature.

I also somewhat regret implementing the feature because it is unnecessary.
The feature is built on the the implementation of pattern rules, which
already supported multiple targets many years before &:.

"grouped targets" makes this possible for direct rules
(make terminology for rules that reference concrete files,
rather than patterns). For instance:

  # both y.tab.c and y.tab.h are made from parser.y

  y.tab.c y.tab.h &: parser.y

Similarly, pattern rules can already have multiple targets,
and that is supported in older versions of GNU Make than
you will ever care to use.

For instance, you have probably seen rules like:

   # A .in and .data file produces a .foo and .bar

   %.foo %.bar: %.in %.data

The limitation in pattern rules is that all the
targets and prerequisites must include some common stem,
indicated by the % character.

Here where I was mistaken in the implementation of &:
believing that to be some kind of deep limitation.

The key insight is that the % stem can be anything.
It doesn't have to be the important part of the name.

For instance, let's reconsider:

  y.tab.c y.tab.h &: parser.y

look, all the objects involved here have a character in
common, the letter 'y'. So that can be the stem.

  %.tab.c %.tab.h : parser.%

If you can find a common stem (which is next to always),
you can use a pattern rule.

The results may look wacky, but the pattern matching
doesn't care.

For instance suppose we wanted to make the files
"alpha" and "bravo", from "charlie" and "delta".

Just use the common character "a" as the stem!

This letter may be a coincidence, and the rule looks weird;
but the pattern matching doesn't care. It works, and the
mechanism by which it works is very straightforward:

Here is a complete sample Makefile:

%lpha br%vo: ch%rlie delt%
        @echo build alpha and bravo from charlie and delta

whole: part alpha
        @echo build $@ from $^

part: bravo
        @echo build $@ from $^

We ensure that the prerequisites charlie and delta
exist and run it:

$ touch charlie delta
$ make
build alpha and bravo from charlie and delta
build part from bravo
build whole from part alpha

whole needs part, which needs bravo. Make does not have a
direct rule for making bravo, so it searches through pattern
rules. It sees, aha br%vo matches bravo, with stem "a".

It instantiates the entire pattern by inserting the stem into
it, and, lo and behold: the concrete rule materializes:
the rule's prerequisites become charlie and delta. These
files are found to exist, and so the rule can proceed.

The only situation in which you would need the &: feature is when
no common stem exists. (The stem may not be the empty string; it
that were the case, it could always be found.) Furthermore, the
situation has to be such that for some reason you cannot adjust
any of the names in order to ensure there is a common stem.

Cheers ...






reply via email to

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