我正在使用 Android ndk 制作一个在 Oculus Quest 上运行的 OpenXR 应用程序。我正在尝试包含其他库,并且我能够使用此 cmake 让应用程序正常运行
cmake_minimum_required(VERSION 3.6)
project(Template)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Assimp
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries" FORCE)
set(ASSIMP_BUILD_TESTS OFF CACHE BOOL "If the test suite for Assimp is built in addition to the library." FORCE)
set(ASSIMP_INSTALL OFF CACHE BOOL "Disable this if you want to use assimp as a submodule." FORCE)
# OpenAL
set(LIBTYPE STATIC CACHE STRING "Build OpenAL as a static library" FORCE)
set(ALSOFT_TESTS OFF CACHE BOOL "Build test programs")
set(ALSOFT_EXAMPLES OFF CACHE BOOL "Build example program")
# OpenXR
set(BUILD_TESTS OFF CACHE INTERNAL "Build tests")
set(BUILD_API_LAYERS ON CACHE INTERNAL "Use OpenXR layers")
# third party submodules
add_subdirectory(${CMAKE_SOURCE_DIR}/ThirdParty/OpenXR-SDK-Source openxr_build)
add_subdirectory(${CMAKE_SOURCE_DIR}/ThirdParty/openal-soft openal_build)
add_subdirectory(${CMAKE_SOURCE_DIR}/ThirdParty/assimp assimp_build)
# Collect all .cpp files in the cpp directory
file(GLOB_RECURSE SRC_FILES ${CMAKE_SOURCE_DIR}/main/cpp/*.cpp)
add_library(${PROJECT_NAME} SHARED
${SRC_FILES}
)
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate"
)
target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_SOURCE_DIR}/main/cpp
)
# export ANativeActivity_onCreate for java to call.
set_property(
TARGET ${PROJECT_NAME}
APPEND_STRING
PROPERTY LINK_FLAGS " -u ANativeActivity_onCreate"
)
# native_app_glue
include(AndroidNdkModules)
android_ndk_import_module_native_app_glue()
# Link libraries to your native library
target_link_libraries(${PROJECT_NAME} PRIVATE
android
EGL
GLESv3
log
native_app_glue
jnigraphics
openxr_loader
OpenAL
assimp
)
我在运行时在 cat 日志中看到了这一点:
ziparchive com.example.Template W Unable to open '/apex/com.meta.xr/priv-app/VrDriver/VrDriver.apk': No such file or directory
vulkan com.example.Template E failed to open apk '/apex/com.meta.xr/priv-app/VrDriver/VrDriver.apk': -11
vulkan com.example.Template D searching for layers in '/system/priv-app/VrDriver/VrDriver.apk!/lib/arm64-v8a'
DriverLoader com.example.Template I Calling into SetLegacyVrApiEntryPointOverride
VrApi_DriverLoader com.example.Template I SetLegacyVrApiEntryPointOverride: calling sprintf
VrApi_DriverLoader com.example.Template I SetLegacyVrApiEntryPointOverride: env buffer is '0x7634a60478'
VrApi_DriverLoader com.example.Template I SetLegacyVrApiEntryPointOverride: calling setenv
DriverLoader com.example.Template I Creating Temp JNIEnv
DriverLoader com.example.Template I Calling FindClass
DriverLoader com.example.Template I Calling RegisterNativeVrApiLoaderMethods
VrApi_DriverLoader com.example.Template I RegisterNativeVrApiLoaderMethods: calling RegisterNatives
DriverLoader com.example.Template I Calling RegisterNativeXrLoaderMethods
OpenXR_DriverLoader com.example.Template I RegisterNativeVrApiLoaderMethods: calling RegisterNatives
DriverLoader com.example.Template I Exiting JNI_OnLoad
OpenXR_ClientState com.example.Template I OpenXRClientState::create - from xrInitializeLoaderKHR
XrRuntimeS...lientState com.example.Template I SharedClientState::create called from 'OpenXRClientState::init'
它似乎无法访问
/apex/com.meta.xr/priv-app/VrDriver/VrDriver.apk
,但它可以从/system/priv-app/VrDriver/VrDriver.apk!/lib/arm64-v8a
打开它
但是,如果我从 cmake(以及 cpp 代码中的所有引用)中删除 OpenAL,删除 .cxx 和构建文件夹以强制进行干净构建,项目会构建,但会崩溃并在日志中显示这一点。
---------------------------- PROCESS STARTED (30599) for package com.example.Template ----------------------------
com.example.Template W Entry not found
com.example.Template W Entry not found
com.example.Template W Warning: unable to resolve "/apex/com.meta.xr/priv-app/VrDriver/VrDriver.apk": No such file or directory (ignoring)
com.example.Template W JIT profile information will not be recorded: profile file does not exist.
com.example.Template W JIT profile information will not be recorded: profile file does not exist.
com.example.Template V ANGLE Developer option for 'com.example.Template' set to: 'default'
com.example.Template V ANGLE GameManagerService for com.example.Template: false
com.example.Template V Neither updatable production driver nor prerelease driver is supported.
com.example.Template D Compat change id reported: 175409949; UID 10152; state: DISABLED
com.example.Template D Compat change id reported: 175409951; UID 10152; state: ENABLED
com.example.Template D Compat change id reported: 175409956; UID 10152; state: DISABLED
com.example.Template D Compat change id reported: 175409950; UID 10152; state: DISABLED
com.example.Template D No Network Security Config specified, using platform default
com.example.Template D Compat change id reported: 175409952; UID 10152; state: DISABLED
com.example.Template D No Network Security Config specified, using platform default
---------------------------- PROCESS ENDED (30599) for package com.example.Template ----------------------------
com.example.Template E Unable to open zip file: /apex/com.meta.xr/priv-app/VrDriver/VrDriver.apk
com.example.Template E java.io.FileNotFoundException: /apex/com.meta.xr/priv-app/VrDriver/VrDriver.apk (No such file or directory)
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.<init>(ZipFile.java:265)
at java.util.zip.ZipFile.<init>(ZipFile.java:187)
at java.util.jar.JarFile.<init>(JarFile.java:169)
at java.util.jar.JarFile.<init>(JarFile.java:106)
at libcore.io.ClassPathURLStreamHandler.<init>(ClassPathURLStreamHandler.java:46)
at dalvik.system.DexPathList$NativeLibraryElement.maybeInit(DexPathList.java:858)
at dalvik.system.DexPathList$NativeLibraryElement.findNativeLibrary(DexPathList.java:879)
at dalvik.system.DexPathList.findLibrary(DexPathList.java:594)
at dalvik.system.BaseDexClassLoader.findLibrary(BaseDexClassLoader.java:301)
at android.app.NativeActivity.onCreate(NativeActivity.java:160)
at android.app.Activity.performCreate(Activity.java:8068)
at android.app.Activity.performCreate(Activity.java:8048)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1341)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3705)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3881)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2270)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:214)
at android.os.Looper.loop(Looper.java:304)
at android.app.ActivityThread.main(ActivityThread.java:7918)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1010)
com.example.Template D Shutting down VM
它似乎找不到
/apex/com.meta.xr/priv-app/VrDriver/VrDriver.apk
,甚至没有像包含 OpenAL 时那样尝试在 /system/priv-app/VrDriver/VrDriver.apk!/lib/arm64-v8a
中查找它。我不明白为什么不包括 OpenAL 会导致这个问题。似乎如果我包含 assimp,我需要包含 OpenAL,否则会出现错误。如果我排除 Assimp 和 OpenAL,应用程序运行正常。
我有一些临时解决方法,例如使用 OpenAL 构建,然后从 cmake 中删除它并再次构建,而不删除 .cxx 和构建文件夹,但我想解决这个问题。
如果您能提供有关如何调试此问题或可以对项目进行哪些更改来解决此问题的建议,我将不胜感激。如果可以帮助解决此问题,我可以包含 AndroidManifest 和 gradle 文件。
事实证明问题是 cmake 中的排序,将
add_subdirectory
移至 android_ndk_import_module_native_app_glue
解决了我的问题之后,即使在进行完全干净的构建之后,这个没有 OpenAL 的 cmake 也可以正常运行
cmake_minimum_required(VERSION 3.6)
project(Template)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Assimp
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries" FORCE)
set(ASSIMP_BUILD_TESTS OFF CACHE BOOL "If the test suite for Assimp is built in addition to the library." FORCE)
set(ASSIMP_INSTALL OFF CACHE BOOL "Disable this if you want to use assimp as a submodule." FORCE)
# OpenAL
set(LIBTYPE STATIC CACHE STRING "Build OpenAL as a static library" FORCE)
set(ALSOFT_TESTS OFF CACHE BOOL "Build test programs")
set(ALSOFT_EXAMPLES OFF CACHE BOOL "Build example program")
# OpenXR
set(BUILD_TESTS OFF CACHE INTERNAL "Build tests")
set(BUILD_API_LAYERS ON CACHE INTERNAL "Use OpenXR layers")
# Collect all .cpp files in the cpp directory
file(GLOB_RECURSE SRC_FILES ${CMAKE_SOURCE_DIR}/main/cpp/*.cpp)
add_library(${PROJECT_NAME} SHARED
${SRC_FILES}
)
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate"
)
target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_SOURCE_DIR}/main/cpp
)
# export ANativeActivity_onCreate for java to call.
set_property(
TARGET ${PROJECT_NAME}
APPEND_STRING
PROPERTY LINK_FLAGS " -u ANativeActivity_onCreate"
)
# native_app_glue
include(AndroidNdkModules)
android_ndk_import_module_native_app_glue()
# third party submodules
add_subdirectory(${CMAKE_SOURCE_DIR}/ThirdParty/OpenXR-SDK-Source openxr_build)
#add_subdirectory(${CMAKE_SOURCE_DIR}/ThirdParty/openal-soft openal_build)
add_subdirectory(${CMAKE_SOURCE_DIR}/ThirdParty/assimp assimp_build)
# Link libraries to your native library
target_link_libraries(${PROJECT_NAME} PRIVATE
android
EGL
GLESv3
log
native_app_glue
jnigraphics
openxr_loader
#OpenAL
assimp
)