2014-09-25 199 views
2

我在Cmake中使用configure_file命令進行功能可用性檢查,如on this page所述。這頁建議使用的命令是這樣的:讓編譯器找到Cmake創建的文件

configure_file(config.h.in config.h) 

這將轉化${CMAKE_CURRENT_SOURCE_DIR}/config.h.in${CMAKE_CURRENT_BINARY_DIR}/config.h。但是,當我編譯我的程序時,編譯器僅在${CMAKE_CURRENT_SOURCE_DIR}中查找標題(例如config.h),而不是在${CMAKE_CURRENT_BINARY_DIR}中查找。所以很自然,編譯器沒有找到config.h它生成的位置,並且構建失敗。

解決此問題的標準方法是什麼?我應該更改CMakeLists.txt,以便在源目錄中創建config.h?或者我應該改變它以將構建目錄添加到包含路徑? (真的,爲什麼我必須手動處理這個問題?[半修辭問題])

This question涉及類似的問題,但兩種選項都被認爲是可能的解決方案;我想知道是否有標準的做法,或者如果這表明我錯過了Cmake的使用方法。

+0

對於出源的構建,添加'include_directories($ {CMAKE_CURRENT_BINARY_DIR})'。 – 2014-09-25 03:40:45

回答

6

保持你的源代碼樹'原始'是正確的,而不是'錯誤'如果你想做多個不同的構建,或者如果你想能夠清理構建通過rm'ing構建目錄(如果你正在向源目錄生成東西,則不夠用)。

在構建目錄中生成它並添加包含路徑。

設置變量

set(CMAKE_INCLUDE_CURRENT_DIR ON) 
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) 

使自動添加每個源目錄對應的build目錄,並做出對其他目標的傳遞行爲,消費(這樣foo沒有添加例如明確指定bar的目錄)。

http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html#build-specification-and-usage-requirements

3

我不認爲有一個標準的方式來處理這個問題,但是從我自己對其他項目的有限看法來看,似乎並不是絕大多數的這種或那種方式。如果我猜測,我認爲將生成的文件放置在構建樹而不是源碼樹中更爲常見。

爲了清楚起見,我自己的選擇是把它放在一個像${CMAKE_CURRENT_BINARY_DIR}/GeneratedFiles/config.h的子目錄中。這樣可以避免所有子目錄${CMAKE_CURRENT_BINARY_DIR}出現在像Visual Studio這樣的IDE自動完成列表中。它還可以讓你的構建根本更清潔一些,特別是如果你最終生成了幾個生成的文件。你必須先創建目錄:

set(GeneratedFilesDir "${CMAKE_CURRENT_BINARY_DIR}/GeneratedFiles") 
file(MAKE_DIRECTORY ${GeneratedFilesDir}) 

set(ConfigFile "${GeneratedFilesDir}/config.h") 
configure_file(config.h.in ${ConfigFile}) 


然後你可以或許做多一點「惹事」使用target_include_directories而不是include_directories。例如,如果config.h中僅由庫MyLib內部使用,你可以這樣做:

add_library(MyLib ${ConfigFile} ... other sources ...) 
target_include_directories(MyLib 
    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ${GeneratedFilesDir} 
    PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) 

與使用include_directories,這避免了${GeneratedFilesDir}爲包括路徑上的所有目標。當所生成的文件需要被公開爲公共頭,或添加到install命令


事情變得更有爭議的。最終,我不認爲這裏有一個「錯誤」的選擇。歸結起來,你是否覺得保持源代碼樹更好,而不是以更復雜的CMake安裝爲代價。