CMake不可配置选项

bksxznpy  于 2023-03-02  发布在  其他
关注(0)|答案(3)|浏览(168)

在CMake中,如何定义一个用户无法配置但自动计算的选项?
我想做以下几点:

if (FOO AND NOT BAR)
    option(BOO "Foo and not bar" ON)
endif()

然后我可以在不同的CMake文件中使用BOO

if (BOO)
    # do something
endif()

也在来源:

#ifdef BOO
// do something
#endif

因此,BOO的行为类似于常规选项,但它是自动计算的,用户运行cmake时无法进行配置。

编辑:我现在意识到选项在源代码中并不是隐式可用的,而是需要用target_add_definitions或其他方式显式定义。所以现在很明显,解决方案是将BOO定义为CMake变量,而不是选项。

bqf10yzr

bqf10yzr1#

您的“non-user-configurable”选项听起来像一个变量,您可以创建如下:

if(FOO AND NOT BAR)
  set(BOO TRUE)
else()
  set(BOO FALSE)
endif()

要在C代码中使用这个变量,你需要告诉CMake创建一个C文件来定义这个信息。看看CMake的configure_file函数。Here's the official documentationhere's part of the official CMake tutorial which walks through a simple usage of this function。我会输入一些示例代码,但这会是很多样板文件,链接的文档可以完成这项工作,应该更好地回答你的问题。
configure_file有一个替代方法:要在实现的简单性和构建时间之间进行权衡。如果编译定义的值在重新配置时发生变化,则CMake必须假设目标的每个源文件都需要重新编译,因为它没有关于如何使用该定义的信息(例如,target_compile_definitions很容易实现,但是在特定场景中 * 可能 * 导致构建时间慢得多)。只有那些包含定义了这些定义的文件才需要重新编译。还有一个关于“可读性”的潜在争论:如果您的目标已经安装,那么阅读已安装的头文件来找到定义比读取生成的CMake文件来找到定义要容易得多。
如果出于某种原因您希望缓存该变量,可以通过marking the cache variable as being for advanced usage purposes在CMake的配置GUI程序(ccmakecmake-gui)中隐藏该高速缓存变量。

ef1yzkbh

ef1yzkbh2#

这可以使用普通变量来完成,但是在某些情况下,该信息不是到处都可用,例如,如果由add_subdirectory创建的子目录结构不能确保仅在引入该信息的CMakeLists.txt文件中或在其后代目录之一中需要该信息。
在这种情况下,您应该使用类型为internal INTERNAL的缓存变量。这有一个额外的好处,即允许您在重新配置期间保留信息。您还可以使用FORCE来覆盖任何缓存变量的值。

    • 示例**
if (... BOO not yet set properly ...)
    set(BOO_VALUE ...)
    set(BOO ${BOO_VALUE} CACHE INTERNAL "") # internal implies FORCE
endif()

注意,这不会使预处理器定义可用。

target_compile_definitions(mytarget PRIVATE "BOO=${BOO}")
arknldoa

arknldoa3#

您可以只将变量与set(BOO <what you want>)一起使用。
您可以在这里找到文档:https://cmake.org/cmake/help/latest/command/set.html
但是没有option会限制你的变量的值作为内部设置。只有你。

相关问题