From 48f7ead2bb8f1f39de29f44938d9ea77e2dd36c8 Mon Sep 17 00:00:00 2001 From: David Hampton Date: Sat, 28 Dec 2024 14:48:49 -0500 Subject: [PATCH] cmake: Support the JAVA_HOME environment variable when building for android. Building for android was only using the android studio installation of java. This worked fine for android studio installations that contained Java 11 or Java 17, but failed at the very end for Java 21. The problem is that the Qt androiddeployqt tool specifically invokes gradle 7.2, and gradle 7.2 only supports up to Java 17. Fix the build support to honor the JAVA_HOME environment variable so that other version of java can be specified at build time. The cmake build instructions now look in the following places to find which java to use: 1) The environment variable JAVA_HOME 2) The option variable MYTH_JAVA_HOME 3) The android studio installation 4) The system version The build will now also check whether or not the version of java it is using is compatible with androiddeployqt. --- CMakeLists.txt | 16 +++++ cmake/MythOptions.cmake | 22 ++----- .../platform/AndroidCrossCustomization.cmake | 6 +- cmake/platform/AndroidCrossPackaging.cmake | 1 + .../AndroidCrossValidateBuildSystem.cmake | 58 +++++++++++++++++++ mythtv/external/libmythbluray/CMakeLists.txt | 7 +-- platform/android/CMakeLists.txt | 4 +- 7 files changed, 89 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f483a4fdfc4..e27a88c3e1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,6 +131,22 @@ endif() if(NOT TARBALL_DIR) set(TARBALL_DIR "${PROJECT_SOURCE_DIR}/tarballs") endif() +if(NOT JAVA_HOME) + # Java home hasn't already been set by one of the platform build system + # validations. + # + # (Have to put an environment variable in real variable to test it.) + set(_TMP_ENV $ENV{JAVA_HOME}) + if(_TMP_ENV) + message(STATUS "Using java from environment: ${_TMP_ENV}") + set(JAVA_HOME ${_TMP_ENV}) + elseif(MYTH_JAVA_HOME) + message(STATUS "Using java from options: ${MYTH_JAVA_HOME}") + set(JAVA_HOME ${MYTH_JAVA_HOME}) + else() + message(STATUS "Using java from system path") + endif() +endif() # # FFmpeg doesn't support compiling out-of-tree after compiling in-tree. Catch diff --git a/cmake/MythOptions.cmake b/cmake/MythOptions.cmake index ebf22af5eed..264c3c432e1 100644 --- a/cmake/MythOptions.cmake +++ b/cmake/MythOptions.cmake @@ -329,22 +329,12 @@ endif() # environment for the necessary commands if there isn't already a JDK_HOME # environment variable. # -if(ANDROID) - foreach(DIR "jbr" "jre") - set(FILENAME "$ENV{HOME}/Android/android-studio/${DIR}") - if(EXISTS ${FILENAME}) - message(STATUS "Defaulting MYTH_JAVA_HOME to ${FILENAME}") - set(MYTH_JAVA_HOME - ${FILENAME} - CACHE PATH "Path to JDK home directory") - break() - endif() - endforeach() -else() - set(MYTH_JAVA_HOME - "" - CACHE PATH "Path to JDK home directory") -endif() +set(MYTH_JAVA_HOME + "" + CACHE + PATH + "Path to JDK home directory. This will be used if the JAVA_HOME environment variable isn't set." +) # # Load any user overrides to these values. diff --git a/cmake/platform/AndroidCrossCustomization.cmake b/cmake/platform/AndroidCrossCustomization.cmake index 1805a061541..519103ff7ec 100644 --- a/cmake/platform/AndroidCrossCustomization.cmake +++ b/cmake/platform/AndroidCrossCustomization.cmake @@ -159,12 +159,12 @@ set(ANDROID_ABI ${CMAKE_ANDROID_ARCH_ABI}) # Set variables for later use when building Qt. # set(QT_PLATFORM_CONFIGURE_ENV - ${PLATFORM_CONFIGURE_ENV} "PATH=${MYTH_JAVA_HOME}/bin:$ENV{PATH}" + ${PLATFORM_CONFIGURE_ENV} "PATH=${JAVA_HOME}/bin:$ENV{PATH}" "PKG_CONFIG_SYSROOT_DIR=${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}") set(QT_PLATFORM_BUILD_ENV ${PLATFORM_BUILD_ENV} - "PATH=${MYTH_JAVA_HOME}/bin:$ENV{PATH}") + "PATH=${JAVA_HOME}/bin:$ENV{PATH}") set(QT_PLATFORM_INSTALL_ENV ${PLATFORM_INSTALL_ENV} - "PATH=${MYTH_JAVA_HOME}/bin:$ENV{PATH}") + "PATH=${JAVA_HOME}/bin:$ENV{PATH}") set(QT5_PLATFORM_ARGS # cmake-format: off diff --git a/cmake/platform/AndroidCrossPackaging.cmake b/cmake/platform/AndroidCrossPackaging.cmake index c0fdaa3ed8a..8e883e69e0a 100644 --- a/cmake/platform/AndroidCrossPackaging.cmake +++ b/cmake/platform/AndroidCrossPackaging.cmake @@ -25,6 +25,7 @@ ExternalProject_Add( -DCMAKE_JOB_POOL_COMPILE:STRING=compile -DCMAKE_JOB_POOL_LINK:STRING=link -DCMAKE_JOB_POOLS:STRING=${CMAKE_JOB_POOLS} + -DJAVA_HOME:PATH=${JAVA_HOME} -DPKG_CONFIG_LIBDIR:PATH=${PKG_CONFIG_LIBDIR} -DPKG_CONFIG_PATH:PATH=${PKG_CONFIG_PATH} USES_TERMINAL_BUILD TRUE diff --git a/cmake/platform/AndroidCrossValidateBuildSystem.cmake b/cmake/platform/AndroidCrossValidateBuildSystem.cmake index dadf994fe6a..7a804536fc0 100644 --- a/cmake/platform/AndroidCrossValidateBuildSystem.cmake +++ b/cmake/platform/AndroidCrossValidateBuildSystem.cmake @@ -4,6 +4,64 @@ # See the file LICENSE_FSF for licensing information. # +# Figure out which java version to use. The priority order is: +# +# ~~~ +# 1) The environment variable JAVA_HOME +# 2) The option variable MYTH_JAVA_HOME +# 3) The android studio installation +# 4) The system version +# ~~~ +# +# (Have to put env variable in real variable to test it.) +set(_TMP_ENV $ENV{JAVA_HOME}) +if(_TMP_ENV) + message(STATUS "Using java from environment: ${_TMP_ENV}") + set(JAVA_HOME ${_TMP_ENV}) +elseif(MYTH_JAVA_HOME) + message(STATUS "Using java from options: ${MYTH_JAVA_HOME}") + set(JAVA_HOME ${MYTH_JAVA_HOME}) +else() + message(STATUS "Searching for java from android studio") + foreach(DIR "jbr" "jre") + set(DIR2 "$ENV{HOME}/Android/android-studio/${DIR}") + if(EXISTS ${DIR2}) + message(STATUS " Found java: ${DIR2}") + set(JAVA_HOME ${DIR2}) + break() + endif() + endforeach() + if(NOT JAVA_HOME) + message(STATUS " Not found") + endif() +endif() +if(NOT JAVA_HOME) + message(STATUS "Using java from system path") +endif() + +# Now validate the java version. +find_package(Java 11 REQUIRED COMPONENTS Development) +if(NOT Java_FOUND) + message(FATAL_ERROR "Can't find installed java") +elseif(QT_VERSION_MAJOR EQUAL 5) + if(Java_VERSION VERSION_GREATER_EQUAL 18) + message( + FATAL_ERROR + "Java version ${Java_VERSION} is too new to compile Qt5. Qt5 requires gradle 7.2 which only officially supports Java 8 through 16, but Java 17 will work. Please set the JAVA_HOME environment variable to a suitable java version." + ) + endif() +elseif(QT_VERSION_MAJOR EQUAL 6) + set(_MAX_JAVA_SUPPORTED 21) + if(Java_VERSION VERSION_GREATER_EQUAL 22) + message( + FATAL_ERROR + "Java version ${Java_VERSION} is too new to compile Qt6. Qt6 requires gradle 8.5 which supports Java 8 through 21. Please set the JAVA_HOME environment variable to a suitable java version." + ) + endif() +else() + message(FATAL_ERROR "Unsupported version of Qt: Qt${QT_VERSION_MAJOR}") +endif() + # Validate the cmake and NDK versions for Android. According to "Professional # CMake: A Practical Guide", the minimum version used to compile android # applications should be CMake 3.21 and Android NDK 23. diff --git a/mythtv/external/libmythbluray/CMakeLists.txt b/mythtv/external/libmythbluray/CMakeLists.txt index 9e7ffb9a348..ae40a1f4895 100644 --- a/mythtv/external/libmythbluray/CMakeLists.txt +++ b/mythtv/external/libmythbluray/CMakeLists.txt @@ -187,10 +187,9 @@ target_include_directories( PUBLIC src PRIVATE src/libbluray src/bdnav ${CMAKE_CURRENT_BINARY_DIR}) -if(MYTH_JAVA_HOME) - target_include_directories( - mythbluray PRIVATE ${MYTH_JAVA_HOME}/include - ${MYTH_JAVA_HOME}/include/${JAVAOS}) +if(JAVA_HOME) + target_include_directories(mythbluray PRIVATE ${JAVA_HOME}/include + ${JAVA_HOME}/include/${JAVAOS}) else() target_sources(mythbluray PRIVATE jni/jni.h jni/${JAVAOS}/jni_md.h) target_include_directories(mythbluray PRIVATE ./jni ./jni/${JAVAOS}) diff --git a/platform/android/CMakeLists.txt b/platform/android/CMakeLists.txt index a39c481b306..81520ef9b1f 100644 --- a/platform/android/CMakeLists.txt +++ b/platform/android/CMakeLists.txt @@ -302,7 +302,7 @@ if(QT_VERSION_MAJOR EQUAL 5) apk2 COMMAND # cmake-format: off - echo ${CMAKE_COMMAND} -E env JAVA_HOME=${MYTH_JAVA_HOME} + echo ${CMAKE_COMMAND} -E env JAVA_HOME=${JAVA_HOME} ${ANDROID_DEPLOY_QT} --input "${PROJECT_BINARY_DIR}/android_deployment_settings.json" --output "${PROJECT_BINARY_DIR}/android-build" @@ -313,7 +313,7 @@ if(QT_VERSION_MAJOR EQUAL 5) # cmake-format: on COMMAND # cmake-format: off - ${CMAKE_COMMAND} -E env JAVA_HOME=${MYTH_JAVA_HOME} + ${CMAKE_COMMAND} -E env JAVA_HOME=${JAVA_HOME} ${ANDROID_DEPLOY_QT} --input "${PROJECT_BINARY_DIR}/android_deployment_settings.json" --output "${PROJECT_BINARY_DIR}/android-build"