从父 CMakeLists.txt 覆盖 CMake 中的默认选项(...)值

Posted

技术标签:

【中文标题】从父 CMakeLists.txt 覆盖 CMake 中的默认选项(...)值【英文标题】:Overriding a default option(...) value in CMake from a parent CMakeLists.txt 【发布时间】:2011-04-15 13:39:42 【问题描述】:

我正在尝试在我的源代码树中包含几个第三方库,对它们的构建系统进行最小的更改以便于升级。他们都使用 CMake,我也是,所以在我自己的 CMakeLists.txt 中,我可以使用 add_subdirectory(extern/foo) 作为 libfoo。

但是 foo CMakeLists.txt 编译测试工具、构建文档、我不需要的共享库等等。 libfoo 作者有远见地通过选项控制这些 - 例如option(FOO_BUILD_SHARED "Build libfoo shared library" ON) - 这意味着我可以通过 CMake 命令行设置它们。但我想默认关闭它并通过命令行覆盖。

我在add_subdirectory(extern/foo) 之前尝试过set(FOO_BUILD_SHARED OFF)。这样做的效果是在第二次和后续构建尝试期间不尝试构建共享库,但在第一次尝试期间不尝试构建共享库,这是我真正需要加速的。

这可能吗,还是我需要为这些项目维护分叉的 CMakeLists.txt?

【问题讨论】:

【参考方案1】:

尝试在缓存中设置变量

SET(FOO_BUILD_SHARED OFF CACHE BOOL "Build libfoo shared library")

注意:您需要指定变量类型和描述,以便 CMake 知道如何在 GUI 中显示此条目。

【讨论】:

把它放在add_subdirectory命令之前,这样它会设置变量的默认值。 有时需要使用FORCE 专业提示(对我自己):FORCE 在文档字符串之后,而不是在中间随机... @Rajish 如果变量由于之前的 OPTIONSET( CACHE ) 调用或来自之前配置的 CMakeCache.txt 已被缓存,则必须使用 SET(FOO_BUILD_SHARED OFF CACHE BOOL "Build libfoo shared library" FORCE)。 source 内部不行吗?【参考方案2】:

这个问题很老了,但谷歌把我带到了这里。

SET(<variable name> <value> CACHE BOOL "" FORCE) 的问题在于它会将选项设置为项目范围。如果你想使用一个子项目,它是一个库,并且你想使用SET(... CACHE BOOL "" FORCE)为子项目(ParentLibrary)设置BUILD_STATIC_LIBS,它将为所有项目设置值。

我正在使用以下项目结构:

|CMakeLists.txt (root)
|- dependencies
   | CMakeLists.txt (dependencies)
   |- ParentLibrary
      | CMakeLists.txt (parent)
|- lib
   | CMakeLists.txt (lib)

现在我有CMakeLists.txt (dependencies),看起来像这样:

# Copy the option you want to change from ParentLibrary here
option (BUILD_SHARED_LIBS "Build shared libraries" ON)
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(ParentLibrary)

优点是我不必修改ParentLibrary,而且我可以只为那个项目设置选项。

必须从ParentLibrary 显式复制option 命令,否则在执行CMake 配置时,变量的值将首先由set 命令设置,然后该值将被覆盖option 命令,因为缓存中没有值。第二次执行 CMake 配置时,option 命令将被忽略,因为缓存中已经存在一个值,并且将使用来自set 命令的值。这会导致一些奇怪的行为,即两次 CMake 运行之间的配置会不同。

【讨论】:

好主意,但准确地说,该选项对依赖项下的所有子项目都有效,而不仅仅是一个。

以上是关于从父 CMakeLists.txt 覆盖 CMake 中的默认选项(...)值的主要内容,如果未能解决你的问题,请参考以下文章

CLion+CMake编写C++程序

在 CMake 中使用本地编译器标志

MAC: CMake compile CloudCompare error:By not providing "FindQt5PrintSupport.cmake" in CMAK

将 Makefile 转换为 CMakeLists.txt

ROS中的CMakeLists.txt

cmake 多级CMakeLists.txt调用