option(WITH_DOC_MAN "Build manpage documentation with Doxygen" OFF) option(WITH_DOC_HTML "Build HTML documentation with Doxygen" OFF) find_package(Doxygen 1.9.4 QUIET) if(NOT DOXYGEN_FOUND) if(WITH_DOC_MAN OR WITH_DOC_HTML) message(FATAL_ERROR "Documentation generation requires Doxygen 1.9.4 or newer") endif() return() endif() set(DOC_NAMES ss-local ss-server ss-tunnel ss-redir ss-manager ss-nat shadowsocks-c) set(DOC_INPUTS) foreach(name IN LISTS DOC_NAMES) list(APPEND DOC_INPUTS "${CMAKE_CURRENT_SOURCE_DIR}/${name}.md") endforeach() set(DOC_SOURCES) foreach(name local.cpp server.cpp tunnel.cpp redir.cpp manager.cpp utils.cpp crypto/aead.cpp) list(APPEND DOC_SOURCES "${PROJECT_SOURCE_DIR}/src/${name}") endforeach() list(APPEND DOC_SOURCES "${PROJECT_SOURCE_DIR}/src/ss-nat") # Doxygen reads native documentation snippets directly from source. No target # binary or Python/AsciiDoc conversion step is needed, including in cross builds. foreach(format html man1 man8) set(DOXYGEN_HTML NO) set(DOXYGEN_MAN NO) set(DOXYGEN_MAN_EXTENSION .1) set(format_inputs ${DOC_INPUTS}) set(outputs) if(format STREQUAL "html") set(DOXYGEN_HTML YES) list(APPEND format_inputs "${CMAKE_CURRENT_SOURCE_DIR}/index.md") list(APPEND outputs "${PROJECT_BINARY_DIR}/html/index.html") foreach(name IN LISTS DOC_NAMES) list(APPEND outputs "${PROJECT_BINARY_DIR}/html/${name}.html") endforeach() elseif(format STREQUAL "man1") set(DOXYGEN_MAN YES) list(REMOVE_ITEM format_inputs "${CMAKE_CURRENT_SOURCE_DIR}/shadowsocks-c.md") foreach(name ss-local ss-server ss-tunnel ss-redir ss-manager ss-nat) list(APPEND outputs "${PROJECT_BINARY_DIR}/man/${name}.1") endforeach() else() set(DOXYGEN_MAN YES) set(DOXYGEN_MAN_EXTENSION .8) set(format_inputs "${CMAKE_CURRENT_SOURCE_DIR}/shadowsocks-c.md") list(APPEND outputs "${PROJECT_BINARY_DIR}/man/shadowsocks-c.8") endif() set(DOXYGEN_INPUT) foreach(path IN LISTS format_inputs) string(APPEND DOXYGEN_INPUT " \"${path}\"") endforeach() set(config "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile-${format}") configure_file(Doxyfile.in "${config}" @ONLY) set(stamp "${CMAKE_CURRENT_BINARY_DIR}/${format}.stamp") add_custom_command(OUTPUT "${stamp}" ${outputs} COMMAND "${DOXYGEN_EXECUTABLE}" "${config}" COMMAND ${CMAKE_COMMAND} -E touch "${stamp}" DEPENDS "${config}" ${format_inputs} ${DOC_SOURCES} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMMENT "Generating ${format} documentation with Doxygen" VERBATIM) set(DOC_${format}_OUTPUTS "${stamp}" ${outputs}) endforeach() add_custom_target(doc-man ALL DEPENDS ${DOC_man1_OUTPUTS} ${DOC_man8_OUTPUTS}) add_custom_target(doc-html ALL DEPENDS ${DOC_html_OUTPUTS}) if(NOT WITH_DOC_MAN) set_target_properties(doc-man PROPERTIES EXCLUDE_FROM_ALL TRUE) else() foreach(name ss-local ss-server ss-tunnel ss-redir ss-manager ss-nat) install(FILES "${PROJECT_BINARY_DIR}/man/${name}.1" DESTINATION share/man/man1) endforeach() install(FILES "${PROJECT_BINARY_DIR}/man/shadowsocks-c.8" "${PROJECT_BINARY_DIR}/man/shadowsocks-libev.8" DESTINATION share/man/man8) endif() if(NOT WITH_DOC_HTML) set_target_properties(doc-html PROPERTIES EXCLUDE_FROM_ALL TRUE) else() install(DIRECTORY "${PROJECT_BINARY_DIR}/html/" DESTINATION share/doc/${PROJECT_NAME}) endif() file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/man") file(WRITE "${PROJECT_BINARY_DIR}/man/shadowsocks-libev.8" ".so man8/shadowsocks-c.8\n")