cmake 'add_custom_command' 预处理头文件?

cmake 'add_custom_command' to pre-process header files?

我正在做一个需要 cmake 的项目。我想在我的 makefile 中添加一些自定义规则,但我不太清楚如何去做。

c源文件和头文件都在同一个目录下。在同一目录中还有许多 .def 文件,它们是编译期间源代码中包含的一些头文件的源代码。

如果我要在 makefile 中执行此操作,我会使用类似

的简单规则
.SUFFIXES: .def

.def.h:
    $(PREPROC) $< > $@

我如何使用 cmake 执行此操作??

我已经尝试了以下的各种排列,有和没有 cmake 工作目录规范:

add_custom_command(
    OUTPUT vvr_const.h
    PRE_BUILD
    COMMAND preproc vvr_const.def > vvr_const.h
    DEPENDS vvr_const.def
)

add_custom_target(vvr_const.h DEPENDS vvr_const.def)

但是编译c源文件时没有生成头文件,所以编译失败。我还尝试了一种变体,我将上面的最后一行替换为

set_property(SOURCE main.c APPEND PROPERTY OBJECT_DEPENDS vvr_const.h)

本例提前正确生成了头文件,但是make找不到,报错没有规则做目标.h.

理想情况下,这将是一个通用规则,就像上面的 make 规则一样,但我不反对为每个 .def 文件制定一个单独的规则,如果需要的话。

干杯。

来自 cmake 的文档:

PRE_BUILD

    On Visual Studio Generators, run before any other rules are executed within the target. On other generators, run just before PRE_LINK commands.

所以你的命令可能 运行 太迟了。

您提出的 add_custom_command 方法有 2 个问题:

  1. 您没有指定工作目录;默认情况下,命令是 运行 在构建目录中,而不是在源目录中。
  2. 您在这里依赖 shell 功能(重定向到文件)。即使这可能仍然有效。您应该采用不依赖于 shell.
  3. 的方法

为了解决问题 1 和 2,我建议创建一个单独的 cmake 脚本文件,接收输入和输出文件的绝对路径,并在自定义命令中使用它们。这允许您使用 execute_process 指定要写入的文件而不依赖于平台。

preprocess_def.cmake

# preprocess def file
# parameters INPUT_FILE and OUTPUT_FILE denote the file to use as source
# and the file to write the results to respectively

# use preproc tool to get data to write to the output file
execute_process(COMMAND preproc "${INPUT_FILE}"
                RESULT_VARIABLE _EXIT_CODE
                OUTPUT_FILE "${OUTPUT_FILE}")

if (_EXIT_CODE)
    message(FATAL_ERROR "An error occured when preprocessing the file ${INPUT_FILE}")
endif()

CMakeLists.txt

set(_INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vvr_const.def")
set(_OUTPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vvr_const.h")

# not necessary to use build event here, if we mark the output file as generated
add_custom_command(OUTPUT "${_OUTPUT_FILE}"
    COMMAND "${CMAKE_BUILD_TOOL}" -D "OUPUT_FILE=${_OUTPUT_FILE}" -D "INPUT_FILE=${_INPUT_FILE}" -P "${CMAKE_CURRENT_SOURCE_DIR}/preprocess_def.cmake"
    DEPENDS "${_INPUT_FILE}")

add_executable(my_target vvr_const.h ...)
set_source_files_properties(vvr_const.h PROPERTIES GENERATED 1)