我正在使用宏爲我的cmake項目創建預編譯頭。對於gcc,這個宏使用add_custom_command創建一個* .h.gch文件,然後可以通過add_executable/add_library將其添加到目標以及其他源文件。問題是,有時相同的* .h.gch文件被用於兩個不同的目標,因爲一些庫被構建爲靜態和動態庫。CMake中的條件add_custom_command
我需要在每個add_library調用之後調用宏,因爲對於MSVC/Xcode,需要調整目標屬性以啓用PCH使用/編譯。但是對於gcc,這會導致錯誤,因爲我試圖將add_custom_command用於已經有構建規則(.gch)的輸出。目前,我通過跳過名稱中包含「Static」的任何目標的add_custom_command來避免此錯誤 - 因爲項目中的所有靜態庫都有一個「靜態」後綴,但這顯然不起作用,但它顯然不是一個非常優雅的解決方案。
cmake有沒有辦法檢查一個目標是否已經有一個構建規則,或者一種方法來允許add_custom_command默默地失敗而不會導致錯誤?或者有沒有辦法改變我的設計,以便我可以完全避免這個問題?我想一個「解決方案」是在每個CMakeLists中添加一個條件檢查,但我真的不想這樣做。
這是我目前使用的代碼:
宏:
macro(SET_PRECOMPILED_HEADER targetName PCHFile)
if(MSVC)
# PCH for MSVC
elseif(${CMAKE_GENERATOR} MATCHES "Xcode")
# PCH for Xcode
else() #gcc
if(NOT ${targetName} MATCHES "Static") ## <-- this is bad
## set the correct "compilerArgs"
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PCHFile}.gch
COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} ${compilerArgs}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${PCHFile}
)
endif()
endmacro(SET_PRECOMPILED_HEADER targetName PCHFile)
...然後在CMakeLists,像這樣:
# Dynamic version:
set(MODULE_NAME MyLib)
project(${MODULE_NAME})
## set ${sources}
add_library(${MODULE_NAME} SHARED ${sources} "src/precompiled.h.${PCH_EXT}")
set_target_properties(${MODULE_NAME} PROPERTIES COMPILE_DEFINITIONS MY_DLL_DEFINITION)
SET_PRECOMPILED_HEADER(${MODULE_NAME} "src/precompiled.h")
# Static version:
set(MODULE_NAME MyLibStatic)
project(${MODULE_NAME})
add_library(${MODULE_NAME} ${sources} "src/precompiled.h.${PCH_EXT}")
set_target_properties(${MODULE_NAME} PROPERTIES COMPILE_DEFINITIONS MY_STATIC_DEFINITION)
SET_PRECOMPILED_HEADER(${MODULE_NAME} "src/precompiled.h")
感謝您的幫助!對不起,如果這是重複的 - 關於add_custom_command已經有幾個問題了,但是他們沒有一個能夠解決我之後的問題。