OpenCV4Android:non-system libraries in linker flags: -lopencv_java错误的解决

最近搞之前的一份老代码,发现OpenCV到2.4.11之后,之前的mk文件不适用了,报一堆一堆的错误。

一是如前文所述,LOCAL_LDLIBS    += -lm -llog这一句+=绝不能错误的写成:=.另外,还会报这样一个错误:

Android NDK: WARNING: APP_PLATFORM android-17 is larger than android:minSdkVersion 16 in ./AndroidManifest.xml
Android NDK: WARNING:jni/Android.mk:ProcessImg: non-system libraries in linker flags: -lopencv_java
Android NDK:     This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK:     or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK:     current module
[armeabi-v7a] Compile++ thumb: ProcessImg <= DetectFace_JNI.cpp
jni/DetectFace_JNI.cpp: In function '_jstring* Java_org_yan_processlib_LibProcessImg_processIplImg(JNIEnv*, jobject, jintArray, int, int)':
jni/DetectFace_JNI.cpp:97:44: warning: converting 'false' to pointer type for argument 2 of 'jint* _JNIEnv::GetIntArrayElements(jintArray, jboolean*)' [-Wconversion-null]
  cbuf = env->GetIntArrayElements(buf, false);
                                            ^
jni/DetectFace_JNI.cpp: In function '_jstring* Java_org_yan_processlib_LibProcessImg_processStaticImg(JNIEnv*, jobject, jintArray, int, int)':
jni/DetectFace_JNI.cpp:131:44: warning: converting 'false' to pointer type for argument 2 of 'jint* _JNIEnv::GetIntArrayElements(jintArray, jboolean*)' [-Wconversion-null]
  cbuf = env->GetIntArrayElements(buf, false);
                                            ^
[armeabi-v7a] Compile++ thumb: ProcessImg <= copyToAssets.cpp
[armeabi-v7a] Compile++ thumb: ProcessImg <= detectFace.cpp
[armeabi-v7a] SharedLibrary  : libProcessImg.so
/Users/yanzi/work/android-ndk-r10d/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: warning: hidden symbol '__aeabi_atexit' in /Users/yanzi/work/android-ndk-r10d/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/thumb/libgnustl_static.a(atexit_arm.o) is referenced by DSO /Users/yanzi/work/OpenCV-android-sdk/sdk/native/jni/../libs/armeabi-v7a/libopencv_java.so
[armeabi-v7a] Install        : libProcessImg.so => libs/armeabi-v7a/libProcessImg.so

尽管so文件生成了,也安装了,但是报一个non-system libraries in linker flags: -lopencv_java的错误,编译出来的so文件只有330KB左右,理论上这个so应该4.5M左右。运行知道发现找不到libopencv.so. 这是产生这个错误的mk文件:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

ifeq ("$(wildcard $(OPENCV_MK_PATH))","") 
#try to load OpenCV.mk from default install location 
#include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk 
include /Users/yanzi/work/OpenCV-android-sdk/sdk/native/jni/OpenCV.mk
else 
include $(OPENCV_MK_PATH)
endif
LOCAL_LDLIBS    += -lm -llog 
LOCAL_MODULE    := ProcessImg 
LOCAL_SRC_FILES := DetectFace_JNI.cpp \
					src/copyToAssets.cpp \
					src/detectFace.cpp
					
					
include $(BUILD_SHARED_LIBRARY) 

正确的mk文件应该如下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

OpenCV_INSTALL_MODULES:=on
OPENCV_CAMERA_MODULES:=off
OPENCV_LIB_TYPE:=STATIC

ifeq ("$(wildcard $(OPENCV_MK_PATH))","") 
#try to load OpenCV.mk from default install location 
#include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk 
include /Users/yanzi/work/OpenCV-android-sdk/sdk/native/jni/OpenCV.mk
else 
include $(OPENCV_MK_PATH)
endif

LOCAL_MODULE    := ProcessImg 
LOCAL_SRC_FILES := DetectFace_JNI.cpp \
					src/copyToAssets.cpp \
					src/detectFace.cpp
					
LOCAL_LDLIBS    += -lm -llog				
include $(BUILD_SHARED_LIBRARY) 

问题就出在:

OpenCV_INSTALL_MODULES:=on
OPENCV_CAMERA_MODULES:=off
OPENCV_LIB_TYPE:=STATIC

这三句话,尤其是OPENCV_LIB_TYPE:=STATIC是要害,没这一句编译出来的so还是要依赖libopencv_java.so的。而且这句话必须放在include OpenCV.mk文件之前。切记切记!


