【问题标题】:Conditional add_custom_command in CMakeCMake 中的条件 add_custom_command
【发布时间】:2012-08-22 08:03:36
【问题描述】:

我正在使用宏为我的 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 已经有几个问题,但似乎没有一个能完全解决我所追求的问题。

【问题讨论】:

    标签: cmake cmake-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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      • 1970-01-01
      相关资源
      最近更新 更多