cmake的缓存变量可以用于cpp源码中吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cmake的缓存变量可以用于cpp源码中吗相关的知识,希望对你有一定的参考价值。

参考技术A CMake 的缓存变量是一种在 CMakeLists.txt 文件中定义的变量,可以用于控制构建过程中的各种参数和选项。在 CMake 构建过程中,缓存变量可以从命令行或 CMake GUI 界面中进行设置和修改。缓存变量通常用于控制构建过程中的编译器选项、库路径、安装路径等等。
在 C++ 源码中使用缓存变量需要引入 CMake 的配置文件,该文件会将缓存变量定义为 C++ 宏,从而可以在源码中使用。引入 CMake 配置文件的方法如下:

cmake
Copy code
configure_file(config.h.in config.h)

这将读取 config.h.in 文件中的内容,并将其中的 CMake 缓存变量替换为 C++ 宏。例如,如果 config.h.in 文件中包含以下内容:

cmake
Copy code
#define MY_OPTION $MY_OPTION

则在生成构建文件时,$MY_OPTION 将被替换为缓存变量 $MY_OPTION 的值。 在 C++ 源码中可以使用 MY_OPTION 宏来访问缓存变量的值。这样,就可以在 C++ 源码中使用缓存变量来控制编译器选项、库路径、安装路径等等。

CMake/Ninja 试图编译已删除的“.cpp”文件

【中文标题】CMake/Ninja 试图编译已删除的“.cpp”文件【英文标题】:CMake/Ninja attempting to compile deleted `.cpp` file 【发布时间】:2015-06-20 01:44:02 【问题描述】:

我发现,当我使用cmakeninja 从我的项目中删除cpp 文件时,如果不先完全删除我的构建目录并从头开始,我就无法轻松编译它。 CMake 和/或 Ninja 显然隐藏了对其编译的所有 cpp 文件的许多引用,即使在重新运行 CMake 之前删除 CMake 缓存也不会删除所有引用。

这是一个已知问题吗?有解决办法吗?我偶尔只是运行rm $(grep -R <filename> <builddir>),但这是一个可怕的组合。

编辑:看来我错了,因为我无法复制这个问题。手动重新运行 CMake 似乎总是生成正确的 .cpp 文件列表,即使使用 GLOB 生成源列表。

【问题讨论】:

您能否添加您的CMakeLists.txt 文件的示例?您是否列出了所有源文件,或者您是否提供file(GLOB ...)?后者是这种行为的一个可能原因。参见 CMake 的文档:We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate. @Florian 是的,我做 glob 文件,但我也会在必要时手动重新运行 CMake(当然,每当我删除 CMake 缓存时)。 Issue 0014820: warn users about removing only CMakeCache.txt 声称您还需要删除所有 CMakeFiles 目录。但我假设您没有缓存源文件列表,因此根据我的经验,重新触发 CMake 配置的最可靠方法是触摸项目 CMakeLists.txt 文件之一(例如使用CMake itselfcmake -E touch CMakeLists.txt)。跨度> @Florian 最可靠的方式:为什么不cmake <build-dir> 【参考方案1】:

把我的 cmets 变成答案

使用file(GLOB ...) 收集您的源文件

是的,在使用file(GLOB ...) 命令收集源文件时,CMake 不会知道新的或已删除的源文件。这是 CMake 的一个已知限制。因此,我已经更改了我的 CMake 项目以单独列出所有源文件。为方便起见,我仍在使用 file(GLOB ...) 命令收集头文件。

引用 CMake 的 file() 命令文档:

我们不建议使用 GLOB 来收集源文件列表 你的源代码树。如果源是时没有 CMakeLists.txt 文件更改 添加或删除然后生成的构建系统不知道何时 要求 CMake 重新生成。

删除CMakeCache.txt重新触发配置

仅删除 CMakeCache.txt 可能不足以重新触发 CMake 配置。 Issue 0014820: warn users about removing only CMakeCache.txt 声称您还需要删除所有 CMakeFiles 目录。

根据我的经验,重新触发 CMake 配置的最可靠方法是触摸其中一个项目 CMakeLists.txt 文件。

注意:对于ninja,CMake 添加了一个rebuild_cache 目标,以便再次为您的项目方便地运行 CMake。

从源代码管理更新后重新触发

想一想:如果源文件被删除是因为它们已从您的源代码管理中删除,那么可能有一种解决方法仍然允许您在源文件上使用file(GLOB ...)

例如如果您使用 GIT,您可以将以下内容添加到您的主 CMakeLists.txt

configure_file($CMAKE_SOURCE_DIR/.git/index $PROJECT_BINARY_DIR/git_index.tmp) 

缺点:它会重新触发每个 GIT 操作(更新、提交、...)的配置。

一些参考资料

run cmake when adding file in eclipse CMake: Correct way to make an arbitrary file trigger

【讨论】:

这是很有价值的信息,但我确实说过我会在必要时手动重新运行 CMake;自动触发重新配置并不是我真正想要的。问题是,即使我手动重新运行 CMake,我似乎也看到了不正确的配置。不过,我需要进行更多调查,以仔细检查我是否可以复制该问题。 @KyleStrand 好的,我承认我以前从未遇到过ninja 的此类问题。我在 Windows 上使用 1.6 版。所以我再次检查了 CMake 的 Ninja 生成器,每次再次运行配置时它都会完全重新生成 rules.ninjabuild.ninja。但是.ninja_deps.ninja_log 文件确实存在。我建议 - 如果你想要一个干净的 ninja 环境 - 你添加类似 if ("$CMAKE_GENERATOR" MATCHES "Ninja") file(REMOVE "$CMAKE_BINARY_DIR/.ninja_deps") endif() 到你的主要 CMakeLists.txt 这是个好主意。如果我有空闲时间,我会玩这个并报告。 看来我无法重现该问题;重新运行 CMake 似乎会忽略以前的源文件条目。我想我上次遇到这个问题时可能忘记更改#include 声明。现在,我将投票关闭。

以上是关于cmake的缓存变量可以用于cpp源码中吗的主要内容,如果未能解决你的问题,请参考以下文章

核心数据和图像缓存

Cocos2d - 我可以将多个精灵帧加载到帧缓存中吗

CMake/Ninja 试图编译已删除的“.cpp”文件

使用redis作为缓存,数据还需要存入数据库中吗?(转)

C++学习(三三九)CMAKE的Advanced

如何使用CMake项目生成提前的QML缓存?