CMake 通配生成的文件

Sva*_*zen 7 dependencies code-generation glob cmake

我使用它是asn1c为了从一个或多个.asn1文件生成一系列文件.h并将.c其放入给定的文件夹中。

这些C 文件的名称与原始文件没有对应关系asn1

这些文件必须与我的文件链接在一起才能获得有效的可执行文件。我希望能够:

  • 自动在构建目录中生成文件,以避免污染项目的其余部分(可能用 完成add_custom_target
  • 指定我的可执行文件对这些文件的依赖关系,以便asn1c在文件丢失或其中一个.asn1文件已更新时自动运行可执行文件。
  • 自动将所有生成的文件添加到我的可执行文件的编译中。

由于预先不知道生成的文件,因此可以仅全局显示命令输出目录的内容asn1c- 只要该目录不为空,我就很高兴。

Tsy*_*rev 6

CMake 期望将完整的源列表传递给add_executable(). 也就是说,您无法在构建阶段生成 glob 文件- 那就太晚了。

您可以通过多种方法来处理生成源文件而无需提前知道源文件的名称:

  1. 在配置阶段execute_process生成文件。之后,您可以使用file(GLOB)收集源名称并将它们传递给add_executable()

    execute_process(COMMAND asn1c <list of .asn1 files>)
    file(GLOB generated_sources "${CMAKE_CURRENT_BINARY_DIR}/*.c")
    add_executable(my_exe <list of normal sources> ${generated_sources})
    
    Run Code Online (Sandbox Code Playgroud)

    .asn1如果将来不打算更改用于生成的输入文件(在您的情况下),那么这是最简单的方法。

    如果您打算更改输入文件并期望 CMake 检测这些更改并重新生成源代码,则应采取更多操作。例如,您可以首先将输入文件复制到构建目录中configure_file(COPY_ONLY)。在这种情况下,将跟踪输入文件,如果它们发生更改,CMake 将重新运行:

    set(build_input_files) # Will be list of files copied into build tree
    foreach(input_file <list of .asn1 files>)
        # Extract name of the file for generate path of the file in the build tree
        get_filename_component(input_file_name ${input_file} NAME)
        # Path to the file created by copy
        set(build_input_file ${CMAKE_CURRENT_BINARY_DIR}/${input_file_name})
        # Copy file
        configure_file(${input_file} ${build_input_file} COPY_ONLY)
        # Add name of created file into the list
        list(APPEND build_input_files ${build_input_file})
    endforeach()
    
    execute_process(COMMAND asn1c ${build_input_files})
    file(GLOB generated_sources "${CMAKE_CURRENT_BINARY_DIR}/*.c")
    add_executable(my_exe <list of normal sources> ${generated_sources})
    
    Run Code Online (Sandbox Code Playgroud)
  2. 解析输入文件以确定将从它们创建哪些文件。不确定它是否适用于.asn1,但对于某些格式,这适用:

    set(input_files <list of .asn1 files>)
    execute_process(COMMAND <determine_output_files> ${input_files}
        OUTPUT_VARIABLE generated_sources)
    add_executable(my_exe <list of normal sources> ${generated_sources})
    add_custom_command(OUTPUT ${generated_sources}
        COMMAND asn1c ${input_files}
        DEPENDS ${input_files})
    
    Run Code Online (Sandbox Code Playgroud)

    在这种情况下,CMake 将检测输入文件中的更改(但如果修改生成的源文件列表,则需要cmake 手动重新运行)。

  • 您可以在*配置阶段*使用“execute_process()”将“asn1c”构建为子项目。这看起来是一个不错的决定:不需要在*构建阶段*推迟构建所有内容。 (2认同)