【发布时间】:2015-09-21 19:07:18
【问题描述】:
我有一个工具可以生成包含定义和声明的文件。这些文件需要包含在其他源文件或头文件中 - 它们不能独立使用。
显而易见的事情是使用自定义命令来生成它们。执行此操作的我的 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 预构建步骤,因为它被认为在正常依赖检查之前在每个构建上运行。但我希望这个预构建步骤具有依赖检查,因此如果其输入比其输出旧,则跳过它。)
【问题讨论】:
标签: c cmake makefile code-generation