为何__android_log_print未定义?Android CMake编译报错排查
Android CMake项目添加android_native_app_glue.c时的链接错误解决
问题现象
编译时出现如下链接错误:
ld: error: undefined symbol: __android_log_print >>> referenced by android_native_app_glue.c:51 (C:/dev/android/sdk/ndk/22.1.7171670/sources/android/native_app_glue\android_native_app_glue.c:51) >>> CMakeFiles/app-glue.dir/C_/dev/android/sdk/ndk/22.1.7171670/sources/android/native_app_glue/android_native_app_glue.c.o:(android_app_read_cmd)
当前使用的CMakeLists.txt内容:
cmake_minimum_required(VERSION 3.22.1) project(MyGame) set (APP_GLUE_DIR ${ANDROID_NDK}/sources/android/native_app_glue) add_library(app-glue SHARED ${APP_GLUE_DIR}/android_native_app_glue.c) target_include_directories(app-glue PUBLIC ${APP_GLUE_DIR}) add_library(native-lib SHARED ./native-lib.cpp) target_include_directories(native-lib PUBLIC ${APP_GLUE_DIR}) add_library(libMyGame SHARED IMPORTED ) find_library(log-lib log) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate") target_link_libraries(native-lib app-glue android ${log-lib} libMyGame)
注:native-lib中同样使用__android_log_print但未出现类似错误。
错误原因
android_native_app_glue.c中调用了__android_log_print,该符号属于Android NDK的log库- 你将
app-glue编译为共享库(SHARED),编译这个共享库时没有链接log库和android库,导致链接器无法找到该符号 native-lib没有报错是因为它本身链接了log库,自身调用的__android_log_print符号能被正常解析,但app-glue作为独立共享库,编译阶段就需要解决自身的符号依赖
修复方法
方法一:为共享库app-glue添加依赖链接
修改CMakeLists.txt,为app-glue库添加log和android库的链接依赖:
cmake_minimum_required(VERSION 3.22.1) project(MyGame) set (APP_GLUE_DIR ${ANDROID_NDK}/sources/android/native_app_glue) find_library(log-lib log) add_library(app-glue SHARED ${APP_GLUE_DIR}/android_native_app_glue.c) target_include_directories(app-glue PUBLIC ${APP_GLUE_DIR}) # 为app-glue添加依赖库链接 target_link_libraries(app-glue android ${log-lib}) add_library(native-lib SHARED ./native-lib.cpp) target_include_directories(native-lib PUBLIC ${APP_GLUE_DIR}) add_library(libMyGame SHARED IMPORTED ) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate") target_link_libraries(native-lib app-glue libMyGame)
方法二:将app-glue编译为静态库
如果不需要将app-glue作为独立共享库,可将其改为静态库(STATIC),这样在链接native-lib时会把app-glue的代码合并进去,只需保证native-lib已链接log和android库即可:
# 将app-glue改为静态库 add_library(app-glue STATIC ${APP_GLUE_DIR}/android_native_app_glue.c) target_include_directories(app-glue PUBLIC ${APP_GLUE_DIR})
这种方式下,原有的target_link_libraries(native-lib app-glue android ${log-lib} libMyGame)无需修改,即可解决符号未定义问题。
内容的提问来源于stack exchange,提问作者Bungles
相关产品推荐
相关产品推荐

