最可能的情况是您尝试编译同一个文件两次,但属性略有不同。例如
exe a : a.cpp : <include>/usr/local/include ; exe b : a.cpp ;
以上代码片段需要对 a.cpp
进行两次不同的编译,它们仅在 include
属性上有所区别。由于 include
特性被声明为 free
,Boost.Build 不会为每个值创建单独的构建目录,因此这两个构建都将在同一个构建目录中生成目标文件。忽略这一点,只编译一次文件将非常危险,因为不同的包含可能会导致完全不同的代码被编译。
要解决此问题,您需要确定是否应该编译一次或两次文件。
要仅编译一次文件,请确保两个目标请求的属性相同
exe a : a.cpp : <include>/usr/local/include ; exe b : a.cpp : <include>/usr/local/include ;
或者
alias a-with-include : a.cpp : <include>/usr/local/include ; exe a : a-with-include ; exe b : a-with-include ;
或者如果您希望 includes
属性不影响为构建的 a
和 b
可执行文件添加的任何其他源代码的编译方式
obj a-obj : a.cpp : <include>/usr/local/include ; exe a : a-obj ; exe b : a-obj ;
请注意,在这两种情况下,include
属性将仅用于构建这些目标文件,而不会用于为目标 a
和 b
添加的任何其他源代码。
要编译两次文件,您可以告诉 Boost.Build 将其编译到两个单独的目标文件中,如下所示
obj a_obj : a.cpp : <include>/usr/local/include ; obj b_obj : a.cpp ; exe a : a_obj ; exe b : b_obj ;
或者您可以将目标文件目标设为主目标的局部目标
exe a : [ obj a_obj : a.cpp : <include>/usr/local/include ] ; exe b : [ obj a_obj : a.cpp ] ;
这将导致 Boost.Build 为您稍微更改生成的物体文件名称,从而避免任何冲突。
请注意,在这两种情况下,include
属性将仅用于构建这些目标文件,而不会用于为目标 a
和 b
添加的任何其他源代码。
一个很好的问题是为什么 Boost.Build 不能自动使用上述方法。问题在于这种魔法只会在一半的情况下有效,而在另一半情况下它会默默地做错事。在这种情况下,向用户询问他/她的意图更简单、更安全。