diff options
author | Joerg Bornemann <[email protected]> | 2025-03-28 09:00:01 +0100 |
---|---|---|
committer | Joerg Bornemann <[email protected]> | 2025-06-02 19:18:04 +0200 |
commit | eaf87cdfd811955e4ef166451865fff0c843abfd (patch) | |
tree | 1979577e67fe7777502d6f805dda1b4c0d192769 | |
parent | 89e7facc2e3095684e64f16103cfce017235e504 (diff) |
One can now run "ninja android_docs" to generate HTML docs for Android
Java sources of Qt. This is done with javadoc.
One can now run "ninja android_source_jars" to generate source jars for
Android. They're supposed to be loaded into an IDE.
The targets are enabled automatically for Android builds.
For non-Android builds, set QT_BUILD_HOST_JAVA_DOCS=ON to create those
targets. In that case you must also set ANDROID_SDK_ROOT.
Fixes: QTBUG-117028
Change-Id: I2df51153359a95870c055d3ee373b8381f10cb51
Reviewed-by: Alexandru Croitor <[email protected]>
Reviewed-by: Alexey Edelev <[email protected]>
Reviewed-by: Nicholas Bennett <[email protected]>
-rw-r--r-- | cmake/QtAndroidHelpers.cmake | 186 | ||||
-rw-r--r-- | cmake/QtAutoDetectHelpers.cmake | 5 | ||||
-rw-r--r-- | cmake/QtBuildHelpers.cmake | 1 | ||||
-rw-r--r-- | cmake/QtBuildOptionsHelpers.cmake | 10 | ||||
-rw-r--r-- | cmake/QtDocsHelpers.cmake | 82 | ||||
-rw-r--r-- | cmake/QtJavaHelpers.cmake | 1 | ||||
-rw-r--r-- | cmake/QtPlatformAndroid.cmake | 27 | ||||
-rw-r--r-- | cmake/QtPublicAndroidHelpers.cmake | 33 | ||||
-rw-r--r-- | src/android/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/network/CMakeLists.txt | 1 |
10 files changed, 315 insertions, 32 deletions
diff --git a/cmake/QtAndroidHelpers.cmake b/cmake/QtAndroidHelpers.cmake index 81b5817967c..64696fff6d4 100644 --- a/cmake/QtAndroidHelpers.cmake +++ b/cmake/QtAndroidHelpers.cmake @@ -287,3 +287,189 @@ function(qt_internal_android_dependencies target) COMPONENT Devel) endfunction() + +function(qt_internal_set_up_build_host_java_docs) + if("${ANDROID_SDK_ROOT}" STREQUAL "") + message(FATAL_ERROR + "QT_HOST_DOCUMENT_JAVA_SOURCES=ON requires setting ANDROID_SDK_ROOT." + ) + endif() + + _qt_internal_locate_android_jar() + set(QT_ANDROID_JAR "${QT_ANDROID_JAR}" PARENT_SCOPE) + set(QT_ANDROID_API_USED_FOR_JAVA "${QT_ANDROID_API_USED_FOR_JAVA}" PARENT_SCOPE) +endfunction() + +# Collect the Java source files that were recorded by qt_internal_add_jar. +# If we're not building for Android, qt_internal_add_jar is not called, and we simple collect +# all java files under the current directory. +function(qt_internal_collect_jar_sources out_var) + if(NOT ANDROID) + file(GLOB_RECURSE sources LIST_DIRECTORIES FALSE "*.java") + set("${out_var}" "${sources}" PARENT_SCOPE) + return() + endif() + + set(no_value_options "") + set(single_value_options DIRECTORY) + set(multi_value_options "") + cmake_parse_arguments(PARSE_ARGV 1 arg + "${no_value_options}" "${single_value_options}" "${multi_value_options}" + ) + _qt_internal_validate_all_args_are_parsed(arg) + + set(directory_arg "") + if(DEFINED arg_DIRECTORY) + set(directory_arg DIRECTORY ${arg_DIRECTORY}) + endif() + + get_directory_property(result ${directory_arg} _qt_jar_sources) + get_directory_property(subdirs ${directory_arg} SUBDIRECTORIES) + foreach(subdir IN LISTS subdirs) + qt_internal_collect_jar_sources(subdir_result DIRECTORY ${subdir}) + if(NOT "${subdir_result}" STREQUAL "") + list(APPEND result ${subdir_result}) + endif() + endforeach() + set("${out_var}" "${result}" PARENT_SCOPE) +endfunction() + +function(qt_internal_add_javadoc_target) + set(no_value_options "") + set(single_value_options + MODULE + OUTPUT_DIR + ) + set(multi_value_options + SOURCES + ) + cmake_parse_arguments(PARSE_ARGV 0 arg + "${no_value_options}" "${single_value_options}" "${multi_value_options}" + ) + _qt_internal_validate_all_args_are_parsed(arg) + + if(TARGET ${arg_MODULE}) + get_target_property(skip ${arg_MODULE} _qt_skip_javadoc) + if(skip) + message(VERBOSE "Skipping generation of Android HTML docs for ${arg_MODULE}.") + return() + endif() + endif() + + # Collect source directories from source file paths. + set(source_dirs "") + foreach(source_path IN LISTS arg_SOURCES) + get_filename_component(dir_path "${source_path}" DIRECTORY) + list(APPEND source_dirs "${dir_path}") + endforeach() + list(REMOVE_DUPLICATES source_dirs) + + # Retrieve package names from source dirs. + set(package_names "") + foreach(source_dir IN LISTS source_dirs) + string(REGEX MATCH "/(org/qtproject/qt/android(/.*|$))" package_dir "${source_dir}") + if(package_dir STREQUAL "") + message(VERBOSE "Java source dir is not a package directory: ${source_dir}") + continue() + endif() + + # Store package_dir without leading slash. + set(package_dir "${CMAKE_MATCH_1}") + + # Use dots instead of slashes for the package name. + string(REPLACE "/" "." package_name "${package_dir}") + + list(APPEND package_names "${package_name}") + endforeach() + + # Strip package paths from the source dirs. + list(TRANSFORM source_dirs REPLACE "/org/qtproject/qt/android.*" "") + list(REMOVE_DUPLICATES source_dirs) + + # Use the correct separator for the --source-path argument. + if(NOT CMAKE_HOST_WIN32) + string(REPLACE ";" ":" source_dirs "${source_dirs}") + endif() + + # Use a response file to avoid quoting issues with the space-separated package names. + set(javadoc_output_dir "${arg_OUTPUT_DIR}/android") + set(response_file "${CMAKE_CURRENT_BINARY_DIR}/doc/.javadocargs") + string(REPLACE ";" " " package_names_space_separated "${package_names}") + file(CONFIGURE + OUTPUT "${response_file}" + CONTENT "${package_names_space_separated} +--class-path \"${QT_ANDROID_JAR}\" +-d \"${javadoc_output_dir}\" +--source-path \"${source_dirs}\"" + ) + + set(module ${arg_MODULE}) + set(javadoc_target android_html_docs_${module}) + add_custom_target(${javadoc_target} ${command_args} + COMMAND ${Java_JAVADOC_EXECUTABLE} "@${response_file}" + COMMENT "Generating Java documentation" + VERBATIM + ) + add_dependencies(docs_android ${javadoc_target}) + + if (QT_WILL_INSTALL) + install(DIRECTORY "${arg_OUTPUT_DIR}/" + DESTINATION "${INSTALL_DOCDIR}/${module}" + COMPONENT _install_docs_android_${module} + EXCLUDE_FROM_ALL + ) + + add_custom_target(install_docs_android_${module} + COMMAND ${CMAKE_COMMAND} + --install "${CMAKE_BINARY_DIR}" + --component _install_docs_android_${module} + COMMENT "Installing Android html docs for ${module}" + ) + else() + add_custom_target(install_docs_android_${module}) + endif() + + add_dependencies(install_docs_android_${module} ${javadoc_target}) + add_dependencies(install_docs_android install_docs_android_${module}) +endfunction() + +function(qt_internal_create_source_jar) + set(no_value_options "") + set(single_value_options MODULE) + set(multi_value_options SOURCES) + cmake_parse_arguments(PARSE_ARGV 0 arg + "${no_value_options}" "${single_value_options}" "${multi_value_options}" + ) + _qt_internal_validate_all_args_are_parsed(arg) + + set(module ${arg_MODULE}) + set(jar_target android_source_jar_${module}) + set(jar_name ${CMAKE_INSTALL_NAMESPACE}AndroidSources${module}) + add_jar(${jar_target} + SOURCES ${arg_SOURCES} + VERSION ${PROJECT_VERSION} + INCLUDE_JARS "${QT_ANDROID_JAR}" + OUTPUT_NAME ${jar_name} + ) + set_target_properties(${jar_target} PROPERTIES EXCLUDE_FROM_ALL ON) + add_dependencies(android_source_jars ${jar_target}) + + if(QT_WILL_INSTALL) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${jar_name}-${PROJECT_VERSION}.jar" + DESTINATION "${INSTALL_DATADIR}/android/${module}" + COMPONENT _install_android_source_jar_${module} + EXCLUDE_FROM_ALL + ) + add_custom_target(install_android_source_jar_${module} + COMMAND ${CMAKE_COMMAND} + --install "${CMAKE_BINARY_DIR}" + --component _install_android_source_jar_${module} + COMMENT "Installing Android source jar for ${module}" + ) + else() + add_custom_target(install_android_source_jar_${module}) + endif() + + add_dependencies(install_android_source_jar_${module} ${jar_target}) + add_dependencies(install_android_source_jars install_android_source_jar_${module}) +endfunction() diff --git a/cmake/QtAutoDetectHelpers.cmake b/cmake/QtAutoDetectHelpers.cmake index 376d92ce91f..a3447346f3e 100644 --- a/cmake/QtAutoDetectHelpers.cmake +++ b/cmake/QtAutoDetectHelpers.cmake @@ -65,6 +65,11 @@ function(qt_auto_detect_wasm) endfunction() function(qt_auto_detect_android) + # Don't assume an Android build if we're requesting to build Java documentation on the host. + if(QT_BUILD_HOST_JAVA_DOCS) + return() + endif() + # We assume an Android build if any of the ANDROID_* cache variables are set. if(DEFINED ANDROID_SDK_ROOT OR DEFINED ANDROID_NDK_ROOT diff --git a/cmake/QtBuildHelpers.cmake b/cmake/QtBuildHelpers.cmake index bfd210a6ec3..60d66eb2353 100644 --- a/cmake/QtBuildHelpers.cmake +++ b/cmake/QtBuildHelpers.cmake @@ -449,6 +449,7 @@ macro(qt_internal_setup_build_and_global_variables) qt_internal_setup_find_host_info_package() qt_internal_setup_build_docs() + qt_internal_setup_build_java_docs_on_host() qt_internal_include_qt_platform_android() diff --git a/cmake/QtBuildOptionsHelpers.cmake b/cmake/QtBuildOptionsHelpers.cmake index 027924103d9..a2f352c39c6 100644 --- a/cmake/QtBuildOptionsHelpers.cmake +++ b/cmake/QtBuildOptionsHelpers.cmake @@ -403,6 +403,16 @@ macro(qt_internal_setup_build_docs) option(QT_BUILD_DOCS "Generate Qt documentation targets" ON) endmacro() +macro(qt_internal_setup_build_java_docs_on_host) + option(QT_BUILD_HOST_JAVA_DOCS "Generate Java documentation targets on host" OFF) + if(QT_BUILD_HOST_JAVA_DOCS) + find_package(Java) + if(Java_FOUND) + include(UseJava) + endif() + endif() +endmacro() + macro(qt_internal_set_use_ccache) option(QT_USE_CCACHE "Enable the use of ccache") if(QT_USE_CCACHE) diff --git a/cmake/QtDocsHelpers.cmake b/cmake/QtDocsHelpers.cmake index 6c7460eea3d..9689bea3e5d 100644 --- a/cmake/QtDocsHelpers.cmake +++ b/cmake/QtDocsHelpers.cmake @@ -79,6 +79,7 @@ function(qt_internal_add_docs) set(opt_args SHOW_INTERNAL + SKIP_JAVADOC ) set(single_args "") set(multi_args @@ -352,9 +353,9 @@ function(qt_internal_add_docs) if (QT_WILL_INSTALL) install(DIRECTORY "${qdoc_output_dir}/" - DESTINATION "${INSTALL_DOCDIR}/${doc_target}" - COMPONENT _install_html_docs_${target} - EXCLUDE_FROM_ALL + DESTINATION "${INSTALL_DOCDIR}/${doc_target}" + COMPONENT _install_html_docs_${target} + EXCLUDE_FROM_ALL ) add_custom_target(install_html_docs_${target} @@ -365,9 +366,9 @@ function(qt_internal_add_docs) ) install(FILES "${qch_file_path}" - DESTINATION "${INSTALL_DOCDIR}" - COMPONENT _install_qch_docs_${target} - EXCLUDE_FROM_ALL + DESTINATION "${INSTALL_DOCDIR}" + COMPONENT _install_qch_docs_${target} + EXCLUDE_FROM_ALL ) add_custom_target(install_qch_docs_${target} @@ -403,4 +404,73 @@ function(qt_internal_add_docs) qt_internal_add_doc_tool_dependency(prepare_docs_${target} qdoc) qt_internal_add_doc_tool_dependency(qch_docs_${target} qhelpgenerator) endif() + + _qt_internal_forward_function_args( + FORWARD_PREFIX arg + FORWARD_OUT_VAR add_java_documentation_args + FORWARD_OPTIONS + SKIP_JAVADOC + ) + qt_internal_add_java_documentation(${target} ${add_java_documentation_args} + OUTPUT_DIR "${qdoc_output_dir}" + ) +endfunction() + +function(qt_internal_add_java_documentation target) + if(NOT ANDROID AND NOT QT_BUILD_HOST_JAVA_DOCS) + return() + endif() + + set(no_value_options + SKIP_JAVADOC + ) + set(single_value_options + OUTPUT_DIR + ) + set(multi_value_options "") + cmake_parse_arguments(PARSE_ARGV 1 arg + "${no_value_options}" "${single_value_options}" "${multi_value_options}" + ) + _qt_internal_validate_all_args_are_parsed(arg) + + # Use a default output directory based on the project name. + if(NOT DEFINED arg_OUTPUT_DIR) + if (QT_WILL_INSTALL) + set(arg_OUTPUT_DIR "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}") + else() + set(arg_OUTPUT_DIR "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}") + endif() + string(APPEND arg_OUTPUT_DIR "/${PROJECT_NAME}") + endif() + + qt_internal_collect_jar_sources(sources) + + # Bail out if we haven't found relevant sources. + if(sources STREQUAL "") + return() + endif() + + if(NOT TARGET docs_android) + add_custom_target(docs_android) + add_custom_target(install_docs_android) + add_dependencies(install_docs_android docs_android) + + add_custom_target(android_source_jars) + add_custom_target(install_android_source_jars) + add_dependencies(install_android_source_jars android_source_jars) + endif() + + if(NOT ANDROID) + qt_internal_set_up_build_host_java_docs() + endif() + + if(NOT arg_SKIP_JAVADOC) + qt_internal_add_javadoc_target( + MODULE ${target} + SOURCES ${sources} + OUTPUT_DIR "${arg_OUTPUT_DIR}" + ) + endif() + + qt_internal_create_source_jar(SOURCES ${sources} MODULE ${target}) endfunction() diff --git a/cmake/QtJavaHelpers.cmake b/cmake/QtJavaHelpers.cmake index ca8b50817e7..249bbd1b17f 100644 --- a/cmake/QtJavaHelpers.cmake +++ b/cmake/QtJavaHelpers.cmake @@ -28,6 +28,7 @@ function(qt_internal_add_jar target) get_filename_component(absolute_path "${path}" ABSOLUTE) list(APPEND absolute_sources "${absolute_path}") endforeach() + set_property(DIRECTORY APPEND PROPERTY _qt_jar_sources "${absolute_sources}") add_jar(${target} SOURCES ${absolute_sources} ${ARGV}) diff --git a/cmake/QtPlatformAndroid.cmake b/cmake/QtPlatformAndroid.cmake index b78b3f7d548..b480b1c14a6 100644 --- a/cmake/QtPlatformAndroid.cmake +++ b/cmake/QtPlatformAndroid.cmake @@ -23,32 +23,7 @@ if (NOT IS_DIRECTORY "${ANDROID_SDK_ROOT}") message(FATAL_ERROR "Could not find ANDROID_SDK_ROOT or path is not a directory: ${ANDROID_SDK_ROOT}") endif() -# This variable specifies the API level used for building Java code, it can be the same as Qt for -# Android's maximum supported Android version or higher. -if(NOT QT_ANDROID_API_USED_FOR_JAVA) - set(QT_ANDROID_API_USED_FOR_JAVA "android-35") -endif() - -set(jar_location "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar") -if(NOT EXISTS "${jar_location}") - _qt_internal_detect_latest_android_platform(android_platform_latest) - if(android_platform_latest) - message(NOTICE "The default platform SDK ${QT_ANDROID_API_USED_FOR_JAVA} not found, " - "using the latest installed ${android_platform_latest} instead.") - set(QT_ANDROID_API_USED_FOR_JAVA ${android_platform_latest}) - endif() -endif() - -set(QT_ANDROID_JAR "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar") -if(NOT EXISTS "${QT_ANDROID_JAR}") - message(FATAL_ERROR - "No suitable Android SDK platform found in '${ANDROID_SDK_ROOT}/platforms'." - " The minimum version required for building Java code is ${QT_ANDROID_API_USED_FOR_JAVA}" - ) -endif() - -message(STATUS "Using Android SDK API ${QT_ANDROID_API_USED_FOR_JAVA} from " - "${ANDROID_SDK_ROOT}/platforms") +_qt_internal_locate_android_jar() # Locate Java include(UseJava) diff --git a/cmake/QtPublicAndroidHelpers.cmake b/cmake/QtPublicAndroidHelpers.cmake index d857cb43844..4baba9f88aa 100644 --- a/cmake/QtPublicAndroidHelpers.cmake +++ b/cmake/QtPublicAndroidHelpers.cmake @@ -45,3 +45,36 @@ function(_qt_internal_sort_android_platforms out_var) endif() set("${out_var}" "${platforms}" PARENT_SCOPE) endfunction() + +function(_qt_internal_locate_android_jar) + # This variable specifies the API level used for building Java code, it can be the same as Qt + # for Android's maximum supported Android version or higher. + if(NOT QT_ANDROID_API_USED_FOR_JAVA) + set(QT_ANDROID_API_USED_FOR_JAVA "android-35") + endif() + + set(jar_location "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar") + if(NOT EXISTS "${jar_location}") + _qt_internal_detect_latest_android_platform(android_platform_latest) + if(android_platform_latest) + message(NOTICE "The default platform SDK ${QT_ANDROID_API_USED_FOR_JAVA} not found, " + "using the latest installed ${android_platform_latest} instead.") + set(QT_ANDROID_API_USED_FOR_JAVA ${android_platform_latest}) + endif() + endif() + + set(QT_ANDROID_JAR "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar") + if(NOT EXISTS "${QT_ANDROID_JAR}") + message(FATAL_ERROR + "No suitable Android SDK platform found in '${ANDROID_SDK_ROOT}/platforms'." + " The minimum version required for building Java code is ${QT_ANDROID_API_USED_FOR_JAVA}" + ) + endif() + + message(STATUS "Using Android SDK API ${QT_ANDROID_API_USED_FOR_JAVA} from " + "${ANDROID_SDK_ROOT}/platforms") + + set(QT_ANDROID_JAR "${QT_ANDROID_JAR}" PARENT_SCOPE) + set(QT_ANDROID_API_USED_FOR_JAVA "${QT_ANDROID_API_USED_FOR_JAVA}" PARENT_SCOPE) +endfunction() + diff --git a/src/android/CMakeLists.txt b/src/android/CMakeLists.txt index 007430598ea..7c99ce7264e 100644 --- a/src/android/CMakeLists.txt +++ b/src/android/CMakeLists.txt @@ -11,3 +11,4 @@ if (ANDROID) add_subdirectory(templates_aar) endif() +qt_internal_add_java_documentation(Global) diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 02459100162..06ffbf71933 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -385,6 +385,7 @@ qt_internal_extend_target(Network CONDITION QT_FEATURE_ocsp AND QT_FEATURE_opens qt_internal_add_docs(Network doc/qtnetwork.qdocconf + SKIP_JAVADOC ) # See mkspecs/common/msvc-desktop.conf |