From 1b0ff575626798628c11be3894c2e4ed208f81bc Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Thu, 18 Jan 2018 16:37:19 +0300 Subject: [PATCH] Merge pull request #10621 from mshabunin:disable-docs Documentation generation refactoring (#10621) * Documentation build updates: - disable documentation by default, do not add to ALL target - combine Doxygen and Javadoc - optimize Doxygen html * javadoc: fix path in build directory * cmake: fix "Documentation" status line --- CMakeLists.txt | 19 +++---- cmake/OpenCVExtraTargets.cmake | 7 +++ cmake/OpenCVUtils.cmake | 8 +++ doc/CMakeLists.txt | 89 ++++++++++++------------------ doc/DoxygenLayout.xml | 1 + doc/footer.html | 66 +--------------------- doc/header.html | 31 +---------- doc/tutorial-utils.js | 98 +++++++++++++++++++++++++++++++++ modules/CMakeLists.txt | 21 +++++++ modules/java/jar/CMakeLists.txt | 33 ++++++----- modules/java/jar/build.xml.in | 2 +- 11 files changed, 202 insertions(+), 173 deletions(-) create mode 100644 doc/tutorial-utils.js diff --git a/CMakeLists.txt b/CMakeLists.txt index fe4527c253..0262cd3a97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -271,7 +271,7 @@ OCV_OPTION(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead o OCV_OPTION(BUILD_opencv_apps "Build utility applications (used for example to train classifiers)" (NOT ANDROID AND NOT WINRT) IF (NOT APPLE_FRAMEWORK) ) OCV_OPTION(BUILD_opencv_js "Build JavaScript bindings by Emscripten" OFF ) OCV_OPTION(BUILD_ANDROID_EXAMPLES "Build examples for Android platform" ON IF ANDROID ) -OCV_OPTION(BUILD_DOCS "Create build rules for OpenCV Documentation" ON IF (NOT WINRT AND NOT APPLE_FRAMEWORK)) +OCV_OPTION(BUILD_DOCS "Create build rules for OpenCV Documentation" OFF IF (NOT WINRT AND NOT APPLE_FRAMEWORK)) OCV_OPTION(BUILD_EXAMPLES "Build all examples" OFF ) OCV_OPTION(BUILD_PACKAGE "Enables 'make package_source' command" ON IF NOT WINRT) OCV_OPTION(BUILD_PERF_TESTS "Build performance tests" ON IF (NOT APPLE_FRAMEWORK) ) @@ -616,14 +616,6 @@ include(cmake/OpenCVFindLAPACK.cmake) # Detect other 3rd-party libraries/tools # ---------------------------------------------------------------------------- -# --- Doxygen for documentation --- -add_custom_target(opencv_docs ALL) -if(BUILD_DOCS) - find_package(Doxygen) -else() - unset(DOXYGEN_FOUND CACHE) -endif() - # --- Java Support --- if(BUILD_JAVA) include(cmake/OpenCVDetectApacheAnt.cmake) @@ -1041,7 +1033,14 @@ ocv_build_features_string(apps_status IF BUILD_ANDROID_EXAMPLES AND CAN_BUILD_ANDROID_PROJECTS THEN "android_examples" ELSE "-") status(" Applications:" "${apps_status}") -status(" Documentation:" BUILD_DOCS AND DOXYGEN_FOUND THEN "YES (${DOXYGEN_EXECUTABLE} ${DOXYGEN_VERSION})" ELSE "NO") +ocv_build_features_string(docs_status + IF TARGET doxygen_cpp THEN "doxygen" + IF TARGET doxygen_python THEN "python" + IF TARGET doxygen_javadoc THEN "javadoc" + IF BUILD_opencv_js OR DEFINED OPENCV_JS_LOCATION THEN "js" + ELSE "NO" +) +status(" Documentation:" "${docs_status}") status(" Non-free algorithms:" OPENCV_ENABLE_NONFREE THEN "YES" ELSE "NO") # ========================== Android details ========================== diff --git a/cmake/OpenCVExtraTargets.cmake b/cmake/OpenCVExtraTargets.cmake index ecb2a3b36a..8dd8a970b6 100644 --- a/cmake/OpenCVExtraTargets.cmake +++ b/cmake/OpenCVExtraTargets.cmake @@ -36,3 +36,10 @@ if(BUILD_PERF_TESTS) set_target_properties(opencv_perf_tests PROPERTIES FOLDER "extra") endif() endif() + +# Documentation +if(BUILD_DOCS) + add_custom_target(opencv_docs) + add_custom_target(install_docs DEPENDS opencv_docs + COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=docs -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") +endif() diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 20b38ec804..1a4d1cbd4d 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -1422,3 +1422,11 @@ macro(ocv_copyfiles_add_target target list_var comment_str) ) add_custom_target(${target} DEPENDS "${OPENCV_DEPHELPER}/${target}") endmacro() + + +# Needed by install(DIRECTORY ...) +if(NOT CMAKE_VERSION VERSION_LESS 3.1) + set(compatible_MESSAGE_NEVER MESSAGE_NEVER) +else() + set(compatible_MESSAGE_NEVER "") +endif() diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index f1f5dc22b2..7fd97b1d24 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,37 +1,18 @@ -#----------------------- -# CMake file for OpenCV docs -#----------------------- - -if(BUILD_DOCS AND DOXYGEN_FOUND) - set(HAVE_DOC_GENERATOR TRUE) -else() - set(HAVE_DOC_GENERATOR FALSE) +if(NOT BUILD_DOCS) + return() endif() -if(HAVE_DOC_GENERATOR) - project(opencv_docs) - # build lists of modules to be documented - set(BASE_MODULES "") - set(EXTRA_MODULES "") +# Dependencies scheme (* - optional): +# +# javadoc* -> doxygen_javadoc* -> doxygen_cpp ---------> doxygen -> opencv_docs +# \ \ / / +# \ -> doxygen_python* -> / +# ----------------------------------------------------------> - foreach(mod ${OPENCV_MODULES_BUILD} ${OPENCV_MODULES_DISABLED_USER} ${OPENCV_MODULES_DISABLED_AUTO} ${OPENCV_MODULES_DISABLED_FORCE}) - string(REGEX REPLACE "^opencv_" "" mod "${mod}") - if("${OPENCV_MODULE_opencv_${mod}_LOCATION}" STREQUAL "${OpenCV_SOURCE_DIR}/modules/${mod}") - list(APPEND BASE_MODULES ${mod}) - else() - list(APPEND EXTRA_MODULES ${mod}) - endif() - endforeach() - ocv_list_sort(BASE_MODULES) - ocv_list_sort(EXTRA_MODULES) - set(FIXED_ORDER_MODULES core imgproc imgcodecs videoio highgui video calib3d features2d objdetect dnn ml flann photo stitching) - list(REMOVE_ITEM BASE_MODULES ${FIXED_ORDER_MODULES}) - set(BASE_MODULES ${FIXED_ORDER_MODULES} ${BASE_MODULES}) -endif(HAVE_DOC_GENERATOR) +find_package(Doxygen) +if(DOXYGEN_FOUND) + add_custom_target(doxygen) -# ========= Doxygen docs ========= - -if(BUILD_DOCS AND DOXYGEN_FOUND) # not documented modules list list(APPEND blacklist "ts" "java_bindings_generator" "java" "python_bindings_generator" "python2" "python3" "js" "world") unset(CMAKE_DOXYGEN_TUTORIAL_CONTRIB_ROOT) @@ -49,7 +30,7 @@ if(BUILD_DOCS AND DOXYGEN_FOUND) set(refs_main) set(refs_extra) set(deps) - foreach(m ${BASE_MODULES} ${EXTRA_MODULES}) + foreach(m ${OPENCV_MODULES_MAIN} ${OPENCV_MODULES_EXTRA}) list(FIND blacklist ${m} _pos) if(${_pos} EQUAL -1) # include folder @@ -105,7 +86,7 @@ if(BUILD_DOCS AND DOXYGEN_FOUND) endif() # Reference entry set(one_ref "\t- ${m}. @ref ${m}\n") - list(FIND EXTRA_MODULES ${m} _pos) + list(FIND OPENCV_MODULES_EXTRA ${m} _pos) if(${_pos} EQUAL -1) set(refs_main "${refs_main}${one_ref}") else() @@ -145,7 +126,7 @@ if(BUILD_DOCS AND DOXYGEN_FOUND) string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_IMAGE_PATH "${paths_doc} ; ${tutorial_path} ; ${tutorial_py_path} ; ${tutorial_js_path} ; ${paths_tutorial}") # TODO: remove paths_doc from EXAMPLE_PATH after face module tutorials/samples moved to separate folders string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_EXAMPLE_PATH "${example_path} ; ${paths_doc} ; ${paths_sample}") - set(CMAKE_DOXYGEN_LAYOUT "${CMAKE_CURRENT_SOURCE_DIR}/DoxygenLayout.xml") + set(CMAKE_DOXYGEN_LAYOUT "${CMAKE_CURRENT_BINARY_DIR}/DoxygenLayout.xml") set(CMAKE_DOXYGEN_OUTPUT_PATH "doxygen") set(CMAKE_DOXYGEN_MAIN_REFERENCE "${refs_main}") set(CMAKE_DOXYGEN_EXTRA_REFERENCE "${refs_extra}") @@ -160,10 +141,12 @@ if(BUILD_DOCS AND DOXYGEN_FOUND) list(APPEND CMAKE_DOXYGEN_HTML_FILES "${CMAKE_CURRENT_SOURCE_DIR}/pattern.png") list(APPEND CMAKE_DOXYGEN_HTML_FILES "${CMAKE_CURRENT_SOURCE_DIR}/acircles_pattern.png") list(APPEND CMAKE_DOXYGEN_HTML_FILES "${CMAKE_CURRENT_SOURCE_DIR}/bodybg.png") - list(APPEND CMAKE_DOXYGEN_HTML_FILES "${CMAKE_CURRENT_SOURCE_DIR}/mymath.sty") + # list(APPEND CMAKE_DOXYGEN_HTML_FILES "${CMAKE_CURRENT_SOURCE_DIR}/mymath.sty") + list(APPEND CMAKE_DOXYGEN_HTML_FILES "${CMAKE_CURRENT_SOURCE_DIR}/tutorial-utils.js") string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_HTML_FILES "${CMAKE_DOXYGEN_HTML_FILES}") # writing file + configure_file(DoxygenLayout.xml DoxygenLayout.xml @ONLY) configure_file(Doxyfile.in ${doxyfile} @ONLY) configure_file(root.markdown.in ${rootfile} @ONLY) @@ -211,11 +194,6 @@ if(BUILD_DOCS AND DOXYGEN_FOUND) COMMENT "Generate Doxygen documentation" ) - install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doxygen/html - DESTINATION "${OPENCV_DOC_INSTALL_PATH}" - COMPONENT "docs" OPTIONAL - ) - if(NOT DEFINED HAVE_PYTHON_BS4 AND PYTHON_DEFAULT_EXECUTABLE) # Documentation post-processing tool requires BuautifulSoup Python package execute_process(COMMAND "${PYTHON_DEFAULT_EXECUTABLE}" -c "import bs4; from bs4 import BeautifulSoup; print(bs4.__version__)" @@ -231,27 +209,32 @@ if(BUILD_DOCS AND DOXYGEN_FOUND) endif() endif() - if(PYTHON_DEFAULT_EXECUTABLE AND HAVE_PYTHON_BS4 - AND OPENCV_PYTHON_SIGNATURES_FILE AND TARGET gen_opencv_python_source) + if(PYTHON_DEFAULT_EXECUTABLE + AND HAVE_PYTHON_BS4 + AND OPENCV_PYTHON_SIGNATURES_FILE + AND TARGET gen_opencv_python_source) add_custom_target(doxygen_python COMMAND ${PYTHON_DEFAULT_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/tools/add_signatures.py" "${CMAKE_CURRENT_BINARY_DIR}/doxygen/html/" "${OPENCV_PYTHON_SIGNATURES_FILE}" "python" DEPENDS doxygen_cpp gen_opencv_python_source COMMENT "Inject Python signatures into documentation" ) - add_custom_target(doxygen - DEPENDS doxygen_cpp doxygen_python - ) - else() - add_custom_target(doxygen - DEPENDS doxygen_cpp - ) endif() - # Alias to build/install docs only - add_custom_target(install_docs - DEPENDS doxygen - COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=docs -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" - ) + add_dependencies(doxygen doxygen_cpp) + + if(TARGET doxygen_python) + add_dependencies(doxygen doxygen_python) + endif() + + if(TARGET doxygen_javadoc) + add_dependencies(doxygen_cpp doxygen_javadoc) + endif() add_dependencies(opencv_docs doxygen) + + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doxygen/html + DESTINATION "${OPENCV_DOC_INSTALL_PATH}" + COMPONENT "docs" OPTIONAL + ${compatible_MESSAGE_NEVER} + ) endif() diff --git a/doc/DoxygenLayout.xml b/doc/DoxygenLayout.xml index b2675719c9..1385327f62 100644 --- a/doc/DoxygenLayout.xml +++ b/doc/DoxygenLayout.xml @@ -17,6 +17,7 @@ + @CMAKE_DOXYGEN_JAVADOC_NODE@ diff --git a/doc/footer.html b/doc/footer.html index a0b4d5ce32..8817f301dd 100644 --- a/doc/footer.html +++ b/doc/footer.html @@ -19,71 +19,7 @@ $generatedby   diff --git a/doc/header.html b/doc/header.html index 94d42b400a..69e8c0df17 100644 --- a/doc/header.html +++ b/doc/header.html @@ -11,6 +11,7 @@ + $treeview $search $mathjax @@ -54,34 +55,4 @@ $extrastylesheet - diff --git a/doc/tutorial-utils.js b/doc/tutorial-utils.js new file mode 100644 index 0000000000..6462872580 --- /dev/null +++ b/doc/tutorial-utils.js @@ -0,0 +1,98 @@ +function getLabelName(innerHTML) { + var str = innerHTML.toLowerCase(); + // Replace all '+' with 'p' + str = str.split('+').join('p'); + // Replace all ' ' with '_' + str = str.split(' ').join('_'); + // Replace all '#' with 'sharp' + str = str.split('#').join('sharp'); + // Replace other special characters with 'ascii' + code + for (var i = 0; i < str.length; i++) { + var charCode = str.charCodeAt(i); + if (!(charCode == 95 || (charCode > 96 && charCode < 123) || (charCode > 47 && charCode < 58))) + str = str.substr(0, i) + 'ascii' + charCode + str.substr(i + 1); + } + return str; +} + +function addToggle() { + var $getDiv = $('div.newInnerHTML').last(); + var buttonName = $getDiv.html(); + var label = getLabelName(buttonName.trim()); + $getDiv.attr("title", label); + $getDiv.hide(); + $getDiv = $getDiv.next(); + $getDiv.attr("class", "toggleable_div label_" + label); + $getDiv.hide(); +} + +function addButton(label, buttonName) { + var b = document.createElement("BUTTON"); + b.innerHTML = buttonName; + b.setAttribute('class', 'toggleable_button label_' + label); + b.onclick = function() { + $('.toggleable_button').css({ + border: '2px outset', + 'border-radius': '4px' + }); + $('.toggleable_button.label_' + label).css({ + border: '2px inset', + 'border-radius': '4px' + }); + $('.toggleable_div').css('display', 'none'); + $('.toggleable_div.label_' + label).css('display', 'block'); + }; + b.style.border = '2px outset'; + b.style.borderRadius = '4px'; + b.style.margin = '2px'; + return b; +} + +function buttonsToAdd($elements, $heading, $type) { + if ($elements.length === 0) { + $elements = $("" + $type + ":contains(" + $heading.html() + ")").parent().prev("div.newInnerHTML"); + } + var arr = jQuery.makeArray($elements); + var seen = {}; + arr.forEach(function(e) { + var txt = e.innerHTML; + if (!seen[txt]) { + $button = addButton(e.title, txt); + if (Object.keys(seen).length == 0) { + var linebreak1 = document.createElement("br"); + var linebreak2 = document.createElement("br"); + ($heading).append(linebreak1); + ($heading).append(linebreak2); + } + ($heading).append($button); + seen[txt] = true; + } + }); + return; +} + +function addTutorialsButtons() { + $("h2").each(function() { + $heading = $(this); + $smallerHeadings = $(this).nextUntil("h2").filter("h3").add($(this).nextUntil("h2").find("h3")); + if ($smallerHeadings.length) { + $smallerHeadings.each(function() { + var $elements = $(this).nextUntil("h2,h3").filter("div.newInnerHTML"); + buttonsToAdd($elements, $(this), "h3"); + }); + } else { + var $elements = $(this).nextUntil("h2").filter("div.newInnerHTML"); + buttonsToAdd($elements, $heading, "h2"); + } + }); + $(".toggleable_button").first().click(); + var $clickDefault = $('.toggleable_button.label_python').first(); + if ($clickDefault.length) { + $clickDefault.click(); + } + $clickDefault = $('.toggleable_button.label_cpp').first(); + if ($clickDefault.length) { + $clickDefault.click(); + } + return; +} diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 2c6c34304e..edbfe1a82a 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -5,3 +5,24 @@ if(NOT OPENCV_MODULES_PATH) endif() ocv_glob_modules(${OPENCV_MODULES_PATH} EXTRA ${OPENCV_EXTRA_MODULES_PATH}) + +# build lists of modules to be documented +set(OPENCV_MODULES_MAIN "") +set(OPENCV_MODULES_EXTRA "") + +foreach(mod ${OPENCV_MODULES_BUILD} ${OPENCV_MODULES_DISABLED_USER} ${OPENCV_MODULES_DISABLED_AUTO} ${OPENCV_MODULES_DISABLED_FORCE}) + string(REGEX REPLACE "^opencv_" "" mod "${mod}") + if("${OPENCV_MODULE_opencv_${mod}_LOCATION}" STREQUAL "${OpenCV_SOURCE_DIR}/modules/${mod}") + list(APPEND OPENCV_MODULES_MAIN ${mod}) + else() + list(APPEND OPENCV_MODULES_EXTRA ${mod}) + endif() +endforeach() +ocv_list_sort(OPENCV_MODULES_MAIN) +ocv_list_sort(OPENCV_MODULES_EXTRA) +set(FIXED_ORDER_MODULES core imgproc imgcodecs videoio highgui video calib3d features2d objdetect dnn ml flann photo stitching) +list(REMOVE_ITEM OPENCV_MODULES_MAIN ${FIXED_ORDER_MODULES}) +set(OPENCV_MODULES_MAIN ${FIXED_ORDER_MODULES} ${OPENCV_MODULES_MAIN}) + +set(OPENCV_MODULES_MAIN ${OPENCV_MODULES_MAIN} CACHE INTERNAL "List of main modules" FORCE) +set(OPENCV_MODULES_EXTRA ${OPENCV_MODULES_EXTRA} CACHE INTERNAL "List of extra modules" FORCE) diff --git a/modules/java/jar/CMakeLists.txt b/modules/java/jar/CMakeLists.txt index 3c3c47a1f7..4771900848 100644 --- a/modules/java/jar/CMakeLists.txt +++ b/modules/java/jar/CMakeLists.txt @@ -30,24 +30,29 @@ add_custom_command(OUTPUT "${OPENCV_DEPHELPER}/${the_module}_jar" ) add_custom_target(${the_module}_jar DEPENDS "${OPENCV_DEPHELPER}/${the_module}_jar") -add_custom_command(OUTPUT "${OPENCV_DEPHELPER}/${the_module}doc" - COMMAND ${ANT_EXECUTABLE} -noinput -k javadoc - COMMAND ${CMAKE_COMMAND} -E touch "${OPENCV_DEPHELPER}/${the_module}doc" - WORKING_DIRECTORY "${OPENCV_JAVA_DIR}" - DEPENDS ${depends} - COMMENT "Generating Javadoc" -) -add_custom_target(${the_module}doc DEPENDS "${OPENCV_DEPHELPER}/${the_module}doc") - install(FILES ${OPENCV_JAR_FILE} OPTIONAL DESTINATION ${OPENCV_JAR_INSTALL_PATH} COMPONENT java) add_dependencies(${the_module} ${the_module}_jar) if(BUILD_DOCS) - add_dependencies(opencv_docs ${the_module}doc) - - install(DIRECTORY ${OpenCV_BINARY_DIR}/doc/javadoc - DESTINATION "${OPENCV_DOC_INSTALL_PATH}/javadoc" - COMPONENT "docs" OPTIONAL + add_custom_command(OUTPUT "${OPENCV_DEPHELPER}/${the_module}doc" + COMMAND ${ANT_EXECUTABLE} -noinput -k javadoc + COMMAND ${CMAKE_COMMAND} -E touch "${OPENCV_DEPHELPER}/${the_module}doc" + WORKING_DIRECTORY "${OPENCV_JAVA_DIR}" + DEPENDS ${depends} + COMMENT "Generating Javadoc" ) + add_custom_target(${the_module}doc DEPENDS "${OPENCV_DEPHELPER}/${the_module}doc") + install(DIRECTORY ${OpenCV_BINARY_DIR}/doc/doxygen/html/javadoc + DESTINATION "${OPENCV_DOC_INSTALL_PATH}/html" + COMPONENT "docs" OPTIONAL + ${compatible_MESSAGE_NEVER} + ) + set(CMAKE_DOXYGEN_JAVADOC_NODE + "" + CACHE INTERNAL "Link to the Java documentation") # set to the cache to make it global + add_custom_target(doxygen_javadoc DEPENDS ${the_module}doc) + add_dependencies(opencv_docs ${the_module}doc) +else() + unset(CMAKE_DOXYGEN_JAVADOC_NODE CACHE) endif() diff --git a/modules/java/jar/build.xml.in b/modules/java/jar/build.xml.in index 04356a6904..d4f01931b2 100644 --- a/modules/java/jar/build.xml.in +++ b/modules/java/jar/build.xml.in @@ -32,7 +32,7 @@