Build 如何在没有固定起点的依赖关系图中指定从何处开始

Build 如何在没有固定起点的依赖关系图中指定从何处开始,build,makefile,scons,Build,Makefile,Scons,我正在使用一个更像网络的工具链。有很多备选起点,所有这些都会产生一个最终输出 我通常使用make或scon——实际上,我更喜欢scon,但我的团队更喜欢make。我对其他构建工具持开放态度 例如,最终结果取决于倒数第二名 final_result: penultimate 倒数第二个可以用几种不同的方法中的任何一种进行: 如果从文件1开始,则 penultimate: file1 ; rule1 如果从文件2开始,则 penultimate: file2 ; rule2 问:如何指定从fi

我正在使用一个更像网络的工具链。有很多备选起点,所有这些都会产生一个最终输出

我通常使用make或scon——实际上,我更喜欢scon,但我的团队更喜欢make。我对其他构建工具持开放态度

例如,最终结果取决于倒数第二名

final_result: penultimate
倒数第二个可以用几种不同的方法中的任何一种进行:

如果从文件1开始,则

penultimate: file1 ; rule1
如果从文件2开始,则

penultimate: file2 ; rule2
问:如何指定从file2开始,而不是file1

我想我可以使用命令行开关和ifdeffing。但我更愿意让make或scons明白“嘿,有一个file2,所以我应该使用rule2,而不是fil1/rule1”。部分原因是网络比这复杂得多

更糟糕的是,有时一条路径上的中间路径可能是另一条路径上的起点。让我们看看:

A.s产生一个.diag

foo.diag: foo.s
但有时没有。s,我只是有一个。诊断,别人给我已经建立

diag生成一个.heximg和一个.hwresult

foo.hwresult: hwsim foo.heximg

foo.heximg: foo.diag
但有时我会直接得到一个.img

等等

我只想写一个整体的依赖关系图,然后说“好的,现在这是我得到的——现在你如何得到最终的结果?”


就我现在所拥有的,当我得到一个foo.img时,我会被告知(在本例中是make)“foo.s not dfound”。因为make想回到依赖关系图中去判断foo.img是否过时,而我想说“假设foo.img是最新的,并且为依赖foo.img的东西工作,而不是回到foo.img依赖的东西。”

你必须用模式规则(隐式规则)来完成这一切。如果指定了显式规则,则make会考虑硬依赖项,如果不满足依赖项的某些部分,make将失败

如果使用隐式规则,那么将考虑建立目标的可能方法。如果这种方法不起作用(因为某些先决条件不存在,make不知道如何构建它),make将尝试另一种方法。如果没有办法,并且目标已经存在,make将只使用该目标而不必更新它

您还说“a.diag生成一个.heximg和一个.hwresult”,然后给出了一个奇怪的makefile语法示例,我不知道,但仅供参考,对于模式规则,您可以指定一个命令生成多个输出(使用显式规则无法做到这一点):


坏消息是:在GNU make中定义隐式规则的唯一方法是如果文件名中有一个公共的“词干”。也就是说,您可以编写一个隐式规则,通过编写模式规则“%.heximg:%.diag”将foo.diag转换为foo.heximg,因为它们有一个公共词干“foo”,但无法为从“foo1”到“倒数第二”的编译创建模式规则,因为它们不共享一个公共词干。

您必须使用模式规则完成所有操作(隐式规则)。如果指定了显式规则,则make会考虑硬依赖项,如果不满足依赖项的某些部分,make将失败

如果使用隐式规则,那么将考虑建立目标的可能方法。如果这种方法不起作用(因为某些先决条件不存在,并且不知道如何构建),那么尝试另一种方式。如果没有方法工作,并且目标已经存在,则只需使用该目标而不必更新它。

您还说“a.diag生成一个.heximg和一个.hwresult”,然后给出了一个奇怪的makefile语法示例,我不知道,但仅供参考,对于模式规则,您可以指定一个命令生成多个输出(使用显式规则无法做到这一点):


坏消息是:在GNU make中定义隐式规则的唯一方法是如果文件名中有一个公共的“stem”。也就是说,您可以编写一个隐式规则,通过编写模式规则“%.heximg:%.diag”将foo.diag转换为foo.heximg,因为它们有一个公共的stem“foo”,但无法为从“foo1”到“倒数第二”的编译创建模式规则,因为它们没有共同的词干。

我不确定,但您可能正在寻找:

双冒号规则是用
而不是目标名称后的
编写的显式规则。当同一目标出现在多个规则中时,它们的处理方式与普通规则不同

双冒号规则有些晦涩,通常也不是很有用;它们提供了一种机制,用于更新目标的方法因导致更新的前提文件而异,而这种情况很少发生


我不确定,但可能您正在寻找:

双冒号规则是用
而不是目标名称后的
编写的显式规则。当同一目标出现在多个规则中时,它们的处理方式与普通规则不同

双冒号规则有些晦涩,通常也不是很有用;它们提供了一种机制,用于更新目标的方法因导致更新的前提文件而异,而这种情况很少发生


实际上,有多个最终输出。我只是想简化。事实上,有多个最终输出。我只是想简化。谢谢。修复了伪示例“a.diag生成一个.heximg和一个.hwresult”中的错误(这是一个伪示例,因为我没有提供规则,尝试删除东西)。我必须承认,我可以发誓,使用明确的规则,您可以指定多个输出。必须阅读/测试。不。您可以编写类似“foo-bar-biz:baz;command”的规则,但这并不意味着一次调用就可以将“baz”转换为文件“foo”、“bar”和“biz”。上面是编写3条规则的简写:“foo:baz;command”,“bar:baz;command”和“biz:baz;command”。换句话说,将运行3
%.heximg %.hwresult: %.diag