欢迎加入OpenCV4Android 3群:272250397 备注:yanzi

BUG -- Linker flags (Release): -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined -- Linker flags (Debug): -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined -- ccache: NO -- Precompiled headers: NO -- Extra dependencies: dl m pthread rt -- 3rdparty dependencies: -- -- OpenCV modules: -- To be built: calib3d core dnn features2d flann gapi highgui imgcodecs imgproc ml objdetect photo stitching ts video videoio -- Disabled: world -- Disabled by dependency: - -- Unavailable: java python2 python3 -- Applications: tests perf_tests apps -- Documentation: NO -- Non-free algorithms: NO -- -- GUI: GTK3 -- GTK+: YES (ver 3.24.20) -- GThread : YES (ver 2.64.6) -- GtkGlExt: NO -- VTK support: NO -- -- Media I/O: -- ZLib: /usr/lib/x86_64-linux-gnu/libz.so (ver 1.2.11) -- JPEG: /usr/lib/x86_64-linux-gnu/libjpeg.so (ver 80) -- WEBP: build (ver encoder: 0x020f) -- PNG: /usr/lib/x86_64-linux-gnu/libpng.so (ver 1.6.37) -- TIFF: /usr/lib/x86_64-linux-gnu/libtiff.so (ver / ) -- JPEG 2000: OpenJPEG (ver 2.4.0) -- OpenEXR: /usr/lib/x86_64-linux-gnu/libImath.so /usr/lib/x86_64-linux-gnu/libIlmImf.so /usr/lib/x86_64-linux-gnu/libIex.so /usr/lib/x86_64-linux-gnu/libHalf.so /usr/lib/x86_64-linux-gnu/libIlmThread.so (ver 2_3) -- HDR: YES -- SUNRASTER: YES -- PXM: YES -- PFM: YES -- -- Video I/O: -- DC1394: YES (2.2.5) -- FFMPEG: YES -- avcodec: YES (58.54.100) -- avformat: YES (58.29.100) -- avutil: YES (56.31.100) -- swscale: YES (5.5.100) -- avresample: NO -- GStreamer: YES (1.16.3) -- v4l/v4l2: YES (linux/videodev2.h) -- -- Parallel framework: pthreads -- -- Trace: YES (with Intel ITT) -- -- Other third-party libraries: -- VA: NO -- Lapack: NO -- Eigen: YES (ver 3.3.7) -- Custom HAL: NO -- Protobuf: build (3.19.1) -- -- OpenCL: YES (no extra features) -- Include path: /home/hyzk/Downloads/opencv-4.7.0/3rdparty/include/opencl/1.2 -- Link libraries: Dynamic load -- -- Python (for build): /usr/bin/python3 -- -- Java: -- ant: NO -- JNI: NO -- Java wrappers: NO -- Java tests: NO -- -- Install to: /usr/local
最新发布
07-20
C/C++: ld: error: found local symbol '_edata' in global part of symbol table in file D:/AndroidProject/Application_721_rknn/app_rknn_face_demp/src/main/jniLibs/arm64-v8a\librknn_sunchip.so 我编译出来的库为什么会出现这种情况,我的编译指令是: cmake_minimum_required(VERSION 3.4.1) project(RKFace VERSION 1.0.0) # 设置 C++ 标准 set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 基本编译选项 set(CMAKE_C_FLAGS "-Wall -fPIC -O2") set(CMAKE_CXX_FLAGS "-Wall -fPIC -O2") # Android 平台配置 if(CMAKE_SYSTEM_NAME STREQUAL "Android") add_definitions(-DANDROID) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") endif() # 包含目录 include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/include ) # 源文件 set(main_source src/main.cc) # 库文件路径 set(LIBPATH ${CMAKE_CURRENT_SOURCE_DIR}/libs/android) # 链接库 set(LINKS ${LIBPATH}/libRKFace.so ${LIBPATH}/libnva.so ${LIBPATH}/librknnrt.so ) # Android 特定库 if(CMAKE_SYSTEM_NAME STREQUAL "Android") list(APPEND LINKS log c++_shared) endif() # 标准库 list(APPEND LINKS c m dl) # 生成可执行文件 add_executable(rkface.demo ${main_source}) # 链接库 target_link_libraries(rkface.demo ${LINKS}) # 设置安装目录为当前目录下的 install set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/install) #生成库 add_library(rknn_sunchip SHARED src/rknn_sunchip.cc) target_include_directories(rknn_sunchip PRIVATE include) target_link_libraries(rknn_sunchip ${LINKS}) # 安装到ABI分层目录 install(TARGETS rknn_sunchip LIBRARY DESTINATION ${LIBPATH}/install/libs/${ANDROID_ABI} ) # 安装可执行文件到 install/bin install(TARGETS rkface.demo RUNTIME DESTINATION bin) # 安装库文件到 install/lib install(FILES ${LIBPATH}/libRKFace.so ${LIBPATH}/libnva.so ${LIBPATH}/librknnrt.so DESTINATION lib ) # 安装头文件到 install/include (如果需要) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp" ),编译脚本是:#!/bin/bash # 编译NVA库为Android .so文件的脚本(优化版本) # 使用方法: ./build_android_optimized.sh [目标ABI] # 检查参数 if [ $# -lt 1 ]; then echo "用法: $0 <目标ABI>" echo "例如: $0 arm64-v8a" echo "支持的ABI: armeabi-v7a, arm64-v8a" exit 1 fi # 参数设置 NDK_PATH=/home/share/work/YML/android-ndk-r19c SRC_PATH=./ TARGET_ABI=$1 BUILD_DIR="${SRC_PATH}/build_android_${TARGET_ABI}" API_LEVEL=24 # 可根据需要调整API级别 PROJECT_ROOT=$(pwd) THIRD_PARTY_PATH="${PROJECT_ROOT}/../000_3rdParty" # OPENCV_PATH="${THIRD_PARTY_PATH}/libopencv/opencv-android-sdk-build" OPENCV_PATH="${THIRD_PARTY_PATH}/libopencv/opencv_android_4.6.0/" # 检查NDK路径是否存在 if [ ! -d "$NDK_PATH" ]; then echo "错误: NDK路径不存在: $NDK_PATH" exit 1 fi # 检查目标ABI是否有效 case $TARGET_ABI in armeabi-v7a) ABI="armeabi-v7a" ARCH_FLAGS="-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard" ;; arm64-v8a) ABI="arm64-v8a" ARCH_FLAGS="-march=armv8-a" ;; *) echo "错误: 不支持的ABI: $TARGET_ABI" echo "支持的ABI: armeabi-v7a, arm64-v8a" exit 1 ;; esac # 设置优化标志 - 与Linux版本一致 # 设置更保守的优化标志,避免过度优化导致的问题 OPT_FLAGS="-O2 -fno-strict-aliasing -fwrapv -fno-omit-frame-pointer" SECURITY_FLAGS="-fstack-protector-strong -D_FORTIFY_SOURCE=2" VISIBILITY_FLAGS="-fvisibility=hidden -fvisibility-inlines-hidden" # 移除可能导致问题的标志 # EXTRA_FLAGS="-fno-common" # 这个可能在Android上有问题 EXTRA_FLAGS="-fno-common -Wno-unused-command-line-argument" # Android特定的标志 ANDROID_FLAGS="-fPIC -fdata-sections -ffunction-sections" # 链接器标志 - 更保守的设置 LINKER_FLAGS="-Wl,--gc-sections,--as-needed,--no-undefined" # 组合所有标志 ALL_FLAGS="$ARCH_FLAGS $OPT_FLAGS $SECURITY_FLAGS $VISIBILITY_FLAGS $EXTRA_FLAGS $ANDROID_FLAGS" echo "====== 配置信息 ======" echo "NDK路径: $NDK_PATH" echo "源码路径: $SRC_PATH" echo "目标ABI: $TARGET_ABI" echo "构建目录: $BUILD_DIR" echo "API级别: $API_LEVEL" echo "第三方库路径: $THIRD_PARTY_PATH" echo "OpenCV库路径: $OPENCV_PATH" echo "编译优化标志: $ALL_FLAGS" echo "链接器标志: $LINKER_FLAGS" echo "======================" # 创建构建目录 mkdir -p $BUILD_DIR cd $BUILD_DIR # 设置CMake工具链文件路径 TOOLCHAIN_FILE="${NDK_PATH}/build/cmake/android.toolchain.cmake" if [ ! -f "$TOOLCHAIN_FILE" ]; then echo "错误: 无法找到Android CMake工具链文件: $TOOLCHAIN_FILE" exit 1 fi # API级别检查函数 check_api_compatibility() { case $TARGET_ABI in armeabi-v7a) MIN_API=24 ;; arm64-v8a) MIN_API=24 ;; esac if [ $API_LEVEL -lt $MIN_API ]; then echo "错误: OpenCV要求${TARGET_ABI}的最低API级别为${MIN_API}" exit 1 fi } # 在参数检查之后调用 check_api_compatibility # 设置OpenCV配置路径 OPENCV_CONFIG_LOCATIONS=( "${OPENCV_PATH}/sdk/native/jni/abi-${TARGET_ABI}" "${OPENCV_PATH}/sdk/native/jni" "${OPENCV_PATH}/sdk/native" "${OPENCV_PATH}/share/OpenCV" "${OPENCV_PATH}/lib/cmake/opencv4" ) OPENCV_CONFIG_PATH="" for location in "${OPENCV_CONFIG_LOCATIONS[@]}"; do if [ -f "${location}/OpenCVConfig.cmake" ]; then OPENCV_CONFIG_PATH="${location}" echo "找到OpenCV配置文件: ${location}/OpenCVConfig.cmake" break fi done if [ -z "$OPENCV_CONFIG_PATH" ]; then echo "警告: 无法找到OpenCVConfig.cmake文件, 请检查OpenCV路径" echo "将尝试继续配置,但可能会失败..." OPENCV_CONFIG_PATH="${OPENCV_PATH}" fi echo "使用OpenCV配置路径: $OPENCV_CONFIG_PATH" echo "使用CMake工具链文件: $TOOLCHAIN_FILE" # 运行CMake配置 echo "正在配置CMake..." export OpenCV_DIR=$OPENCV_CONFIG_PATH cmake -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN_FILE \ -DANDROID_ABI=$ABI \ -DANDROID_PLATFORM=android-$API_LEVEL \ -DANDROID_STL=c++_shared \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_FLAGS="$ALL_FLAGS" \ -DCMAKE_CXX_FLAGS="$ALL_FLAGS" \ -DCMAKE_SHARED_LINKER_FLAGS="$LINKER_FLAGS" \ -DCMAKE_EXE_LINKER_FLAGS="$LINKER_FLAGS" \ -DOpenCV_DIR=$OPENCV_CONFIG_PATH \ -DBUILD_SHARED_LIBS=ON \ -DENABLE_LTO=OFF \ -DCMAKE_VERBOSE_MAKEFILE=ON \ -DANDROID_NATIVE_API_LEVEL=$API_LEVEL \ .. # 检查CMake配置是否成功 if [ $? -ne 0 ]; then echo "错误: CMake配置失败" # 提供调试信息 echo "" echo "======= 调试信息 =======" echo "请检查以下几点:" echo "1. OpenCV安装是否完整,确认OpenCV Android SDK路径是否正确" echo "2. 在CMakeLists.txt中,确认OpenCV_DIR路径设置正确" echo "3. 尝试手动查找OpenCVConfig.cmake位置:" echo " find $OPENCV_PATH -name OpenCVConfig.cmake -o -name opencv-config.cmake" echo "4. 确认opencv库对应的ABI版本是否存在:" if [ -d "${OPENCV_PATH}/sdk/native/libs/${ABI}" ]; then echo " ABI库文件存在: ${OPENCV_PATH}/sdk/native/libs/${ABI}" ls -la "${OPENCV_PATH}/sdk/native/libs/${ABI}" else echo " 警告: 没有找到对应ABI的OpenCV: ${OPENCV_PATH}/sdk/native/libs/${ABI}" fi echo "========================" exit 1 fi # 编译 echo "正在编译..." cmake --build . --config Release -- -j$(nproc) # 检查编译是否成功 if [ $? -ne 0 ]; then echo "错误: 编译失败" exit 1 fi # 创建输出目录 INSTALL_DIR="${BUILD_DIR}/../../install" mkdir -p $INSTALL_DIR/lib/$ABI # 复制生成的库文件 echo "正在安装..." cmake --install . --prefix "$INSTALL_DIR" # 使用strip进一步精简库文件 echo "正在精简库文件..." find $INSTALL_DIR -name "*.so" -exec ${NDK_PATH}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip --strip-all {} \; echo "编译完成!" echo "库文件位置: $INSTALL_DIR/lib/" ls -la $INSTALL_DIR/lib/ echo "头文件位置: $INSTALL_DIR/include/" ls -la $INSTALL_DIR/include/ echo "生成的库文件列表:" find $INSTALL_DIR -name "*.so" -o -name "*.a" # 显示库文件大小 echo "" echo "库文件大小信息:" find $INSTALL_DIR -name "*.so" -exec du -h {} \;
06-08
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值