一、先看chatgpt 的回答。
如果您希望把没有直接使用的静态链接库打包进动态链接库,那么您需要确保这些静态链接库中的符号在最终的动态库中被保留。
通常情况下,如果您没有在您的代码中直接引用静态库的符号,编译器可能会在优化过程中丢弃这些符号。为了避免这种情况,您可以使用 -Wl,--whole-archive
和 -Wl,--no-whole-archive
这两个链接器标志包围您的静态库,这会告诉链接器把静态库中的所有符号都包括进来,即使它们没有被显式使用。
二、需要配置CMakeLists.txt 文件
三、完整的配置,主要是add_library(opencv_so SHARED my_dynamic_lib.cpp)之后的代码,my_dynamic_lib.cpp是一个空文件,啥毛也不需要有。
cmake_minimum_required(VERSION 3.6)
set(target native-lib)
project(${target} CXX)
include_directories(${PROJECT_SOURCE_DIR}/../../../../sdk_so/native/jni/include)
get_cmake_property(_variableNames VARIABLES)
foreach (_variableName ${_variableNames})
message(WARNING "${_variableName}=${${_variableName}}")
endforeach()
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jni-libs/${ANDROID_ABI})
# 添加您的静态库
#add_library(libstatic_opencv STATIC IMPORTED)
#set_target_properties(libstatic_opencv PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../../../../sdk/native/staticlibs/${ANDROID_ABI}/libopencv_core.a)
#target_link_libraries(${target} libstatic_opencv)
file(GLOB srcs *.cpp *.c)
file(GLOB hdrs *.hpp *.h)
include_directories("${CMAKE_CURRENT_LIST_DIR}")
add_library(${target} SHARED ${srcs} ${hdrs})
message(WARNING "target: ${target}")
message(WARNING "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}")
message(WARNING "CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
message(WARNING "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
message(WARNING "CMAKE_PROJECT_NAME: ${CMAKE_PROJECT_NAME}")
#target_link_libraries(${target} lib_opencv)
#add_library(libshared_opencv SHARED IMPORTED )
#set_target_properties(libshared_opencv PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../../../../sdk/native/libs/${ANDROID_ABI}/libopencv_java4.so)
#target_link_libraries(${target} libshared_opencv)
# 设置静态库的路径
set(LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../sdk_so/native/libs/${ANDROID_ABI})
# 使用 file(GLOB ...) 获取所有的动态库文件列表
file(GLOB OPENCV_SHARED_LIBS "${LIB_DIR}/*.so")
# 设置目标属性,将找到的所有动态库链接到 native-lib
foreach(LIB_FILE ${OPENCV_SHARED_LIBS})
# 获取不带路径的库文件名
get_filename_component(LIB_NAME ${LIB_FILE} NAME_WE)
# 添加库(这里每个库都是独立的 target)
add_library(${LIB_NAME} SHARED IMPORTED)
set_target_properties(${LIB_NAME} PROPERTIES IMPORTED_LOCATION ${LIB_FILE})
message(WARNING "LIB_NAME:${LIB_NAME} LIB_FILE: ${LIB_FILE}")
# 链接库到 native-lib
target_link_libraries(${target} ${LIB_NAME})
endforeach()
#https://blog.csdn.net/shulianghan/article/details/104349622
#可以不进行该配置, 直接在后面的 target_link_libraries 中链接 log 也不会出错
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
find_library( # Sets the name of the path variable.
z-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
z )
message(WARNING "log-lib:${log-lib}")
message(WARNING "z-lib:${z-lib}")
target_link_libraries(${target} ${log-lib} z)
#FATAL_ERROR STATIC WARNING
message(WARNING "^_^ all done ^_^")
# 假设我们有两个静态库 libstatic1.a 和 libstatic2.a
# 并且我们想将它们链接到一个叫做 libcombined.so 的共享库中
# 创建一个新的共享库目标
#add_library(combined SHARED dummy.c )
#set_target_properties(combined PROPERTIES LINKER_LANGUAGE CXX)
#set(LIB_STATIC_NAME ${CMAKE_CURRENT_SOURCE_DIR}/../../../../sdk-static/native/staticlibs/${ANDROID_ABI}/libopencv_video.a)
#target_link_libraries(combined ${LIB_STATIC_NAME})
# 创建一个名为 "native-lib" 的库,将其设置为 SHARED 类型,并提供要编译的 C 源文件
add_library(opencv_so SHARED my_dynamic_lib.cpp)
project(opencv_so CXX)
#set_target_properties(opecv_so PROPERTIES LINKER_LANGUAGE CXX)
# 将日志库 (log-lib) 链接到你的 native-lib 库
set(LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../sdk-static/native/staticlibs/${ANDROID_ABI})
# 使用 file(GLOB ...) 获取所有的静态库文件列表
file(GLOB LIB_STATIC_FILES "${LIB_DIR}/*.a")
# 设置目标属性,将找到的所有静态库链接到 native-lib
foreach(LIB_STATIC_FILE ${LIB_STATIC_FILES})
# 获取不带路径的库文件名
get_filename_component(LIB_STATIC_NAME ${LIB_STATIC_FILE} NAME_WE)
set(LIB_STATIC_NAME ${LIB_STATIC_NAME}test)
# 添加库(这里每个库都是独立的 target)
add_library(${LIB_STATIC_NAME} STATIC IMPORTED)
set_target_properties(${LIB_STATIC_NAME} PROPERTIES IMPORTED_LOCATION ${LIB_STATIC_FILE})
message(WARNING "LIB_STATIC_NAME:${LIB_STATIC_NAME} LIB_STATIC_FILE: ${LIB_STATIC_FILE}")
# 链接库到 native-lib FATAL_ERROR
target_link_libraries(opencv_so
-Wl,-whole-archive
-Wl,--allow-multiple-definition
${LIB_STATIC_NAME})
endforeach()
# 设置静态库的路径
set(LIB_3RDPARTY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../sdk-static/native/3rdparty/libs/${ANDROID_ABI})
file(GLOB LIB_3RDPARTY_FILES "${LIB_3RDPARTY_DIR}/*.a")
foreach(LIB_3RDPARTY_FILE ${LIB_3RDPARTY_FILES})
# 获取不带路径的库文件名
get_filename_component(LIB_3RDPARTY_NAME ${LIB_3RDPARTY_FILE} NAME_WE)
# 添加库(这里每个库都是独立的 target)
add_library(${LIB_3RDPARTY_NAME} STATIC IMPORTED)
set_target_properties(${LIB_3RDPARTY_NAME} PROPERTIES IMPORTED_LOCATION ${LIB_3RDPARTY_FILE})
message(WARNING "LIB_3RDPARTY_NAME:${LIB_3RDPARTY_NAME} LIB_3RDPARTY_FILE: ${LIB_3RDPARTY_FILE}")
# 链接库到 native-lib FATAL_ERROR
target_link_libraries(opencv_so
-Wl,-whole-archive
-Wl,--allow-multiple-definition
${LIB_3RDPARTY_NAME})
endforeach()
target_link_libraries(opencv_so log z)
message(WARNING "^_^ build a file to one so ^_^")
四、编译后就会生成libopencv_so.so,大功造成。
五、调用这个libopencv_so库的时候CMakeLists.txt 文件配置如下。
cmake_minimum_required(VERSION 3.6)
set(target test-lib)
project(${target} CXX)
include_directories(${PROJECT_SOURCE_DIR}/../../../../sdk_so/native/jni/include)
get_cmake_property(_variableNames VARIABLES)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jni-libs/${ANDROID_ABI})
# 添加您的静态库
#add_library(libstatic_opencv STATIC IMPORTED)
#set_target_properties(libstatic_opencv PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../../../../sdk/native/staticlibs/${ANDROID_ABI}/libopencv_core.a)
#target_link_libraries(${target} libstatic_opencv)
include_directories("${CMAKE_CURRENT_LIST_DIR}")
add_library(${target} SHARED dummy.cpp)
add_library(libshared_opencv SHARED IMPORTED )
set_target_properties(libshared_opencv PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jni-libs/${ANDROID_ABI}/libopencv_so.so)
#set_target_properties(libshared_opencv PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../jni-libs/${ANDROID_ABI}/libopencv_java4.so)
target_link_libraries(${target} libshared_opencv)
target_link_libraries(${target} log z dl)
message(WARNING "^_^ call my one so ^_^")