【问题标题】:How to pass C/CXX flags to an external project in CMake如何将 C/CXX 标志传递给 CMake 中的外部项目
【发布时间】:2019-05-28 12:28:33
【问题描述】:

我正在使用 CMake 来驱动项目的构建,但是有一些子项目需要使用自动工具来构建。我使用 CMake 中的 ExternalProject 功能来构建它,但我无法将完整的默认 C/CXX 标志集传递给子项目的配置脚本。

目前我只传递 CMAKE_C_FLAGS、CMAKE_CXX_FLAGS 等。问题是这不包括特定于 build_type 的标志,这会导致在使用调试信息(例如)编译时出现问题,因为我必须手动传播 -g 标志.

当前外部项目配置如下:

ExternalProject_Add(
  openthread-build
  SOURCE_DIR ${openthread_SOURCE_DIR}
  BINARY_DIR ${openthread_BINARY_DIR}
  CONFIGURE_COMMAND cd ${openthread_SOURCE_DIR}
        COMMAND ${openthread_SOURCE_DIR}/configure ${OPENTHREAD_CONFIGURE_OPTS}
        "CXX=${CMAKE_CXX_COMPILER}"
        "CPP=${CMAKE_C_COMPILER} -E"
        "CC=${CMAKE_C_COMPILER}"
        "AR=${CMAKE_C_COMPILER_AR}"
        "RANLIB=${CMAKE_C_COMPILER_RANLIB}"
        "NM=${CMAKE_NM}"
        "STRIP=${CMAKE_STRIP}"
        "CFLAGS=${CMAKE_C_FLAGS} ${OPENTHREAD_INCLUDE_ARG}"
        "CPPFLAGS=${CMAKE_C_FLAGS} ${OPENTHREAD_INCLUDE_ARG}"
        "CXXFLAGS=${CMAKE_CXX_FLAGS} ${OPENTHREAD_INCLUDE_ARG}"
        "LDFLAGS=${CMAKE_EXE_LINKER_FLAGS}"
        "--host=${MACHINE_NAME}"
  BUILD_COMMAND ${OPENTHREAD_MAKE} ${OPENTHREAD_MAKE_ARGS}
  BUILD_ALWAYS ON
  DOWNLOAD_COMMAND  cd ${openthread_SOURCE_DIR} && ./bootstrap
  INSTALL_COMMAND   ""
  TEST_COMMAND      ""
)

问题行如下:

"CFLAGS=${CMAKE_C_FLAGS} ${OPENTHREAD_INCLUDE_ARG}"

理想情况下可能是 ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}},但由于变量名区分大小写,这不起作用。

"CFLAGS=${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}} ${OPENTHREAD_INCLUDE_ARG}"

所以我猜最后的选择是编写一个形成CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE} 的函数,将其转换为大写然后展开它,但这似乎很笨重。

是否有任何简单的方法可以将默认的基本 C/CXX 标志集传递给外部项目,而无需对每种构建类型进行手动硬编码或添加功能?我希望包含用于构建类型的默认 CMAKE_C_FLAGS 和 CMAKE_C_FLAGS_*。

【问题讨论】:

  • 我可能在这里遗漏了一些东西。 CMake 文档说CMAKE_BUILD_TYPE 已经控制CMAKE_C_FLAGS_DEBUGCMAKE_C_FLAGS_RELEASE 是否包含在CMAKE_C_FLAGS 中。你手动覆盖它吗?
  • 我同意 CMake 文档确实这么说,但在实践中似乎并没有发生。我在刚才提到的项目中确实使用了工具链文件,但我只是尝试了另一个没有工具链的项目并得到: ${CMAKE_C_FLAGS} = "", ${CMAKE_C_FLAGS_DEBUG} = "-g", ${CMAKE_BUILD_TYPE} = "Debug"
  • 我还注意到,使用 CMake 构建的实际文件使用正确的完整标志,包括 build_type 标志。
  • 我认为来自CMAKE_BUILD_TYPE 文档的CMake will see to having CMAKE_C_FLAGS_DEBUG settings get added to the CMAKE_C_FLAGS settings. 可能措辞不当。它不会更新变量CMAKE_C_FLAGS,这会破坏多配置生成器。当用于生成构建文件时,它将每个配置设置添加到 CMAKE_C_FLAGS 设置中。

标签: cmake


【解决方案1】:

我仍然对其他答案持开放态度,但目前我已决定创建 build_type 的大写版本,并使用它来提取 build_type 特定标志。

# get an uppercase version of the build type, for extracting build_type specific flags
if(CMAKE_BUILD_TYPE)
    string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE_UC)
endif()

所以各个标志线看起来像:

"CFLAGS=${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${BUILD_TYPE_UC}} ${OPENTHREAD_INCLUDE_ARG}"

完整的 externalproject 调用非常拥挤,但看起来像:

ExternalProject_Add(
  openthread-build
  SOURCE_DIR ${openthread_SOURCE_DIR}
  BINARY_DIR ${openthread_BINARY_DIR}
  CONFIGURE_COMMAND cd ${openthread_SOURCE_DIR}
        COMMAND ${openthread_SOURCE_DIR}/configure ${OPENTHREAD_CONFIGURE_OPTS}
        "CXX=${CMAKE_CXX_COMPILER}"
        "CPP=${CMAKE_C_COMPILER} -E"
        "CC=${CMAKE_C_COMPILER}"
        "AR=${CMAKE_C_COMPILER_AR}"
        "RANLIB=${CMAKE_C_COMPILER_RANLIB}"
        "NM=${CMAKE_NM}"
        "STRIP=${CMAKE_STRIP}"
        "CFLAGS=${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${BUILD_TYPE_UC}} ${OPENTHREAD_INCLUDE_ARG}"
        "CPPFLAGS=${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${BUILD_TYPE_UC}} ${OPENTHREAD_INCLUDE_ARG}"
        "CXXFLAGS=${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BUILD_TYPE_UC}} ${OPENTHREAD_INCLUDE_ARG}"
        "LDFLAGS=${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_${BUILD_TYPE_UC}}"
        "--host=${MACHINE_NAME}"
  BUILD_COMMAND ${OPENTHREAD_MAKE} ${OPENTHREAD_MAKE_ARGS}
  BUILD_ALWAYS ON
  DOWNLOAD_COMMAND  cd ${openthread_SOURCE_DIR} && ./bootstrap
  INSTALL_COMMAND   ""
  TEST_COMMAND      ""
)

【讨论】:

  • 如果CMAKE_BUILD_TYPE 为空,当前的行为是变量CMAKE_C_FLAGS_ 不存在,因此扩展为空。如果我遵循您的建议 @VictorSergienko ,那么变量 CMAKE_C_FLAGS 将扩展为基本标志集,这些标志已经包含在该行的前面。
猜你喜欢
  • 2014-06-05
  • 1970-01-01
  • 2019-04-14
  • 1970-01-01
  • 2016-08-08
  • 2018-01-03
  • 1970-01-01
  • 2012-08-23
  • 2018-02-15
相关资源
最近更新 更多