CMake文件通配符生成的文件

7
我正在使用asn1c来将一个或多个.asn1文件生成一系列.h.c文件到指定的文件夹中。
这些C文件与原始的asn1文件没有名称上的对应关系。
为了获得工作的可执行文件,这些文件必须与我的文件链接在一起。我希望能够:
  • 自动在构建目录中生成文件,以避免污染项目的其余部分(可能是通过add_custom_target完成)
  • 指定我的可执行文件依赖于这些文件,以便如果缺少文件或更新了一个.asn1文件,则自动运行asn1c可执行文件。
  • 自动将所有生成的文件添加到我的可执行文件的编译中。
由于生成的文件事先不知道,只要输出目录中的内容不为空,就可以使用glob获取该目录的所有文件- 只要目录不为空,我就很满意。
1个回答

6
CMake希望你向add_executable()传递完整的源代码列表。也就是说,在构建阶段无法使用文件通配符,这将太晚了。
要在不预先知道文件名的情况下处理生成的源文件,有几种方法:
  1. Generate files at configuration stage with execute_process. After that you may use file(GLOB) for collect source names and pass them to 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})
    

    If input files for generation (.asn1 in your case) are not intended to be changed in the future, this is the most simple approach which just works.

    If you intend to change input files and expect CMake to detect these changings and regenerate source, some more action should be taken. E.g., you may first copy input files into build directory with configure_file(COPY_ONLY). In that case input files will be tracked, and CMake will rerun if they are changed:

    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})
    
  2. Parse input files for determine, which files would be created from them. Not sure whether it works with .asn1, but for some formats this works:

    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})
    

    In that case CMake will detect changes in input files (but in case of modification of list of generated source files you need to rerun cmake manually).


这个问题的实际问题是我也使用CMake来构建asn1c可执行文件,因此在构建阶段之前无法运行它。 - Svalorzen
2
您可以在配置阶段使用execute_process()asn1c构建为子项目。这似乎是一个不错的决定:无需推迟在构建阶段构建所有内容。 - Tsyvarev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接