如何为在构建过程中生成头文件的构建设置DOOXO和CMake?

2022-05-28 00:00:00 doxygen cmake c++

概述

我的CMake项目中的一些头文件是在构建过程中自动生成的。我的目标是设置CMakeLists.txt,以便为我的项目构建文档也会触发头文件的生成(而不会触发任何其他构建)。基本的CMake/DO2设置遵循MS tutorial中的初始步骤。

详细信息

此项目的目录结构有些非常规:

${CMAKE_SOURCE_DIR}cmake/保存顶级CMakeLists.txt文件,${CMAKE_BINARY_DIR}cmake/cmake-build-debug

我希望生成的文档以cmake/cmake-build-debug/docs结尾。但是,我想要提交到存储库的CMake和DO2配置使这些文件位于docs/中。

源文件如下:

  1. squawk.cpp

    #include "squawk.hpp"
    
    void squawk(const std::string &s) {
        std::cout<<STRFY(SQUAWK)<<": "<<s<<std::endl;
    }
    
  2. squawk.hpp

    #include <iostream>
    #include <string>
    
    #define STRINGIFY(X) #X
    #define STRFY(X) STRINGIFY(X)
    #include "squawk.hd"
    
    void squawk(const std::string &s);
    
  3. main.cpp

    #include "squawk.hpp"
    
    int main(int argc, char* argv[]) {
    
        const std::string s = "Hello World!";
        squawk(s);
    
        return 0;
    }
    
  4. squawk.def

    #define SQUAWK squeal
    
在构建过程中,我获取squawk.def,将squeal更改为caw,并另存为squawk.hd,这是由sed执行的,说明在squawk.sss/(#define SQUAWK)(.*)/1 caw/中。这是头文件生成过程。即使我只构建文档而不必构建squawk二进制文件,我也希望发生这种情况。


解决方案

解决方案

解决此问题的关键是使用add_custom_target而不是add_custom_command生成头文件。

  1. cmake/CMakeLists.txt

    ### Set variables ###
    set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../src)
    set(SOURCES ${SRC_DIR}/squawk.cpp
        ${SRC_DIR}/main.cpp)
    set(SQUAWK_DEF ${SRC_DIR}/squawk.def)
    set(SQUAWK_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/squawk.ss)
    # Create include/ dir to save generated .hd file
    set(INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include)
    file(MAKE_DIRECTORY ${INCLUDE_DIR})
    set(SQUAWK_HD ${INCLUDE_DIR}/squawk.hd)
    set(BIN_NAME squawk)
    
    ### Generate .hd file ###
    add_custom_target(gen_hd
            BYPRODUCTS ${SQUAWK_HD}
            DEPENDS ${SQUAWK_DEF}
            SOURCES ${SQUAWK_DEF} ${SQUAWK_SCRIPT}
            COMMAND sed --regexp-extended -f ${SQUAWK_SCRIPT} ${SQUAWK_DEF} >${SQUAWK_HD})
    
    ### Add target ###
    add_executable(${BIN_NAME}
        ${SOURCES}
        ${SQUAWK_HD})
    target_include_directories(${BIN_NAME} PUBLIC
        ${INCLUDE_DIR})
    
    ### Build documentation ###
    if(DOCUMENTATION)
        add_subdirectory(../docs ${CMAKE_CURRENT_BINARY_DIR}/docs)
    endif()
    
  2. docs/CMakeLists.txt

    ### Find Doxygen ###
    # We need Doxygen 1.9.2 or higher
    find_package(Doxygen 1.9.2 REQUIRED)
    
    ### Find headers ###
    get_target_property(SQUAWK_PUBLIC_HEADER_DIR ${BIN_NAME} INTERFACE_INCLUDE_DIRECTORIES)
    set(SQUAWK_PUBLIC_HEADERS "")
    foreach(d ${SQUAWK_PUBLIC_HEADER_DIR})
        file(GLOB_RECURSE SPH ${d}/*.h*)
        list(APPEND SQUAWK_PUBLIC_HEADERS ${SPH})
    endforeach()
    
    ### Set Doxygen variables ###
    # Set variables which will be subsituted
    # in the Doxyfile.in for INPUT and OUTPUT
    set(DOXYGEN_INPUT_DIR "${SQUAWK_PUBLIC_HEADER_DIR}" "${SOURCES}")
    # Replace ; with space so string adheres to Doxygen syntax
    string(REPLACE ";" " " DOXYGEN_INPUT_DIR "${DOXYGEN_INPUT_DIR}")
    set(DOXYGEN_OUTPUT_DIR "${CMAKE_BINARY_DIR}/docs")
    
    ### Generate Doxyfile ###
    # Use docs/Doxyfile.in and configure_file
    # to create cmake/docs/Doxyfile which will be used
    # to generate the documentation
    set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
    set(DOXYFILE_OUT ${DOXYGEN_OUTPUT_DIR}/Doxyfile)
    configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY)
    
    ### Run Doxygen ###
    # Create directory where documentation will live
    # Specify index file which will be the output of the command
    # Add command and target
    file(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR})
    set(DOXYGEN_INDEX_FILE ${DOXYGEN_OUTPUT_DIR}/html/index.html)
        add_custom_command(OUTPUT ${DOXYGEN_INDEX_FILE}
                COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
                MAIN_DEPENDENCY "${DOXYFILE_IN}"
                DEPENDS ${SQUAWK_PUBLIC_HEADERS} gen_hd
                WORKING_DIRECTORY ${DOXYGEN_OUTPUT_DIR}
                COMMENT "Generating doxygen docs")
        add_custom_target(doxydocs
                ALL
                DEPENDS ${DOXYGEN_INDEX_FILE} ${SQUAWK_HD}
                WORKING_DIRECTORY ${DOXYGEN_OUTPUT_DIR})
    

通过上述设置,构建doxydocs将触发gen_hd,从而生成squawk.hd。如果我们生成squawk,它将发出:

相关文章