2012-08-22 135 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() 
相关问题