【问题标题】:cmake 'add_custom_command' to pre-process header files?cmake 'add_custom_command' 预处理头文件?
【发布时间】:2020-11-08 16:28:23
【问题描述】:

我正在做一个需要 cmake 的项目。我想在我的 makefile 中添加一些自定义规则,但我不知道该怎么做。

c 源文件和头文件都在同一个目录中。在同一目录下还有一些.def 文件,它们是一些头文件的源代码#included 在编译过程中的源代码中。

如果我要在 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 文件制定单独的规则。

干杯。

【问题讨论】:

    标签: makefile cmake header-files preprocessor


    【解决方案1】:

    您提出的add_custom_command 方法存在两个问题:

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

    为了解决问题 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)
    

    【讨论】:

    • 非常感谢,这似乎是最好的方法。虽然我用目录制作了几个版本,但我 [显然] 弄错了,所以你的变量在这里产生了影响,你的方法是可以理解的。谢谢你。撇开 - 该项目一直在 unix 下,但即便如此,我们还是需要使用 cmake :(
    【解决方案2】:

    来自 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.
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 2011-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多