如何检查 include(CPack) 之前是否已经在 CMake 中被调用?

How to check whether include(CPack) is already being called before or not in CMake?

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

的 cmake 配置警告
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()

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

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

但是,以下代码段应该有效:

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 ()