如何仅针对更改的 header 文件在 CMake 构建过程中添加代码生成步骤?

How to add code generation step in CMake build process only for changed header files?

我正在使用需要代码生成的 ODB 编写 C++ 应用程序。我正在使用以下 CMake 脚本。

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

CMAKE_POLICY(SET CMP0015 NEW)

PROJECT(odb_poc)

INCLUDE_DIRECTORIES(
    ${CMAKE_SOURCE_DIR}/src/
    ${CMAKE_SOURCE_DIR}/generated/)

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y")

MACRO(ODB_GENERATE header)
    SET(cxxFile "${CMAKE_SOURCE_DIR}/generated/${header}-odb.cxx")
    SET(hxxFile "${CMAKE_SOURCE_DIR}/generated/${header}-odb.hxx")
    SET(ixxFile "${CMAKE_SOURCE_DIR}/generated/${header}-odb.ixx")
    SET(sqlFile "${CMAKE_SOURCE_DIR}/generated/${header}.sql")

    SET(ODB_GENERATED_FILES "${cxxFile} ${hxxFile} ${ixxFile} ${sqlFile}")

    ADD_CUSTOM_COMMAND(
        OUTPUT ${ODB_GENERATED_FILES}
        COMMAND odb -o ${CMAKE_SOURCE_DIR}/generated/ --std c++14 -d pgsql --generate-query --generate-schema
                --show-sloc ${CMAKE_SOURCE_DIR}/src/${header}.hpp
        DEPENDS ${CMAKE_SOURCE_DIR}/src/${header}.hpp
        COMMENT "Generate database support code for ${header}.hpp")

    ADD_CUSTOM_TARGET(RunGenerator-${header} DEPENDS ${ODB_GENERATED_FILES}
                      COMMENT "Checking if re-generation is required for ${header}.hpp")

    ADD_DEPENDENCIES(${CMAKE_PROJECT_NAME} RunGenerator-${header})
ENDMACRO()

ADD_EXECUTABLE(${CMAKE_PROJECT_NAME}
    src/main.cpp
    src/house.hpp
    src/person.hpp
    src/servkeys.hpp
    generated/house-odb.cxx
    generated/person-odb.cxx
    generated/servkeys-odb.cxx)

TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME}
    odb
    odb-pgsql)

ODB_GENERATE(house)
ODB_GENERATE(person)
ODB_GENERATE(servkeys)

问题在于,每次更改 ODB 生成数据库支持代码的 header 个文件之一时,所有文件的代码都会重新生成。这是构建过程的输出:

14:11:03: Running steps for project odb_poc...
14:11:03: Starting: "/usr/bin/cmake" --build . --target all
[ 10%] Generate database support code for person.hpp
person-odb.hxx: 220
person-odb.ixx: 46
person-odb.cxx: 625
total: 891
[ 20%] Checking if re-generation is required for person.hpp
[ 20%] Built target RunGenerator-person
[ 30%] Generate database support code for house.hpp
house-odb.hxx: 205
house-odb.ixx: 46
house-odb.cxx: 580
total: 831
[ 40%] Checking if re-generation is required for house.hpp
[ 40%] Built target RunGenerator-house
[ 50%] Generate database support code for servkeys.hpp
servkeys-odb.hxx: 563
servkeys-odb.ixx: 46
servkeys-odb.cxx: 1477
total: 2086
[ 60%] Checking if re-generation is required for servkeys.hpp
[ 60%] Built target RunGenerator-servkeys
Scanning dependencies of target odb_poc
[ 70%] Building CXX object CMakeFiles/odb_poc.dir/src/main.cpp.o
[ 80%] Building CXX object CMakeFiles/odb_poc.dir/generated/house-odb.cxx.o
[ 90%] Building CXX object CMakeFiles/odb_poc.dir/generated/person-odb.cxx.o
[100%] Building CXX object CMakeFiles/odb_poc.dir/generated/servkeys-odb.cxx.o
Linking CXX executable odb_poc
[100%] Built target odb_poc
14:11:06: The process "/usr/bin/cmake" exited normally.
14:11:06: Elapsed time: 00:04.

如何更改 CMake 脚本以仅重新生成已更改 header 的代码?

我删除了这一行的引号:

SET(ODB_GENERATED_FILES "${cxxFile} ${hxxFile} ${ixxFile} ${sqlFile}")

将其更改为:

SET(ODB_GENERATED_FILES ${cxxFile} ${hxxFile} ${ixxFile} ${sqlFile})

这解决了问题。