Reputation: 5608
I'm using asn1c
in order to produce from one or more .asn1
files a series of .h
and .c
files into a given folder.
These C files have no correspondence in names with the original asn1
files.
These files must be linked together with mine in order to obtain a working executable. I'd love to be able to:
add_custom_target
)asn1c
executable is automatically run if the files are missing or if one of the .asn1
files is updated.Since the generated files are not known in advance it's ok to just glob whatever the contents of the output directory of the asn1c
command - as long as the directory is not empty I'm happy.
Upvotes: 7
Views: 4157
Reputation: 65870
CMake expects complete list of sources to be passed to add_executable()
. That is, you cannot glob files generated at build stage - it would be too late.
You have several ways for handle generating source files without knowing their names in advance:
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})
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).
Upvotes: 7