CMake中的条件add_custom_command

时间:2012-08-22 08:03:37

标签: cmake

我正在使用宏为我的cmake项目创建预编译头文件。对于gcc,此宏使用add_custom_command创建一个* .h.gch文件,然后可以使用add_executable / add_library将其与其他源文件一起添加到目标。问题是有时相同的* .h.gch文件用于两个不同的目标,因为一些库既是静态库也是动态库。

我需要在每次add_library调用之后调用宏,因为对于MSVC / Xcode,需要调整目标属性以启用PCH使用/编译。但对于gcc,这会导致错误,因为我正在尝试将add_custom_command与已具有构建规则(.gch)的输出一起使用。目前我通过为其名称中包含“静态”的任何目标跳过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 个答案:

答案 0 :(得分: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()