从父CMakeLists.txt覆盖CMake中的默认option(…)值


69

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

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

我以前尝试set(FOO_BUILD_SHARED OFF)add_subdirectory(extern/foo)。这样的效果是,在第二次及以后的构建尝试中不尝试构建共享库,而在第一次构建时则不尝试,这是我真正需要加快的速度。

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

Answers:


83

尝试在CACHE中设置变量

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

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


12
将其放在add_subdirectory命令之前,以便它将设置变量的默认值。
tibur 2010年

10
有时您需要使用FORCE
Rajish

6
专业提示(对我自己):FORCE在文档字符串之后,而不是在中间随机出现……
Claudiu

7
@Rajish如果由于先前的配置OPTIONSET( CACHE )调用或来自先前配置的CMakeCache.txt而已将变量缓存,则必须使用SET(FOO_BUILD_SHARED OFF CACHE BOOL "Build libfoo shared library" FORCE)来源
2016年

INTERNAL不会吗?
Zingam

3

这个问题比较老,但是Google将我带到了这里。

问题SET(<variable name> <value> CACHE BOOL "" FORCE)在于它将设置选项项目的范围。如果要使用子项目(即库),并且要BUILD_STATIC_LIBS为子项目(ParentLibrary)进行SET(... CACHE BOOL "" FORCE)设置,则将为所有项目设置值。

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

|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,而只能为该项目设置选项。

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


好主意,但准确地说,该选项将对依赖项下的所有子项目有效,而不仅仅是一个。
托马斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.