CMake 通配生成的文件

标签 cmake dependencies code-generation glob

我正在使用 asn1c 以便从一个或多个 .asn1 文件将一系列 .h.c 文件生成到给定文件夹中。

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

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

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

  • 由于预先不知道生成的文件,因此可以只对 asn1c 命令的输出目录的任何内容进行 glob - 只要该目录不为空,我就很高兴。

    最佳答案

    CMake 期望将 完整的源列表 传递给 add_executable() 。也就是说,您不能在构建阶段生成 glob 文件 - 为时已晚。

    有几种方法可以在不知道源文件名称的情况下处理生成源文件:

  • 在配置阶段使用 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})
    

    如果将来不打算更改用于生成的输入文件(在您的情况下为 .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})
    
  • 解析输入文件以确定将从它们创建哪些文件。不确定它是否适用于 .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})
    

    在这种情况下,CMake 将检测输入文件中的更改(但在修改生成的源文件的 列表 的情况下,您需要手动重新运行 cmake)。
  • 关于CMake 通配生成的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44076307/

    相关文章:

    cmake - 如何在另一个文件夹中添加源文件

    android - Gradle Dependencies Command找不到其他Maven仓库

    linux - 我在哪里可以找到 Amazon Linux 上的 “libgconf-2.so.4()(64bit)” 和 “xdg-utils” 依赖项?

    c# - 在 .NET Core 2.x csproj 项目中可靠地生成 C# 代码?

    cmake:如何在只有 target_link_directories (没有 target_link_libraries)的共享库中设置 rpath?

    cmake - 在子目录中调用project()

    java - 在android studio中更改构建sdk时出错

    c# - XSD 工具在生成 C# 代码时将 "Specified"附加到某些属性/字段

    java - Jaxb 生成的类使用 JAXBElement 而不是指定类型

    cmake - CMake 策略的范围是什么?