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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3766740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:39:07  来源:igfitidea点击:

Overriding a default option(...) value in CMake from a parent CMakeLists.txt

c++buildbuild-processcmake

提问by pkit

I am trying to include several third-party libraries in my source tree with minimal changes to their build system for ease of upgrading. They all use CMake, as do I, so in my own CMakeLists.txt I can use add_subdirectory(extern/foo)for libfoo.

我试图在我的源代码树中包含几个第三方库,并对其构建系统进行最少的更改,以便于升级。他们和我一样都使用 CMake,所以在我自己的 CMakeLists.txt 中我可以add_subdirectory(extern/foo)用于 libfoo。

But the foo CMakeLists.txt compiles a test harness, builds documentation, a shared library which I don't need, and so on. The libfoo authors had the foresight to control these via options - option(FOO_BUILD_SHARED "Build libfoo shared library" ON)for example - which means I can set them via the CMake command line. But I would like to make that off by default and overridable via the command line.

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

I have tried doing set(FOO_BUILD_SHARED OFF)before add_subdirectory(extern/foo). That has the effect of not trying to build the shared library during the second and subsequent build attempts, but not during the first one, which is the one I really need to speed up.

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

Is this possible, or do I need to maintain forked CMakeLists.txt for these projects?

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

回答by pkit

Try setting the variable in the CACHE

尝试在 CACHE 中设置变量

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

Note: You need to specify the variable type and a description so CMake knows how to display this entry in the GUI.

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

回答by Martin Stolpe

This question is rather old but Google brought me here.

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

The problem with SET(<variable name> <value> CACHE BOOL "" FORCE)is that it will set the option project wide. If you want to use a sub-project, which is a library, and you want to set BUILD_STATIC_LIBSfor the sub-project (ParentLibrary) using SET(... CACHE BOOL "" FORCE)it will set the value for all projects.

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

I'm using the following project structure:

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

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

Now I have CMakeLists.txt (dependencies)which looks like this:

现在我有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)

Advantage is that I don't have to modify ParentLibraryand that I can set the option only for that project.

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

It is necessary to explicitly copy the optioncommand from the ParentLibraryas otherwise when executing CMake configuration initially the value of the variable would first be set by the setcommand and later the value would be overwritten by the optioncommand because there was no value in the cache. When executing CMake configuration for the second time the optioncommand would be ignored because there is already a value in the cache and the value from the setcommand would be used. This would lead to some strange behavior that the configuration between two CMake runs would be different.

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