我有一个项目,其中包括一个代码生成器,它从一个输入文件生成多个 .c 和 .h 文件,只需调用一次代码生成器。我有一条规则,其中 .c 和 .h 文件作为多个目标,输入文件作为先决条件,配方是代码生成器的调用。然后我有进一步的规则来编译和链接生成的 .c 文件。
这适用于 -j 因子 1,但如果我增加 j 因子,我发现我会多次调用代码生成器,直到 -j 因子或预期目标文件的数量,以最小者为准。这很糟糕,因为代码生成器的多次调用可能会由于生成的代码被多次编写而导致失败。
我不打算在这里发布我的实际(大)代码,但我已经能够构建一个看起来展示相同行为的小示例。
Makefile 看起来像这样:
输出.concat:输出5输出4输出3输出2输出1 猫 $^ > $@ 输出1 输出2 输出3 输出4 输出5:输入 ./frob 输入 干净的: rm -rf 输出*
对于这个示例,我编写了一个简单的 shell 脚本,而不是代码生成器,frob
它从一个输入文件生成多个输出文件:
#!/bin/bash 对于 {1..5} 中的 i;做 { echo "这是输出 ${i},从 ${1} 生成。输入是:" 猫 ${1} } > 输出${i} 完毕
当我使用非 unity -j 因素运行此 Makefile 时,我得到以下输出:
$使-j2 ./frob 输入 ./frob 输入 cat output5 output4 output3 output2 output1 > output.concat $
我们看到./frob
这里被调用了两次,这很糟糕。有没有什么方法可以构建这个规则,使得配方只被调用一次,即使是非统一的 -j 因素?
我已经考虑更改规则,以便只有一个预期的输出文件是目标,然后添加另一个没有配方的规则,使其目标是剩余的预期输出文件,并且先决条件是第一个预期的输出文件。但我不确定这是否可行,因为我不知道我是否可以保证生成文件的顺序,因此可能会导致循环依赖。