且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何包括生成的文件编译与cmake?

更新时间:2023-02-05 09:11:26

包括来源



include($ {PROJECT_SOURCE_DIR} /cmake_xsd_filelist.txt)
add_executable(Prog $ {SOURCE_FILES} $ {XSD_GENERATED_FILES})

这意味着您需要在配置步骤中有 cmake_xsd_filelist.txt 文件,即xsd必须由 execute_process 调用。我认为***是生成文件到二进制目录(按照 out-of-source 概念):

 #如果需要,创建目录
文件(MAKE_DIRECTORY$ {CMAKE_BINARY_DIR} / generated )

execute_process(
COMMAND
$ {XSD_EXECUTABLE} cxx-tree
--file-list-prologue'set(XSD_GENERATED_FILES'
--file -list$ {CMAKE_BINARY_DIR} /generated/cmake_xsd_filelist.txt
--file-list-epilogue)'
--output-dir$ {CMAKE_BINARY_DIR} / generated / xsd
$ {XSD_SOURCE_FILES}
RESULT_VARIABLE结果

不要忘记检查successfull退出状态:

  if(NOT result EQUAL 0)
message(FATAL_ERRORXSD failed)
endif()

现在您可以包括来源:

  include($ {CMAKE_BINARY_DIR} /generated/cmake_xsd_filelist.txt)
add_executable(Prog $ {SOURCE_FILES} $ {XSD_GENERATED_FILES})



XSD源更新



 文件在xsd文件夹中更改,执行XSD_EXECUTABLE 
生成.cpp和hpp文件。

如果 xsd 文件之一更改,CMake必须运行重新配置。这是帮助的诀窍:

  foreach(x $ {XSD_SOURCE_FILES})
configure_file($ {x} $ {x} COPYONLY)
endforeach()

现在如果 XSD_SOURCE_FILES 更改CMake将重新配置项目,有效地重新运行 XSD_EXECUTABLE 并重新包含 cmake_xsd_filelist.txt


I have a set of .xsd files in a subdirectory 'xsd'. I generate a set of .hxx and cxx files for XML-binding with an external command.

add_custom_command(
PRE_BUILD
OUTPUT ${PROJECT_SOURCE_DIR}/xsd/file1.hxx ${PROJECT_SOURCE_DIR}/xsd/file1.cxx
COMMAND ${XSD_EXECUTABLE} cxx-tree
    --file-list-prologue 'set(XSD_GENERATED_FILES '
    --file-list ${PROJECT_SOURCE_DIR}/cmake_xsd_filelist.txt
    --file-list-epilogue ')'
    --output-dir ${PROJECT_SOURCE_DIR}/xsd
    ${XSD_SOURCE_FILES}
DEPENDS ${XSD_SOURCE_FILES}
)

The tool creates a list of generated files. I have it in the following form:

set(XSD_GENERATED_FILES
file1.cpp
file1.hpp
file2.cpp
file2.hpp
)

Fine up to here.

Now the part where I don't know how to continue. I want to include the generated file list and add them to the executable.

include(${PROJECT_SOURCE_DIR}/cmake_xsd_filelist.txt)
add_executable(Prog ${SOURCE_FILES} ${XSD_GENERATED_FILES})

But this does not do what I want. Actually, it does nothing because initially cmake_xsd_filelist.txt is empty.

My goal is the following:

  • when a file in the 'xsd' folder changes, execute XSD_EXECUTABLE for generating the .cpp and hpp files.
  • only compile once the generated .cpp files when they have changed
  • add the generated source files to the executable.

Is this even possible with cmake? If yes, how?

Include sources

include(${PROJECT_SOURCE_DIR}/cmake_xsd_filelist.txt)
add_executable(Prog ${SOURCE_FILES} ${XSD_GENERATED_FILES})

This means that you need to have a cmake_xsd_filelist.txt file on configure step, i.e. xsd must be invoked by execute_process. Also I think it's better to generate files to binary directory (follow out-of-source concept):

# Create directory if needed
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/generated")

execute_process(
    COMMAND
        ${XSD_EXECUTABLE} cxx-tree
        --file-list-prologue 'set(XSD_GENERATED_FILES '
        --file-list "${CMAKE_BINARY_DIR}/generated/cmake_xsd_filelist.txt"
        --file-list-epilogue ')'
        --output-dir "${CMAKE_BINARY_DIR}/generated/xsd"
        ${XSD_SOURCE_FILES}
    RESULT_VARIABLE result
)

Do not forget to check successfull exit status:

if(NOT result EQUAL 0)
  message(FATAL_ERROR "XSD failed")
endif()

Now you can include sources:

include(${CMAKE_BINARY_DIR}/generated/cmake_xsd_filelist.txt)
add_executable(Prog ${SOURCE_FILES} ${XSD_GENERATED_FILES})

XSD sources update

when a file in the 'xsd' folder changes, execute XSD_EXECUTABLE
for generating the .cpp and hpp files.

I.e. CMake must run reconfigure if one of the xsd file changes. Here is the trick that helps:

foreach(x ${XSD_SOURCE_FILES})
  configure_file(${x} ${x} COPYONLY)
endforeach()

Now if any of the XSD_SOURCE_FILES changes CMake will reconfigure the project effectively re-running XSD_EXECUTABLE and re-including cmake_xsd_filelist.txt.