summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <[email protected]>2025-03-28 09:00:01 +0100
committerJoerg Bornemann <[email protected]>2025-06-02 19:18:04 +0200
commiteaf87cdfd811955e4ef166451865fff0c843abfd (patch)
tree1979577e67fe7777502d6f805dda1b4c0d192769
parent89e7facc2e3095684e64f16103cfce017235e504 (diff)
CMake: Add targets for building Android docs from Java sourcesHEADdev
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.cmake186
-rw-r--r--cmake/QtAutoDetectHelpers.cmake5
-rw-r--r--cmake/QtBuildHelpers.cmake1
-rw-r--r--cmake/QtBuildOptionsHelpers.cmake10
-rw-r--r--cmake/QtDocsHelpers.cmake82
-rw-r--r--cmake/QtJavaHelpers.cmake1
-rw-r--r--cmake/QtPlatformAndroid.cmake27
-rw-r--r--cmake/QtPublicAndroidHelpers.cmake33
-rw-r--r--src/android/CMakeLists.txt1
-rw-r--r--src/network/CMakeLists.txt1
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