c - 如何使用 cmake 生成包含文件?

标签 c cmake makefile code-generation

我有一个工具可以生成包含定义和声明的文件。这些文件需要包含在其他源文件或 header 中 - 它们不能单独使用。

显而易见的事情是使用自定义命令来生成它们。我的 CMakeLists.txt 执行此操作如下。我目前正在将其与 GNU makefile 生成器一起使用。

project(test_didl)
cmake_minimum_required(VERSION 3.0)

add_custom_command(
  OUTPUT test_didl_structs.h test_didl_structs.c
  COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/didl.py --decls=test_didl_structs.h --defs=test_didl_structs.c ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py
  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/didl.py ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py
  MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py)

add_executable(test_didl test_didl.c)
target_include_directories(test_didl PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(test_didl shared_lib)

test_didl.c 非常简单:

#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "test_didl_structs.h"
#include "test_didl_structs.c"

int main(void) {
}

但是在第一次构建时,make 尝试构建 test_didl.c,这当然会失败,因为 test_didl_structs.* 尚未生成。当然,在第一次成功构建 test_didl.c 之前,依赖信息是未知的,因此 make 不知道先运行 python 命令。

我尝试了自定义目标,但这不好,因为自定义目标被认为总是脏的。这意味着 C 文件在每次构建时都会重新编译,并且 EXE 会被链接。这种方法无法扩展。

我最终的解决方案是将输出 .h 文件作为可执行文件的输入:

add_executable(test_didl test_didl.c test_didl_structs.h)

.h 文件输入被视为依赖项,但不会为 makefile 生成器执行任何有趣的操作。 (我目前对其他生成器不感兴趣。)

这样可行,但感觉有点难看。它实际上并没有明确声明需要首先运行自定义命令,尽管实际上这似乎会发生。不过,我不太确定如何实现(但我还没有跟上阅读 CMake 生成的 Makefile 的速度)。

这是应该如何工作的吗?或者我应该做一些更简洁的事情来代替?

(我想,我想象的是类似于 Visual Studio 预构建步骤,因为在正常的依赖项检查之前,它被考虑在每个构建上运行。但我希望这个预构建步骤具有依赖性检查,以便在输入早于输出时跳过。)

最佳答案

My eventual solution was to make the output .h file an input to the executable.

这个方法是正确的。

它实际上指出,构建可执行文件取决于给定的文件,并且,如果该文件是某些 add_custom_command() 的 OUTPUT,则将执行此命令在构建可执行文件之前。 <小时/>

另一种方法是在配置阶段使用execute_process()生成所需的 header 。在这种情况下,无需添加头文件作为 add_executable() 的源:CMake 具有自动检测编译依赖项的概念,因此 test_didl 将在重新生成 test_didl_structs.h

execute_process(COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/didl.py --decls=test_didl_structs.h --defs=test_didl_structs.c ${CMAKE_CURRENT_SOURCE_DIR}/test_didl_structs.py)
# ...
add_executable(test_didl test_didl.c)

这种方法的缺点是您需要在更改 .py 文件后手动重新运行配置阶段。另请参阅question并回答它。 另一个问题是每次运行配置时都会更新头文件。

关于c - 如何使用 cmake 生成包含文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31215300/

相关文章:

c - 如何将 float 数组传递给以 unsigned char 指针为参数的函数?

linux - Haskell make recipe 使用 GHC 的悖论定理证明器失败

Makefile:使用@if,eval在运行时重新定义变量:变量始终采用最后一个eval的值

c++ - 尾随逗号和 C++

c - 如何将一个文件拆分为两个文件以获取 400k 记录

python - 为什么 pcap_dispatch 只返回 1 个数据包?

cmake - 有没有办法告诉 conan 在 conan 安装过程中使用不同的 cmake 可执行文件?

python-3.x - 使用 CMake 为 Python 3 构建 SimpleITK

c++ - 如何在 x86_64 上交叉编译 Raspberry Pi 项目? (缺少 *.so 由于路径无效)

c - 在树莓派上制作 "not recognized as an internal or external command"