【问题标题】:How to set up Doxygen and CMake for builds that generate headerfiles during the build process?如何为在构建过程中生成头文件的构建设置 Doxygen 和 CMake?
【发布时间】:2021-12-19 15:06:22
【问题描述】:

概述

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

详情

这个项目的目录结构有些不合常规:

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

我希望生成的文档以cmake/cmake-build-debug/docs 结尾。但是,我想将 CMake 和 Doxygen 配置提交到存储库,因此这些文件位于 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.ss:s/(#define SQUAWK)(.*)/\1 caw/。这是头文件的生成过程。即使我只是构建文档而无需构建 squawk 二进制文件,我也希望发生这种情况。

【问题讨论】:

    标签: c++ cmake doxygen


    【解决方案1】:

    解决方案

    解决此问题的关键是使用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,它会发出警告:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-10
      • 2021-10-24
      • 1970-01-01
      • 2016-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多