I have a project that includes a code generator that generates several .c and .h files from one input file with just one call to the code generator. I have a rule that has .c and .h files as several targets, the input file as a prerequisite, and the recipe is a call to the code generator. Then I have additional rules for compiling and linking the generated .c files.
This works fine with -j factor 1, but if I increase the coefficient j, I find that I get multiple calls to the code generator, down to the -j factor or the number of expected target files, whichever is the smallest, This is bad, because that multiple calls to the code generator can cause failures due to the fact that the generated code is written several times.
I will not post my actual (large) code here, but I managed to create a small example that seems to exhibit the same behavior.
The Makefile is as follows:
output.concat: output5 output4 output3 output2 output1
cat $ ^> $@
output1 output2 output3 output4 output5: input
./frob input
clean:
rm -rf output *
Instead of the code generator for this example, I wrote a simple shell script, frob , that generates multiple output files from a single input file:
#! / bin / bash
for i in {1..5}; do
{
echo "This is output $ {i}, generated from $ {1}. input was:"
cat $ {1}
}> output $ {i}
done
When I run this Makefile with factors other than one, I get the following output:
$ make -j2
./frob input
./frob input
cat output5 output4 output3 output2 output1> output.concat
$
We see that ./frob is called twice here, which is bad. Is there a way I can build this rule so that the recipe is called only once, even with the non-unity coefficient -j?
I examined a rule change, so that only one of the expected output files is the target, and then adds another rule without a prescription, so that its goal is the remaining expected output files, and the precondition is the first expected output file. But Iβm not sure if this will work, because I donβt know if I can guarantee the order in which the files are created, and therefore can end up with circular dependencies.