我创建了一个支持 C++ 的新 Android Studio 项目,但没有向其中添加任何内容。该项目使用 CMake 构建、编译和运行。然后,我将以下两行代码添加到文件底部的
CMakeLists.txt
,然后出现 CMake 构建错误。
find_package(Java COMPONENTS Development) # Line 47
find_package(JNI REQUIRED) # Line 48
这是我在构建项目时遇到的错误
-- Found Java: /usr/lib/jvm/java-10-oracle/bin/java (found version "10.0.1") found components: Development
-- Configuring incomplete, errors occurred!
CMake Error at /home/xxxxx/Android/Sdk/cmake/3.6.4111459/share/cmake-3.6/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY
See also "/home/xxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/release/x86_64/CMakeFiles/CMakeOutput.log".
JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)
Call Stack (most recent call first):
/home/xxxxxx/Android/Sdk/cmake/3.6.4111459/share/cmake-3.6/Modules/FindPackageHandleStandardArgs.cmake:388 (_FPHSA_FAILURE_MESSAGE)
/home/xxxxxx/Android/Sdk/cmake/3.6.4111459/share/cmake-3.6/Modules/FindJNI.cmake:314 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
CMakeLists.txt:48 (find_package)
External native generate JSON release: JSON generation completed with problems
CMake 在从命令行调用时运行,但由于某种原因在 Android Studio 中失败,我不确定为什么。
编辑1
这是 CMakeOutput.log 文件
编辑2
这就是
CMakeLists.txt
文件中的全部内容。它使用命令 cmake 在 cmd 中编译。
cmake_minimum_required(VERSION 3.4.1)
find_package(Java COMPONENTS Development)
find_package(JNI REQUIRED)
这是cmd输出
E:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\build>cmake ..
-- Configuring done
-- Generating done
-- Build files have been written to: E:/Users/xxxxx/AndroidStudioProjects/MyApplication/app/build
当我尝试添加它并使用 gradle 在 Android Studio 中编译它时,我在 Windows 10 专业版 64 位上收到以下错误
Microsoft Windows [Version 10.0.17134.112]
(c) 2018 Microsoft Corporation. All rights reserved.
E:\Users\xxxxx\AndroidStudioProjects\MyApplication>gradlew build --stacktrace
> Task :app:generateJsonModelDebug
External native generate JSON debug: starting JSON generation
External native generate JSON debug: using platform version 24 for ABI ARMEABI_V7A and min SDK version 24
External native generate JSON debug: noticing that build file 'E:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\CMakeLists.txt' is out of date with respect to E:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\.extern
alNativeBuild\cmake\debug\armeabi-v7a\android_gradle_build.json
External native generate JSON debug: rebuilding JSON E:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\.externalNativeBuild\cmake\debug\armeabi-v7a\android_gradle_build.json due to:
External native generate JSON debug: - a dependent build file changed
External native generate JSON debug: keeping json folder 'E:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\.externalNativeBuild\cmake\debug\armeabi-v7a' but regenerating project
External native generate JSON debug: executing cmake Executable : E:\Android\SDK\cmake\3.6.4111459\bin\cmake.exe
arguments :
-HE:\Users\xxxxx\AndroidStudioProjects\MyApplication\app
-BE:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\.externalNativeBuild\cmake\debug\armeabi-v7a
-DANDROID_ABI=armeabi-v7a
-DANDROID_PLATFORM=android-24
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=E:\Users\xxxxx\AndroidStudioProjects\MyApplication\app\build\intermediates\cmake\debug\obj\armeabi-v7a
-DCMAKE_BUILD_TYPE=Debug
-DANDROID_NDK=E:\Android\SDK\ndk-bundle
-DCMAKE_CXX_FLAGS=
-DCMAKE_TOOLCHAIN_FILE=E:\Android\SDK\ndk-bundle\build\cmake\android.toolchain.cmake
-DCMAKE_MAKE_PROGRAM=E:\Android\SDK\cmake\3.6.4111459\bin\ninja.exe
-GAndroid Gradle - Ninja
jvmArgs :
CMake Error at E:/Android/SDK/cmake/3.6.4111459/share/cmake-3.6/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY
JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH)
Call Stack (most recent call first):
E:/Android/SDK/cmake/3.6.4111459/share/cmake-3.6/Modules/FindPackageHandleStandardArgs.cmake:388 (_FPHSA_FAILURE_MESSAGE)
E:/Android/SDK/cmake/3.6.4111459/share/cmake-3.6/Modules/FindJNI.cmake:314 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
CMakeLists.txt:4 (find_package)
-- Configuring incomplete, errors occurred!
See also "E:/Users/xxxxx/AndroidStudioProjects/MyApplication/app/.externalNativeBuild/cmake/debug/armeabi-v7a/CMakeFiles/CMakeOutput.log".
Could NOT find JNI (missing: JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY
解决了
sudo apt-get install -y openjdk-8-jdk
sudo apt-get install -y default-jdk
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
正如与 Android 捆绑在一起的 CMake 版本试图告诉您的那样,它找不到 JNI 包,因为缺少某些部分:
缺少:JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH
检查 FindJNI 的文档 (https://cmake.org/cmake/help/latest/module/FindJNI.html) 这些变量被设置为 Android 版本的 JNI 未附带的库和标头的位置(以例如,Android 不包含 AWT 库,这并不奇怪)。 运行
find_package(JNI REQUIRED)
时,FindJNI 代码会检查这些变量是否已设置,如果没有,则发出错误。
解决方法是在调用
find_package
: 之前自行设置这些变量
# We are only interested in finding jni.h: we do not care about extended JVM
# functionality or the AWT library.
set(JAVA_AWT_LIBRARY NotNeeded)
set(JAVA_JVM_LIBRARY NotNeeded)
set(JAVA_INCLUDE_PATH2 NotNeeded)
set(JAVA_AWT_INCLUDE_PATH NotNeeded)
find_package(JNI REQUIRED)
但请注意,您的代码只能使用 jni.h 及其功能:如果它尝试访问 JNI 包的任何其他部分,它将失败(可能在编译时),因为本质上,您已经欺骗了CMake 认为已找到整个包,而实际上 Android 设置中只存在其中的一部分。
我找到了适合我的解决方案:
cmake_minimum_required(VERSION 3.10)
project("ktaglib")
set(JAVA_AWT_LIBRARY "$ENV{JAVA_HOME}/lib/libjawt.so")
set(JAVA_JVM_LIBRARY "$ENV{JAVA_HOME}/lib/server/libjvm.so")
set(JAVA_INCLUDE_PATH "$ENV{JAVA_HOME}/include")
set(JAVA_INCLUDE_PATH2 "$ENV{JAVA_HOME}/include/linux")
set(JAVA_AWT_INCLUDE_PATH "$ENV{JAVA_HOME}/include")
find_package(JNI REQUIRED)
您必须事先设置环境变量
JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64"
。
与 alpine:edge docker 镜像相同,使用以下方法修复:
ENV JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk
RUN apk add --no-cache openjdk8
参考:https://pkgs.alpinelinux.org/contents?branch=edge&name=openjdk8&arch=x86_64&repo=community
CMake 中的
FindJNI
模块确定是否安装了 Java 以及包含文件和库的位置。
某些功能(例如 AWT)并不包含在与 Android 捆绑的 Jvm 中。
解决方案是删除 REQUIRED
参数并检查变量是否已设置。
find_package(JNI)
if (NOT JAVA_INCLUDE_PATH)
message(FATAL_ERROR "Failed to find Java include path.")
endif()
从 CMake 开始
3.24
这不再是问题。最新的 CMake 版本会检测平台是否为 Android,并将不在 Android 中的组件标记为不需要。为了让您可以像往常一样使用 find_library(JNI REQUIRED)
,请考虑将 CMake 版本更新到最新以避免此问题。
/usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:230 处出现 CMake 错误(消息): 找不到 JNI(缺少:JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH) 调用堆栈(首先是最近的调用): /usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE) /usr/share/cmake-3.22/Modules/FindJNI.cmake:382 (FIND_PACKAGE_HANDLE_STANDARD_ARGS) CMakeLists.txt:19 (find_package)
如果您尝试在 virtualenv 中检查是否安装了 cmake,请更新 cmake。 安装cmake版本cmake-3.26.4-h96355d8_0 conda安装cmake