我有一个工具可以生成包含定义和声明的文件。这些文件需要包含在其他源文件或标题中 - 它们不能单独使用。
显而易见的事情是使用自定义命令来生成它们。我的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预构建步骤,因为在正常的依赖性检查之前,它被考虑在每个构建上运行。但是我想要这个预构建步骤以进行依赖性检查,以便在输入比其输出旧时跳过它。)
答案 0 :(得分:1)
我的最终解决方案是使输出.h文件成为可执行文件的输入。
这种方式是正确的。
它实际上表明,在给定文件上构建可执行文件取决于,如果该文件对某些add_custom_command()
是OUTPUT,则此命令将在之前执行建立可执行文件。
另一种方法是使用configuration
在execute_process()
阶段生成所需的标头。在这种情况下,不需要添加头文件作为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并回答它。 另一个问题是每次运行配置时都会更新头文件。
答案 1 :(得分:0)
您可以尝试告诉cmake您使用的是外部来源,请参阅有关set_source_files_properties的文档,请参阅此past post