【问题标题】:How to check whether include(CPack) is already being called before or not in CMake?如何检查在 CMake 中是否已经调用了 include(CPack)?
【发布时间】:2021-08-27 23:16:03
【问题描述】:

我正在开发一个使用第三方源作为子模块的项目。在 CMakeLists.txt 的第三方源中,他们的 CMakeLists.txt 中有 include(CPack),这会导致问题,因为当我在项目的 CMakeLists.txt 中编写自己的 include(CPack) 时,我会收到 cmake config 警告,例如

CPack.cmake has already been included!!

而且我写的所有CPack变量都被第三方源覆盖,导致我运行make package时出错

我尝试了add_subdirectory(third-party-source EXCLUDE_FROM_ALL),它忽略了第三方源中的所有install 调用,但不幸的是它没有忽略CPack 调用。

有没有办法让我添加类似的东西

if(CPACK_ALREADY_INCLUDED)
  include(CPack)
endif()

在第三方资源中解决这个问题?

【问题讨论】:

  • EXCLUDE_FROM_ALL 仅适用于在该目录及以下目录中创建的目标,因此绝对没有理由忽略include() 指令。

标签: cmake cpack


【解决方案1】:

推翻第 3 方的不当行为绝非易事。这就是为什么我个人不赞成add_subdirectory 而更喜欢使用vcpkg 或其他构建编排工具(如柯南)。

但是,以下 sn-p 应该可以工作:

function (add_third_party)
  # Write an empty CPack module
  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/override/CPack.cmake" "")
  set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_BINARY_DIR}/override;${CMAKE_MODULE_PATH}")
  add_subdirectory(third-party-source)
endfunction ()

add_third_party()

这将创建一个空白的 CPack 模块并诱使第三方代码包含它而不是标准模块。该函数的存在是为了确保这种覆盖行为不会泄漏到您的构建的其余部分中。


我误读了你的问题。我以为你控制着包含CPack的项目。

是的,变量名为CPack_CMake_INCLUDED。但是,最好检查一下你是否是顶级项目,并有条件地包含你的打包规则,如下所示:

string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" is_top_level)
option(MyProj_INCLUDE_PACKAGING "Include packaging rules for MyProj" "${is_top_level}")

if (MyProj_INCLUDE_PACKAGING)
    # ...
    include(CPack)
endif ()

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-03-05
  • 2020-07-07
  • 1970-01-01
  • 2011-10-17
  • 1970-01-01
  • 2019-01-07
  • 1970-01-01
  • 2013-08-20
相关资源
最近更新 更多