Skip to content

Conversation

kazinator-arista
Copy link

The meta/Makefile contains several rules which are not correct for parallel make. These rules contain several targets to the left of the colon, and express the intent that the targets are built together as a group. Unfortunately, that's not what the syntax means: Rather:

t1 t2 t3 : prereq
recipe # recipe generates all three!

is essentially a syntactic sugar condensing multiple rules with the same recipe and prerequisites:

t1 : prereq
recipe # recipe generates all three!

t2 : prereq
recipe

t3 : prereq
recipe

Under parallel make these rules fire in parallel which can wreak havoc, since they stomp on each other's files.

The issue can be addressed using the grouped targets feature:

t1 t2 t3 &: prereq
recipe # recipe generates all three!

The ampersand-colon separator &: means that there is only one rule here which Make understands to be updating all three targets.

This feature has been available since GNU Make 4.2.90. Ubuntu-latest is on 4.3.

(The grouped targets feature was the subject of a bugfix before 4.4. The bug potentially causes a grouped target not to be remade if it is deleted. This is minor problem because it's not expected that someone will be deleting, say, the generated file saimetadata.c individually rather than doing a "make clean" which deletes all the generated files.)

The meta/Makefile contains several rules which are not correct
for parallel make. These rules contain several targets to the
left of the colon, and express the intent that the targets are
built together as a group. Unfortunately, that's not what the
syntax means:  Rather:

   t1 t2 t3 : prereq
           recipe # recipe generates all three!

is essentially a syntactic sugar condensing multiple rules
with the same recipe and prerequisites:

   t1 : prereq
           recipe # recipe generates all three!

   t2 : prereq
           recipe

   t3 : prereq
           recipe

Under parallel make these rules fire in parallel which can
wreak havoc, since they stomp on each other's files.

The issue can be addressed using the grouped targets feature:

   t1 t2 t3 &: prereq
           recipe # recipe generates all three!

The ampersand-colon separator &: means that there is only one
rule here which Make understands to be updating all three
targets.

This feature has been available since GNU Make 4.2.90.
Ubuntu-latest is on 4.3.

(The grouped targets feature was the subject of a bugfix before
4.4. The bug potentially causes a grouped target not to be
remade if it is deleted.  This is minor problem because it's
not expected that someone will be deleting, say, the generated
file saimetadata.c individually rather than doing a "make clean"
which deletes all the generated files.)

Signed-off-by: Kaz Kylheku <[email protected]>
@kcudnik
Copy link
Collaborator

kcudnik commented Aug 30, 2025

Not all targets are compatible for parallel execution, since some files are created by the same process example parse.pl

@kazinator-arista
Copy link
Author

Not all targets are compatible for parallel execution, since some files are created by the same process example parse.pl

The grouped target semantics fixes this because with :&, make is informed that the single recipe is updating all targets. The dependency is correctly expressed for parallel execution.

However, if that makes you nervous, you can always put a .NOTPARALLEL: special target at the top of the Makefile, which overrides the -j option. Then if the Makefile does what we want, that actual behavior is repeatable, even if the dependencies are not all correct.

(That's usually my first instinct when I'm locally dealing with Makefile races in third party code; but I don't want to tell people they should actually upstream a change that disables their parallel build.)

@kcudnik
Copy link
Collaborator

kcudnik commented Sep 3, 2025

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants