![]() |
最有可能的情況是您嘗試以幾乎相同但屬性不同的方式編譯相同檔案兩次。例如
exe a : a.cpp : <include>/usr/local/include ; exe b : a.cpp ;
以上程式碼片段需要對 a.cpp
進行兩次不同的編譯,它們只在 include
屬性方面有所不同。由於 include
功能宣告為 free
Boost.Build 沒有為每個值建立獨立的建置目錄,因此這兩個建置都會在相同的建置目錄中產生物件檔。忽略它並且只編譯檔案一次會很危險,因為不同的 include 程式碼可能會導致編譯出完全不同的程式碼。
若要解決這個問題,您需要決定該檔案是要編譯一次或兩次。
若要只編譯檔案一次,請確定 target 要求的屬性都相同
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 無法自動使用上述方法中的某種方法。問題在於,這樣的魔法只對一半的情況有所幫助,而對另一半的情況,這種魔法會在靜默情況下執行錯誤的工作。在這種情況下,讓使用者說明其意圖會更簡單、更安全。