2012-08-22 130 views
0

我正在使用宏爲我的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已經有幾個問題了,但是他們沒有一個能夠解決我之後的問題。

回答

1

首先,你可以爲每個PCH創建目標,然後宣佈新的目標前使用此功能:

if(TARGET ${PCHFile}.gch) 

另一種方式:

在根的CMakeLists.txt:

set(PRECOMPILED_HEADERS "" CACHE INTERNAL "")

在宏中:

list(FIND PRECOMPILED_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/${PCHFile}.gch res) 
if(NOT res EQUAL -1) 
    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} 
    ) 
    list(APPEND PRECOMPILED_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/${PCHFile}.gch) 
endif() 
相關問題