diff --git a/CMakeLists.txt b/CMakeLists.txt index 42457f1a8ee..699cb974302 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -219,15 +219,11 @@ include(generate_docs) set(MKHTML_PY ${CMAKE_BINARY_DIR}/utils/mkhtml.py) set(THUMBNAILS_PY ${CMAKE_BINARY_DIR}/utils/thumbnails.py) -set(HTML2MAN VERSION_NUMBER=${GRASS_VERSION_NUMBER} ${PYTHON_EXECUTABLE} - ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/g.html2man.py) +set(HTML2MAN ${CMAKE_BINARY_DIR}/utils/g.html2man.py) set(env_path "$ENV{PATH}") if(WIN32) - set(NULL_DEVICE nul) - set(SEARCH_COMMAND findstr /v) - set(HTML_SEARCH_STR "\"\|\| \"") set(sep "\;") string(REPLACE ";" "${sep}" env_path "${env_path}") set(grass_env_command @@ -241,9 +237,6 @@ if(WIN32) "VERSION_NUMBER=\"${GRASS_VERSION_NUMBER}\"" "VERSION_DATE=\"${GRASS_VERSION_DATE}\"") else() - set(NULL_DEVICE /dev/null) - set(SEARCH_COMMAND grep -v) - set(HTML_SEARCH_STR "\'\|\| \'") set(sep ":") set(grass_env_command ${CMAKE_COMMAND} -E env "PATH=${BIN_DIR}${sep}${SCRIPTS_DIR}${sep}${env_path}" @@ -300,6 +293,8 @@ endif() if(WITH_DOCS) add_subdirectory(doc) add_subdirectory(man) + install(DIRECTORY ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/ DESTINATION ${GRASS_INSTALL_DOCDIR}) + install(DIRECTORY ${OUTDIR}/${GRASS_INSTALL_MANDIR}/ DESTINATION ${GRASS_INSTALL_MANDIR}) endif() add_custom_target( diff --git a/cmake/generate_man_pages.cmake b/cmake/generate_man_pages.cmake deleted file mode 100644 index 85553ef8629..00000000000 --- a/cmake/generate_man_pages.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# work in progress... - - -file(GLOB doc_HTMLFILES "${OUTDIR}/${GRASS_INSTALL_DOCDIR}/*.html") - -foreach(html_file ${doc_HTMLFILES}) - get_filename_component(PGM_NAME ${html_file} NAME) - add_custom_command( - TARGET create_man_pages - PRE_BUILD - COMMAND ${HTML2MAN} ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${PGM_NAME}.html - ${OUTDIR}/${GRASS_INSTALL_MANDIR}/${PGM_NAME}.1 - ) -endforeach() - -#[[ -COMMAND ${HTML2MAN} ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${PGM_NAME}.html - ${OUTDIR}/${GRASS_INSTALL_MANDIR}/${PGM_NAME}.1 -]] diff --git a/cmake/modules/GRASSInstallDirs.cmake b/cmake/modules/GRASSInstallDirs.cmake index 796cf0a904a..0d21253164a 100644 --- a/cmake/modules/GRASSInstallDirs.cmake +++ b/cmake/modules/GRASSInstallDirs.cmake @@ -21,7 +21,7 @@ if(WITH_FHS) "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME_LOWER}-doc") set(GRASS_INSTALL_DEVDOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME_LOWER}-dev-doc") - set(GRASS_INSTALL_MANDIR "${CMAKE_INSTALL_MANDIR}") + set(GRASS_INSTALL_MANDIR "${CMAKE_INSTALL_MANDIR}/man1") set(GRASS_INSTALL_MKDOCSDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME_LOWER}-mkdocs") set(GRASS_INSTALL_DEMODIR "${GRASS_INSTALL_SHAREDIR}/demolocation") @@ -46,7 +46,7 @@ else() set(GRASS_INSTALL_INCLUDEDIR "${GISBASE_DIR}/include") set(GRASS_INSTALL_DOCDIR "${GISBASE_DIR}/docs/html") set(GRASS_INSTALL_DEVDOCDIR "${GISBASE_DIR}/html") - set(GRASS_INSTALL_MANDIR "${GISBASE_DIR}/docs/man") + set(GRASS_INSTALL_MANDIR "${GISBASE_DIR}/docs/man/man1") set(GRASS_INSTALL_MKDOCSDIR "${GISBASE_DIR}/docs/mkdocs") set(GRASS_INSTALL_DEMODIR "${GISBASE_DIR}/demolocation") set(GRASS_INSTALL_MISCDIR "${GISBASE_DIR}") diff --git a/cmake/modules/build_gui_in_subdir.cmake b/cmake/modules/build_gui_in_subdir.cmake index 7e08fff7bd2..838ea6cce5c 100644 --- a/cmake/modules/build_gui_in_subdir.cmake +++ b/cmake/modules/build_gui_in_subdir.cmake @@ -45,16 +45,16 @@ function(build_gui_in_subdir dir_name) "${OUTDIR}/${GRASS_INSTALL_SCRIPTDIR}/${G_TARGET_NAME}${SCRIPT_EXT}") if(UNIX) - add_custom_command( - OUTPUT ${OUT_SCRIPT_FILE} - COMMAND ${CMAKE_COMMAND} -E copy ${SRC_SCRIPT_FILE} ${OUT_SCRIPT_FILE} - COMMAND /bin/chmod 755 ${OUT_SCRIPT_FILE} - DEPENDS g.parser ${SRC_SCRIPT_FILE}) + add_custom_command( + OUTPUT ${OUT_SCRIPT_FILE} + COMMAND ${CMAKE_COMMAND} -E copy ${SRC_SCRIPT_FILE} ${OUT_SCRIPT_FILE} + COMMAND /bin/chmod 755 ${OUT_SCRIPT_FILE} + DEPENDS g.parser ${SRC_SCRIPT_FILE}) else() - add_custom_command( - OUTPUT ${OUT_SCRIPT_FILE} - COMMAND ${CMAKE_COMMAND} -E copy ${SRC_SCRIPT_FILE} ${OUT_SCRIPT_FILE} - DEPENDS g.parser ${SRC_SCRIPT_FILE}) + add_custom_command( + OUTPUT ${OUT_SCRIPT_FILE} + COMMAND ${CMAKE_COMMAND} -E copy ${SRC_SCRIPT_FILE} ${OUT_SCRIPT_FILE} + DEPENDS g.parser ${SRC_SCRIPT_FILE}) endif() if(WITH_DOCS) @@ -81,40 +81,19 @@ function(build_gui_in_subdir dir_name) endif() endif() - set(TMP_HTML_FILE - ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${G_TARGET_NAME}.tmp.html) - set(OUT_HTML_FILE ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${G_TARGET_NAME}.html) - set(GUI_HTML_FILE ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/wxGUI.${G_NAME}.html) + set(out_html_file ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${G_TARGET_NAME}.html) - - add_custom_command( - OUTPUT ${OUT_HTML_FILE} - COMMAND ${CMAKE_COMMAND} -E copy ${G_SRC_DIR}/${G_TARGET_NAME}.html - ${CMAKE_CURRENT_BINARY_DIR}/${G_TARGET_NAME}.html - COMMAND - ${grass_env_command} ${PYTHON_EXECUTABLE} - ${OUTDIR}/${GRASS_INSTALL_SCRIPTDIR}/${G_TARGET_NAME}${SCRIPT_EXT} - --html-description < ${NULL_DEVICE} | ${SEARCH_COMMAND} - ${HTML_SEARCH_STR} > ${TMP_HTML_FILE} - COMMAND ${grass_env_command} ${PYTHON_EXECUTABLE} ${MKHTML_PY} - ${G_TARGET_NAME} ${GRASS_VERSION_DATE} > ${OUT_HTML_FILE} - COMMAND ${copy_images_command} - COMMAND ${CMAKE_COMMAND} -E remove ${TMP_HTML_FILE} - ${CMAKE_CURRENT_BINARY_DIR}/${G_TARGET_NAME}.html - COMMAND ${grass_env_command} ${PYTHON_EXECUTABLE} ${MKHTML_PY} - ${G_TARGET_NAME} ${GRASS_VERSION_DATE} > ${GUI_HTML_FILE} - COMMENT "Creating ${OUT_HTML_FILE} (and ${GUI_HTML_FILE}))" + generate_docs(${G_NAME} + OUTPUT ${out_html_file} + GUI_TARGET_NAME ${G_TARGET_NAME} + SOURCEDIR ${G_SRC_DIR} DEPENDS ${OUT_SCRIPT_FILE} GUI_WXPYTHON LIB_PYTHON) - - install(FILES ${OUT_HTML_FILE} ${GUI_HTML_FILE} - DESTINATION ${GRASS_INSTALL_DOCDIR}) - endif() # WITH_DOCS add_custom_target( ${G_TARGET_NAME} DEPENDS ${GUI_STAMP_FILE} ${OUT_SCRIPT_FILE} - ${OUT_HTML_FILE}) + ${out_html_file}) set(modules_list "${G_TARGET_NAME};${modules_list}" diff --git a/cmake/modules/build_module.cmake b/cmake/modules/build_module.cmake index fac4557bc85..8811d0739e0 100644 --- a/cmake/modules/build_module.cmake +++ b/cmake/modules/build_module.cmake @@ -143,6 +143,7 @@ function(build_module) generate_export_header(${G_NAME} STATIC_DEFINE "STATIC_BUILD" EXPORT_FILE_NAME ${export_file_name}) + add_dependencies(${G_NAME} python_doc_utils) endif() if(G_HTML_FILE_NAME) @@ -214,14 +215,6 @@ function(build_module) endif() endforeach() - # To use this property later in build_docs - set(PGM_EXT "") - if(WIN32) - if(G_EXE) - set(PGM_EXT ".exe") - endif() - endif() - set(G_HTML_FILE_NAME "${HTML_FILE_NAME}.html") set(html_file_search ${G_SRC_DIR}/${G_HTML_FILE_NAME}) if(NOT G_NO_DOCS AND NOT EXISTS ${html_file_search}) @@ -229,61 +222,30 @@ function(build_module) endif() if(WITH_DOCS AND NOT G_NO_DOCS) - set(HTML_FILE) + + set(html_file) if(EXISTS ${html_file_search}) - set(HTML_FILE ${html_file_search}) - install(FILES ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${G_HTML_FILE_NAME} - DESTINATION ${GRASS_INSTALL_DOCDIR}) + set(html_file ${html_file_search}) endif() - if(NOT HTML_FILE) + if(NOT html_file) return() endif() - get_filename_component(HTML_FILE_NAME ${HTML_FILE} NAME) - get_filename_component(PGM_SOURCE_DIR ${HTML_FILE} PATH) + get_filename_component(HTML_FILE_NAME ${html_file} NAME) + get_filename_component(PGM_SOURCE_DIR ${html_file} PATH) string(REPLACE ".html" "" PGM_NAME "${HTML_FILE_NAME}") - string(REPLACE ".html" ".tmp.html" TMP_HTML_NAME ${HTML_FILE_NAME}) - set(TMP_HTML_FILE ${CMAKE_CURRENT_BINARY_DIR}/${TMP_HTML_NAME}) - set(OUT_HTML_FILE ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${HTML_FILE_NAME}) - - set(PGM_EXT "") - if(WIN32) - set(PGM_EXT ".exe") - endif() if(RUN_HTML_DESCR) - set(html_descr_command - ${G_NAME}${PGM_EXT} --html-description < ${NULL_DEVICE} | - ${SEARCH_COMMAND} ${HTML_SEARCH_STR}) - else() - set(html_descr_command ${CMAKE_COMMAND} -E echo) + set(HTML_DESCR "HTML_DESCR") endif() - file( - GLOB IMG_FILES - LIST_DIRECTORIES FALSE - ${G_SRC_DIR}/*.png ${G_SRC_DIR}/*.jpg) - if(IMG_FILES) - set(copy_images_command ${CMAKE_COMMAND} -E copy ${IMG_FILES} - ${OUTDIR}/${GRASS_INSTALL_DOCDIR}) - install(FILES ${IMG_FILES} DESTINATION ${GRASS_INSTALL_DOCDIR}) - endif() - - add_custom_command( + generate_docs(${PGM_NAME} TARGET ${G_NAME} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${G_SRC_DIR}/${G_HTML_FILE_NAME} - ${CMAKE_CURRENT_BINARY_DIR}/${G_HTML_FILE_NAME} - COMMAND ${grass_env_command} ${html_descr_command} > ${TMP_HTML_FILE} - COMMAND ${grass_env_command} ${PYTHON_EXECUTABLE} ${MKHTML_PY} ${PGM_NAME} - > ${OUT_HTML_FILE} - COMMAND ${copy_images_command} - COMMAND ${CMAKE_COMMAND} -E remove ${TMP_HTML_FILE} - ${CMAKE_CURRENT_BINARY_DIR}/${G_HTML_FILE_NAME} - COMMENT "Creating ${OUT_HTML_FILE}") - install(FILES ${OUT_HTML_FILE} DESTINATION ${GRASS_INSTALL_DOCDIR}) + SOURCEDIR ${PGM_SOURCE_DIR} + ${HTML_DESCR}) + endif() # WITH_DOCS foreach(test_SOURCE ${G_TEST_SOURCES}) diff --git a/cmake/modules/build_script_in_subdir.cmake b/cmake/modules/build_script_in_subdir.cmake index 579ffa38cc1..c92484e8ee1 100644 --- a/cmake/modules/build_script_in_subdir.cmake +++ b/cmake/modules/build_script_in_subdir.cmake @@ -39,18 +39,18 @@ function(build_script_in_subdir dir_name) return() endif() - set(SCRIPT_EXT "") + set(script_ext "") if(WIN32) - set(SCRIPT_EXT ".py") + set(script_ext ".py") endif() set(HTML_FILE ${G_SRC_DIR}/${G_NAME}.html) configure_file( ${G_SRC_DIR}/${G_NAME}.py - ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${G_NAME}${SCRIPT_EXT} COPYONLY) + ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${G_NAME}${script_ext} COPYONLY) file( - COPY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${G_NAME}${SCRIPT_EXT} + COPY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${G_NAME}${script_ext} DESTINATION ${OUTDIR}/${G_DEST_DIR} FILE_PERMISSIONS OWNER_READ @@ -90,46 +90,17 @@ function(build_script_in_subdir dir_name) install(FILES ${IMG_FILES} DESTINATION ${GRASS_INSTALL_DOCDIR}) endif() - set(HTML_FILE ${G_SRC_DIR}/${G_NAME}.html) - if(EXISTS ${HTML_FILE}) - install(FILES ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${G_NAME}.html - DESTINATION ${GRASS_INSTALL_DOCDIR}) - else() - set(HTML_FILE) - file(GLOB html_files ${G_SRC_DIR}/*.html) - if(html_files) - message( - FATAL_ERROR - "${html_file} does not exists. ${G_SRC_DIR} \n ${OUTDIR}/${G_DEST_DIR}| ${G_NAME}" - ) - endif() - endif() + set(out_html_file ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${G_NAME}.html) - set(TMP_HTML_FILE ${CMAKE_CURRENT_BINARY_DIR}/${G_NAME}.tmp.html) - set(OUT_HTML_FILE ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${G_NAME}.html) - - add_custom_command( - OUTPUT ${OUT_HTML_FILE} - COMMAND ${CMAKE_COMMAND} -E copy ${G_SRC_DIR}/${G_NAME}.html - ${CMAKE_CURRENT_BINARY_DIR}/${G_NAME}.html - COMMAND - ${grass_env_command} ${PYTHON_EXECUTABLE} - ${OUTDIR}/${G_DEST_DIR}/${G_NAME}${SCRIPT_EXT} - --html-description < ${NULL_DEVICE} | ${SEARCH_COMMAND} - ${HTML_SEARCH_STR} > ${TMP_HTML_FILE} - COMMAND ${grass_env_command} ${PYTHON_EXECUTABLE} ${MKHTML_PY} ${G_NAME} > - ${OUT_HTML_FILE} - COMMAND ${copy_images_command} - COMMAND ${CMAKE_COMMAND} -E remove ${TMP_HTML_FILE} - ${CMAKE_CURRENT_BINARY_DIR}/${G_NAME}.html - COMMENT "Creating ${OUT_HTML_FILE}" + generate_docs(${G_NAME} + OUTPUT ${out_html_file} + SOURCEDIR ${G_SRC_DIR} + DEST_DIR ${G_DEST_DIR} DEPENDS ${TRANSLATE_C_FILE} LIB_PYTHON) - install(FILES ${OUT_HTML_FILE} DESTINATION ${GRASS_INSTALL_DOCDIR}) - endif() # WITH_DOCS - add_custom_target(${G_NAME} DEPENDS ${TRANSLATE_C_FILE} ${OUT_HTML_FILE}) + add_custom_target(${G_NAME} DEPENDS ${TRANSLATE_C_FILE} ${out_html_file}) set(modules_list "${G_NAME};${modules_list}" @@ -142,7 +113,7 @@ function(build_script_in_subdir dir_name) DESTINATION ${G_DEST_DIR}) endif() - install(PROGRAMS ${OUTDIR}/${G_DEST_DIR}/${G_NAME}${SCRIPT_EXT} + install(PROGRAMS ${OUTDIR}/${G_DEST_DIR}/${G_NAME}${script_ext} DESTINATION ${G_DEST_DIR}) endfunction() diff --git a/cmake/modules/generate_docs.cmake b/cmake/modules/generate_docs.cmake index b951164666a..0834aa5f8be 100644 --- a/cmake/modules/generate_docs.cmake +++ b/cmake/modules/generate_docs.cmake @@ -1,41 +1,184 @@ -macro(generate_html) - cmake_parse_arguments(PGM "IMG_NOT" "NAME;SOURCEDIR;TARGET" "" ${ARGN}) +#[[ +AUTHOR(S): Nicklas Larsson +PURPOSE: Generate documentation (html, man etc.) +COPYRIGHT: (C) 2025-2026 by the GRASS Development Team +SPDX-License-Identifier: GPL-2.0-or-later +]] - if(NOT PGM_NAME) - message(FATAL_ERROR "NAME in not set") +#[=======================================================================[.rst: + +generate_docs +------------- + +Generate documentation + + generate_docs_list([TARGET ] + [DOC_FILES ...] + [IMG_FILES ...]) + + Generate documentation files (.html, .man1 etc.) of , which is + a list of file names without file extension. The image files + are installed. The command is added to the target . + This is a command intended for plain documentation files, not modules. + + generate_docs( + [SOURCEDIR ] + [TARGET ] + [OUTPUT ] + [DEST_DIR ] + [GUI_TARGET_NAME ] + [DEPENDS ...] + [IMG_FILES ...] + [IMG_NO] + [HTML_DESCR]) + + Generate documentation files (.html, .man1 etc.) of , which is a source + documentation file name without extension. + + Typical use case is, for example: + + `generate_docs( TARGET )` + + Which generates documentation based on file(s) named [.html|.md], + added as a POST_BUILD command to . + +#]=======================================================================] + +macro(generate_docs_list) + cmake_parse_arguments(D "" "TARGET" "DOC_FILES;IMG_FILES" ${ARGN}) + + if(NOT D_TARGET OR NOT D_DOC_FILES) + message(FATAL_ERROR "TARGET >${D_TARGET}< or DOC_FILES >${D_DOC_FILES}< in not set") endif() - if(NOT PGM_TARGET) - message(FATAL_ERROR "TARGET in not set") + foreach(doc_file ${D_DOC_FILES}) + generate_docs(${doc_file} TARGET ${D_TARGET} SOURCEDIR ${CMAKE_CURRENT_SOURCE_DIR} IMG_NO) + endforeach() + + if(D_IMG_FILES) + add_custom_command( + TARGET ${D_TARGET} + PRE_BUILD + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${D_IMG_FILES} ${OUTDIR}/${GRASS_INSTALL_DOCDIR}) + install(FILES ${D_IMG_FILES} DESTINATION ${GRASS_INSTALL_DOCDIR}) endif() +endmacro() - if(NOT PGM_SOURCEDIR) - set(PGM_SOURCEDIR ${CMAKE_CURRENT_SOURCE_DIR}) +function(generate_docs name) + cmake_parse_arguments(PARSE_ARGV 1 D + "IMG_NO;HTML_DESCR" + "SOURCEDIR;TARGET;OUTPUT;DEST_DIR;GUI_TARGET_NAME" + "IMG_FILES;DEPENDS") + + if(NOT D_TARGET AND NOT D_OUTPUT) + message(FATAL_ERROR "TARGET or OUTPUT in not set") endif() - set(PGM_SOURCE ${PGM_SOURCEDIR}/${PGM_NAME}.html) + set(sourcedir "${D_SOURCEDIR}") + if(NOT D_SOURCEDIR) + set(sourcedir "${CMAKE_CURRENT_SOURCE_DIR}") + endif() - file( - GLOB IMG_FILES - LIST_DIRECTORIES FALSE - ${PGM_SOURCEDIR}/*.png ${PGM_SOURCEDIR}/*.jpg) - if(IMG_FILES AND NOT PGM_IMG_NOT) - set(copy_images_command ${CMAKE_COMMAND} -E copy_if_different ${IMG_FILES} + if(D_GUI_TARGET_NAME) + set(html_file_name ${D_GUI_TARGET_NAME}.html) + set(tmp_html_name ${D_GUI_TARGET_NAME}.tmp.html) + set(man_file_name ${D_GUI_TARGET_NAME}.1) + else() + set(html_file_name ${name}.html) + set(tmp_html_name ${name}.tmp.html) + set(man_file_name ${name}.1) + endif() + set(source_html "${sourcedir}/${html_file_name}") + set(html_file "${CMAKE_CURRENT_BINARY_DIR}/${html_file_name}") + set(tmp_html_file "${CMAKE_CURRENT_BINARY_DIR}/${tmp_html_name}") + set(out_html_file "${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${html_file_name}") + set(out_man_file "${OUTDIR}/${GRASS_INSTALL_MANDIR}/${man_file_name}") + + if(WIN32) + set(ext ".exe") + set(py ".py") + set(null_device nul) + set(search_cmd findstr /v) + set(html_search_str "\"\|\| \"") + else() + set(ext "") + set(py "") + set(null_device /dev/null) + set(search_cmd grep -v) + set(html_search_str "\'\|\| \'") + endif() + + if(D_HTML_DESCR) + set(html_descr_command + ${grass_env_command} + ${name}${ext} --html-description < ${null_device} | + ${search_cmd} ${html_search_str}) + else() + set(html_descr_command ${CMAKE_COMMAND} -E echo) + endif() + + if(NOT D_IMG_FILES) + file(GLOB D_IMG_FILES + LIST_DIRECTORIES FALSE + ${sourcedir}/*.png ${sourcedir}/*.jpg) + endif() + if(D_IMG_FILES AND NOT D_IMG_NO) + set(copy_images_command ${CMAKE_COMMAND} -E copy_if_different ${D_IMG_FILES} ${OUTDIR}/${GRASS_INSTALL_DOCDIR}) - install(FILES ${IMG_FILES} DESTINATION ${GRASS_INSTALL_DOCDIR}) - endif() - - add_custom_command( - TARGET ${PGM_TARGET} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${PGM_SOURCE} - ${CMAKE_CURRENT_BINARY_DIR}/${PGM_NAME}.html - COMMAND ${grass_env_command} ${PYTHON_EXECUTABLE} ${MKHTML_PY} ${PGM_NAME} > - ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${PGM_NAME}.html - COMMAND ${copy_images_command} - COMMAND ${CMAKE_COMMAND} -E remove - ${CMAKE_CURRENT_BINARY_DIR}/${PGM_NAME}.html - COMMENT "Creating ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${PGM_NAME}.[html|1]") - install(FILES ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${PGM_NAME}.html - DESTINATION ${GRASS_INSTALL_DOCDIR}) -endmacro() + install(FILES ${D_IMG_FILES} DESTINATION ${GRASS_INSTALL_DOCDIR}) + endif() + + set(mkhtml_cmd ${grass_env_command} ${PYTHON_EXECUTABLE} ${MKHTML_PY}) + set(html2man_cmd ${grass_env_command} ${PYTHON_EXECUTABLE} ${HTML2MAN}) + + if(D_TARGET) + add_custom_command( + TARGET ${D_TARGET} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${source_html} ${html_file} + COMMAND ${html_descr_command} > ${tmp_html_file} + COMMAND ${mkhtml_cmd} ${name} > ${out_html_file} + COMMAND ${html2man_cmd} ${out_html_file} ${out_man_file} + COMMAND ${copy_images_command} + COMMAND ${CMAKE_COMMAND} -E remove ${html_file} + COMMENT "Creating ${name}.[html|1]") + elseif(D_GUI_TARGET_NAME) + set(gui_html_file ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/wxGUI.${name}.html) + set(gui_man_file ${OUTDIR}/${GRASS_INSTALL_MANDIR}/wxGUI.${name}.1) + set(py_script_file ${OUTDIR}/${GRASS_INSTALL_SCRIPTDIR}/${D_GUI_TARGET_NAME}${py}) + + add_custom_command( + OUTPUT ${out_html_file} + COMMAND ${CMAKE_COMMAND} -E copy ${source_html} ${html_file} + COMMAND ${grass_env_command} ${PYTHON_EXECUTABLE} ${py_script_file} + --html-description < ${null_device} | ${search_cmd} + ${html_search_str} > ${tmp_html_file} + COMMAND ${mkhtml_cmd} ${D_GUI_TARGET_NAME} > ${out_html_file} + COMMAND ${html2man_cmd} ${out_html_file} ${out_man_file} + COMMAND ${copy_images_command} + COMMAND ${CMAKE_COMMAND} -E remove ${tmp_html_file} + COMMAND ${mkhtml_cmd} ${D_GUI_TARGET_NAME} > ${gui_html_file} + COMMAND ${html2man_cmd} ${gui_html_file} ${gui_man_file} + COMMAND ${CMAKE_COMMAND} -E remove ${html_file} + COMMENT "Creating ${out_html_file} and ${gui_html_file}" + DEPENDS ${D_DEPENDS}) + else() + set(out_html_file "${D_OUTPUT}") + set(py_script_file "${OUTDIR}/${D_DEST_DIR}/${name}${py}") + + add_custom_command( + OUTPUT ${out_html_file} + COMMAND ${CMAKE_COMMAND} -E copy ${source_html} ${html_file} + COMMAND ${grass_env_command} ${PYTHON_EXECUTABLE} ${py_script_file} + --html-description < ${null_device} | ${search_cmd} + ${html_search_str} > ${tmp_html_file} + COMMAND ${mkhtml_cmd} ${name} > ${out_html_file} + COMMAND ${html2man_cmd} ${out_html_file} ${out_man_file} + COMMAND ${copy_images_command} + COMMAND ${CMAKE_COMMAND} -E remove ${tmp_html_file} ${html_file} + COMMENT "Creating ${OUT_HTML_FILE}" + DEPENDS ${D_DEPENDS}) + endif() + +endfunction() diff --git a/db/CMakeLists.txt b/db/CMakeLists.txt index 64e899c02e9..8005c8a4895 100644 --- a/db/CMakeLists.txt +++ b/db/CMakeLists.txt @@ -18,7 +18,7 @@ add_custom_target( COMMENT "All database modules are built.") if(WITH_DOCS) - generate_html(TARGET ALL_DATABASE_MODULES NAME databaseintro) + generate_docs(databaseintro TARGET ALL_DATABASE_MODULES) endif() set(db_drivers grass_gis) diff --git a/db/drivers/CMakeLists.txt b/db/drivers/CMakeLists.txt index e6b291274a5..b6a70eb39fb 100644 --- a/db/drivers/CMakeLists.txt +++ b/db/drivers/CMakeLists.txt @@ -162,8 +162,9 @@ if(TARGET MYSQL) list(APPEND db_drivers mysql) if(WITH_DOCS) - generate_html(TARGET mysql NAME grass-mesql SOURCEDIR - ${CMAKE_CURRENT_SOURCE_DIR}/mysql) + generate_docs(grass-mesql + TARGET mysql + SOURCEDIR ${CMAKE_CURRENT_SOURCE_DIR}/mysql) endif() endif() diff --git a/display/CMakeLists.txt b/display/CMakeLists.txt index 9ddb3faa214..53d0cdead3a 100644 --- a/display/CMakeLists.txt +++ b/display/CMakeLists.txt @@ -42,7 +42,7 @@ add_custom_target( COMMENT "All display modules are built.") if(WITH_DOCS) - generate_html(TARGET ALL_DISPLAY_MODULES NAME displaydrivers) + generate_docs(displaydrivers TARGET ALL_DISPLAY_MODULES) endif() build_program_in_subdir(d.barscale DEPENDS grass_symb grass_display grass_gis) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 1717479ebad..1607a619213 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,15 +1,40 @@ -file(GLOB doc_HTMLFILES "*.html") +set(doc_files + grass_database + projectionintro) + +set(img_files + create_new_project_gui.png + gi_3dview.jpg + gi_addons.jpg + gi_c.jpg + gi_cartography.jpg + gi_database.jpg + gi_display.jpg + gi_gallery.jpg + gi_general.jpg + gi_gui.jpg + gi_imagery.jpg + gi_miscellaneous.jpg + gi_python.jpg + gi_raster.jpg + gi_raster3d.jpg + gi_temporal.jpg + gi_vector.jpg + grass_arch.png + grass_database.png + jupyter_3d_map.png + jupyter_interactive_map.png + jupyter_map.png + jupyter_series_map.png + jupyter_timeseries_map.png + project.png) + add_custom_target(ADD_DOC_DOCS ALL COMMENT "Generate doc/html docs." DEPENDS LIB_PYTHON) -foreach(html_file ${doc_HTMLFILES}) - get_filename_component(filename ${html_file} NAME_WLE) - generate_html(TARGET ADD_DOC_DOCS NAME ${filename} IMG_NOT) -endforeach() - -file( - GLOB IMG_FILES - LIST_DIRECTORIES FALSE - *.png *.jpg) -if(IMG_FILES) - install(FILES ${IMG_FILES} DESTINATION ${GRASS_INSTALL_DOCDIR}) -endif() +generate_docs_list( + TARGET ADD_DOC_DOCS + DOC_FILES ${doc_files} + IMG_FILES ${img_files}) + +unset(doc_files) +unset(img_files) diff --git a/gui/wxpython/docs/CMakeLists.txt b/gui/wxpython/docs/CMakeLists.txt index 1041def8638..05d9b96ef51 100644 --- a/gui/wxpython/docs/CMakeLists.txt +++ b/gui/wxpython/docs/CMakeLists.txt @@ -1,4 +1,4 @@ -set(wxpython_html_files +set(doc_files wxGUI.components wxGUI wxGUI.iscatt @@ -7,26 +7,33 @@ set(wxpython_html_files wxGUI.toolboxes wxGUI.vnet) +set(img_files + wxGUI_iscatt.jpg + wxGUI_layer_manager.png + wxGUI_map_display.jpg + wxGUI_modules_flags.png + wxGUI_modules_parameters.png + wxGUI_modules_style_left.png + wxGUI_modules_style_top.png + wxGUI_modules_widget_file1.png + wxGUI_modules_widget_file2.png + wxGUI_modules_widget_selection.png + wxGUI_nviz_toolbar.jpg + wxGUI_nviz_tools_light.jpg + wxGUI_nviz_tools_surface.jpg + wxGUI_nviz_tools_vector.jpg + wxGUI_nviz_tools_view.jpg + wxGUI_nviz_tools_volume.jpg + wxGUI_toolboxes.jpg + wxGUI_vnet.jpg) + add_custom_target(wxpython_docs DEPENDS grass_gis LIB_PYTHON) add_dependencies(GUI_WXPYTHON wxpython_docs) -foreach(html_file ${wxpython_html_files}) - add_custom_command( - TARGET wxpython_docs - PRE_BUILD - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMAND ${grass_env_command} ${PYTHON_EXECUTABLE} ${MKHTML_PY} ${html_file} - > ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${html_file}.html - BYPRODUCTS ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${html_file}.html) - install(FILES ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/${html_file}.html - DESTINATION ${GRASS_INSTALL_DOCDIR}) -endforeach() - -file( - GLOB img_files - LIST_DIRECTORIES FALSE - *.png *.jpg) +generate_docs_list( + TARGET wxpython_docs + DOC_FILES ${doc_files} + IMG_FILES ${img_files}) -if(img_files) - install(FILES ${img_files} DESTINATION ${GRASS_INSTALL_DOCDIR}) -endif() +unset(doc_files) +unset(img_files) diff --git a/imagery/CMakeLists.txt b/imagery/CMakeLists.txt index 41f93c94711..f6126c8d5ea 100644 --- a/imagery/CMakeLists.txt +++ b/imagery/CMakeLists.txt @@ -45,7 +45,7 @@ add_custom_target( COMMENT "All imagery modules are built.") if(WITH_DOCS) - generate_html(TARGET ALL_IMAGERY_MODULES NAME imageryintro) + generate_docs(imageryintro TARGET ALL_IMAGERY_MODULES) file(COPY ${CMAKE_SOURCE_DIR}/lib/imagery/band_references_scheme.png DESTINATION ${OUTDIR}/${GRASS_INSTALL_DOCDIR}) diff --git a/lib/db/sqlp/CMakeLists.txt b/lib/db/sqlp/CMakeLists.txt index 6cdc6a88ac8..ce4fcc0f2bd 100644 --- a/lib/db/sqlp/CMakeLists.txt +++ b/lib/db/sqlp/CMakeLists.txt @@ -10,4 +10,4 @@ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/sqlp.tab.c GENERATED) set(sqlp_SRCS alloc.c print.c sql.c ${CMAKE_CURRENT_BINARY_DIR}/sqlp.tab.c ${CMAKE_CURRENT_BINARY_DIR}/sqlp.yy.c) -build_module(NAME grass_sqlp SOURCES "${sqlp_SRCS}" NO_DOCS) +build_module(NAME grass_sqlp SOURCES "${sqlp_SRCS}" HTML_FILE_NAME sql) diff --git a/lib/init/CMakeLists.txt b/lib/init/CMakeLists.txt index a02829c96ec..a09eac66edb 100644 --- a/lib/init/CMakeLists.txt +++ b/lib/init/CMakeLists.txt @@ -1,13 +1,26 @@ # #for i18N support -file(GLOB init_HTMLFILES "*.html") add_custom_target(ADD_INIT_DOCS ALL COMMENT "Generate init docs.") if(WITH_DOCS) - foreach(html_file ${init_HTMLFILES}) - get_filename_component(filename ${html_file} NAME_WLE) - generate_html(TARGET ADD_INIT_DOCS NAME ${filename}) - endforeach() + + generate_docs_list( + TARGET ADD_INIT_DOCS + DOC_FILES + grass + helptext + variables + IMG_FILES + grass_start.png + grassdb.png + help_project_structure.png + location-add.png + location-download.png + location.png + mapset.png + raster-import.png + vector-import.png) + endif() # START_UP is the variable used in grass.py, grass.sh.in and grass.bat.in diff --git a/lib/vector/CMakeLists.txt b/lib/vector/CMakeLists.txt index 159b148a5a2..24c42eaa123 100644 --- a/lib/vector/CMakeLists.txt +++ b/lib/vector/CMakeLists.txt @@ -62,5 +62,5 @@ build_library_in_subdir( GDAL::GDAL) if(WITH_DOCS) - generate_html(TARGET grass_vector NAME vectorascii) + generate_docs(vectorascii TARGET grass_vector) endif() diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index 806dc1e3339..fc24e39aa2f 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -109,17 +109,6 @@ add_custom_target( COMMAND ${grass_env_command} ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/build_check.py ${OUTDIR}/${GRASS_INSTALL_DOCDIR} - DEPENDS ${category_targets} ALL_MODULES LIB_PYTHON GUI_WXPYTHON + DEPENDS ${category_targets} build_class_graphical ALL_MODULES LIB_PYTHON GUI_WXPYTHON COMMENT "man generation: check output") set_target_properties(build_check PROPERTIES FOLDER man) - -#[=======[ TODO: implement somehow... -add_custom_target( - create_man_pages ALL - DEPENDS build_check - COMMAND ${CMAKE_COMMAND} -DHTML2MAN=${HTML2MAN} - -DGRASS_INSTALL_DOCDIR=${GRASS_INSTALL_DOCDIR} -DOUTDIR=${OUTDIR} - -DGRASS_INSTALL_MANDIR=${GRASS_INSTALL_MANDIR} -P - ${CMAKE_SOURCE_DIR}/cmake/generate_man_pages.cmake - COMMENT "!!! man generation: create man pages") -]=======] diff --git a/raster/CMakeLists.txt b/raster/CMakeLists.txt index 325cf179d79..a70f0bb9f08 100644 --- a/raster/CMakeLists.txt +++ b/raster/CMakeLists.txt @@ -145,7 +145,7 @@ add_custom_target( COMMENT "All raster modules are built.") if(WITH_DOCS) - generate_html(TARGET ALL_RASTER_MODULES NAME rasterintro) + generate_docs(rasterintro TARGET ALL_RASTER_MODULES) endif() build_program_in_subdir(r.basins.fill DEPENDS grass_gis grass_raster) diff --git a/raster/r.li/CMakeLists.txt b/raster/r.li/CMakeLists.txt index eae49565492..29b388f8498 100644 --- a/raster/r.li/CMakeLists.txt +++ b/raster/r.li/CMakeLists.txt @@ -28,7 +28,7 @@ build_library_in_subdir( "r.li.daemon") if(WITH_DOCS) - generate_html(TARGET grass_rli NAME r.li) + generate_docs(r.li TARGET grass_rli) endif() foreach(SUBDIR ${SUBDIRS1}) diff --git a/raster3d/CMakeLists.txt b/raster3d/CMakeLists.txt index ab4eaca79df..6e2d562ffdf 100644 --- a/raster3d/CMakeLists.txt +++ b/raster3d/CMakeLists.txt @@ -33,7 +33,7 @@ add_custom_target( COMMENT "All temporal modules are built.") if(WITH_DOCS) - generate_html(TARGET ALL_RASTER3D_MODULES NAME raster3dintro) + generate_docs(raster3dintro TARGET ALL_RASTER3D_MODULES) endif() build_program_in_subdir(r3.cross.rast DEPENDS grass_gis grass_raster diff --git a/temporal/CMakeLists.txt b/temporal/CMakeLists.txt index ae4fc25fab6..8878789ee4e 100644 --- a/temporal/CMakeLists.txt +++ b/temporal/CMakeLists.txt @@ -58,7 +58,7 @@ add_custom_target( COMMENT "All temporal modules are built.") if(WITH_DOCS) - generate_html(TARGET ALL_TEMPORAL_MODULES NAME temporalintro) + generate_docs(temporalintro TARGET ALL_TEMPORAL_MODULES) endif() build_program_in_subdir(t.connect DEPENDS grass_gis grass_temporal) diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index ba7e4fddf5d..a7060339025 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -1,15 +1,22 @@ -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/mkhtml.py - DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/mkdocs.py - DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/mkmarkdown.py - DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/mkrest.py - DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/thumbnails.py - DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/generate_last_commit_file.py - DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +# Copy utility script files, fix file permissions +set(py_files + g.html2man/g.html2man.py + g.html2man/ggroff.py + g.html2man/ghtml.py + generate_last_commit_file.py + mkdocs.py + mkhtml.py + mkmarkdown.py + thumbnails.py) +foreach(py_file ${py_files}) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${py_file} ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + cmake_path(GET py_file FILENAME pyfile) + file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/${pyfile} + FILE_PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) +endforeach() set(current_time_s_ms_SRCS "timer/main.c") if(MSVC) @@ -38,43 +45,43 @@ build_program( "NONE" NO_DOCS) add_dependencies(g.echo python_doc_utils) + add_custom_target( python_doc_utils COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/g.html2man/g.html2man.py + ${CMAKE_CURRENT_BINARY_DIR}/g.html2man.py ${OUTDIR}/${GRASS_INSTALL_UTILSDIR} COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/generate_last_commit_file.py + ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/generate_last_commit_file.py ${OUTDIR}/${GRASS_INSTALL_UTILSDIR} COMMAND - ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/g.html2man/g.html2man.py + ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/g.html2man.py ${OUTDIR}/${GRASS_INSTALL_UTILSDIR} COMMAND - ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/g.html2man/ggroff.py + ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/ggroff.py ${OUTDIR}/${GRASS_INSTALL_UTILSDIR} COMMAND - ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/g.html2man/ghtml.py + ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/ghtml.py ${OUTDIR}/${GRASS_INSTALL_UTILSDIR} COMMAND - ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/mkhtml.py + ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/mkhtml.py ${OUTDIR}/${GRASS_INSTALL_UTILSDIR} COMMAND - ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/mkdocs.py + ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/mkdocs.py ${OUTDIR}/${GRASS_INSTALL_UTILSDIR} COMMAND - ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/mkmarkdown.py + ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/mkmarkdown.py ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}) install( - FILES ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/g.html2man.py - ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/generate_last_commit_file.py - ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/ggroff.py - ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/g.html2man.py - ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/ghtml.py - ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/mkhtml.py - ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/mkdocs.py - ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/mkmarkdown.py - DESTINATION ${GRASS_INSTALL_UTILSDIR}) + PROGRAMS + ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/g.html2man.py + ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/generate_last_commit_file.py + ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/ggroff.py + ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/ghtml.py + ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/mkdocs.py + ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/mkhtml.py + ${OUTDIR}/${GRASS_INSTALL_UTILSDIR}/mkmarkdown.py + DESTINATION + ${GRASS_INSTALL_UTILSDIR}) diff --git a/vector/CMakeLists.txt b/vector/CMakeLists.txt index 72397f95a61..2b9358911a4 100644 --- a/vector/CMakeLists.txt +++ b/vector/CMakeLists.txt @@ -111,9 +111,10 @@ add_custom_target( COMMENT "All vector modules are built.") if(WITH_DOCS) - generate_html(TARGET ALL_VECTOR_MODULES NAME vectorintro) - generate_html(TARGET ALL_VECTOR_MODULES NAME lrs SOURCEDIR - ${CMAKE_CURRENT_SOURCE_DIR}/v.lrs) + generate_docs(vectorintro TARGET ALL_VECTOR_MODULES) + generate_docs(lrs + TARGET ALL_VECTOR_MODULES + SOURCEDIR "${CMAKE_CURRENT_SOURCE_DIR}/v.lrs") endif() # build v.buffer only with GEOS following