win下编译TNN安卓库(静态或者动态) + android studio ndk调用

前言:
如果想借用TNN自己写一个库(比如exp.so), 通常我们选用TNN的静态库(libTNN.a),
因为使用静态库后自己生成的库文件就一个exp.so
如果使用动态库(libTNN.so)那么自己生成的库文件就有两个了: libTNN.so和exp.so

TNN安卓库编译

环境:
    源码: https://github.com/Tencent/TNN/archive/refs/tags/v0.3.0.zip
    c++编译器: "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
    cmake: cmake-3.20.4-windows-x86_64.zip
    android ndk: android-ndk-r20b-windows-x86_64.zip

1.解压/安装上面各个包
2.新建xxx.bat, 写入以下内容:(以下编译的是arm64-v8a, 静态库)

::功能: 在windows下编译tnn for android

call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
::set VS_CL_PATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\Hostx86\x64
::set PATH=%PATH%;%VS_CL_PATH%

set TNN_ROOT=D:\code\TNN\TNN-0.3.0
set CMAKE_BIN=D:\development_kits\cmake-3.20.4-windows-x86_64\bin
set ANDROID_NDK=D:\development_kits\android-ndk-r20b
::set ABIA32=armeabi-v7a
set ABIA32=arm64-v8a
:: SHARED_LIB ON表示动态库, OFF表示静态库
set SHARED_LIB=OFF


set PATH=%PATH%;%CMAKE_BIN%
if "%SHARED_LIB%" == "ON" (
	set MODE=share
) else if "%SHARED_LIB%" == "OFF" (
	set MODE=static
) else (
	echo unknown model with SHARED_LIB: %SHARED_LIB%. exit.
	pause
	exit
)


cd %TNN_ROOT%
mkdir build_android
cd build_android
mkdir %MODE%
cd %MODE%
mkdir %ABIA32%
cd %ABIA32%


cmake -G "Unix Makefiles" ^
-DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%/build/cmake/android.toolchain.cmake ^
-DCMAKE_MAKE_PROGRAM="%ANDROID_NDK%/prebuilt/windows-x86_64/bin/make.exe" ^
-DDEBUG:BOOL=OFF ^
-DANDROID_ABI="%ABIA32%" ^
-DANDROID_STL=c++_static ^
-DANDROID_NATIVE_API_LEVEL=android-14 ^
-DANDROID_TOOLCHAIN=clang ^
-DBUILD_FOR_ANDROID_COMMAND=true ^
-DTNN_CPU_ENABLE:BOOL=ON ^
-DTNN_ARM_ENABLE:BOOL=ON ^
-DTNN_HUAWEI_NPU_ENABLE:BOOL=OFF ^
-DTNN_OPENCL_ENABLE:BOOL=ON ^
-DTNN_BENCHMARK_MODE:BOOL=OFF ^
-DTNN_TEST_ENABLE:BOOL=ON ^
-DTNN_OPENMP_ENABLE:BOOL=ON ^
-DSHARING_MEM_WITH_OPENGL=0 ^
-DTNN_BUILD_SHARED:BOOL=%SHARED_LIB% %TNN_ROOT%
	  

cmake --build . -j4
cmd.exe /k

3.双击编译成功
4.总结
    1.用的是vs2019的c++编译器, vs2017 vs2013应该也行
    2.cmake指令选项参考官方scripts/build_android.sh
    3.目前只测试arm64-v8a成功, 对于armeabi-v7a平台(属于32位arm), 不知道能不能用, 可能需要搭配32位的vs编译器(vcvars32.bat)?


android studio ndk工程调用

android studio环境
    android studio: 4.2.2
    buildToolsVersion “30.0.2”
    ndkVersion "20.0.5594570"
以上buildToolsVersion和ndkVersion最好在build.gradle中指明:

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"
//    ndkVersion "21.4.7075529" // android studio 4.2 默认ndk版本, 搭配android-ndk-r20b生成的libTNN.a build成功报警告, run app失败
    ndkVersion "20.0.5594570" // 搭配android-ndk-r20b生成的libTNN.a build成功报警告, run app成功
//    ndkVersion "16.1.4479499" // 搭配android-ndk-r20b生成的libTNN.a build失败
    ...
}



1.新建android studio native c++工程
2.写好各种所需要的java和cpp代码
3.在CMakeLists.txt中加入对TNN链接库的链接和头文件引用
    引用头文件:  

include_directories(${TNN_ROOT}/include)

    只针对arm64-v8a和armeabi-v7a平台(TNN android只编译了这两种平台):

if((ANDROID_ABISTREQUAL"arm64-v8a")OR(ANDROID_ABISTREQUAL"armeabi-v7a"))

    导入TNN库:

#=== 导入TNN库libTNN.so/libTNN.a
add_library (tnn ${LIB_MODE} IMPORTED)
if("${LIB_MODE}" STREQUAL "SHARED")
    set(LIB_TNN_FILE libTNN.so)
endif()
if("${LIB_MODE}" STREQUAL "STATIC")
    set(LIB_TNN_FILE libTNN.a)
endif()
set_target_properties(tnn PROPERTIES IMPORTED_LOCATION ${TNN_ROOT}/build_android/${LIB_MODE}/${ANDROID_ABI}/${LIB_TNN_FILE})

    链接TNN库:

    #=== 将TNN库与目标文件链接. -fopenmp和-Wl,--whole-archive tnn -Wl,--no-whole-archive是gcc的编译选项
    #=== 添加动态链接库jnigraphics解决AndroidBitmap_getInfo报错
    #=== 添加fopenmp解决undefined reference to '__kmpc_fork_call错误 参考https://github.com/Tencent/ncnn/issues/292
    if("${LIB_MODE}" STREQUAL "STATIC")
        target_link_libraries( # Specifies the target library.
                native-lib
                -ljnigraphics
                -fopenmp
                -Wl,--whole-archive tnn -Wl,--no-whole-archive
                tnn)
    endif()
    if("${LIB_MODE}" STREQUAL "SHARED")
        target_link_libraries( # Specifies the target library.
                native-lib
                -ljnigraphics
                tnn)
    endif()

完整的CMakeLists.txt:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.10.2)

# Declares and names the project.

project("tnn")

set(TNN_ROOT D:/code/TNN/TNN-0.3.0)
include_directories(${TNN_ROOT}/include)
include_directories(${CMAKE_SOURCE_DIR}/)
set(LIB_MODE STATIC) # STATIC表示使用libTNN.a, SHARED表示使用libTNN.so

if((ANDROID_ABI STREQUAL "arm64-v8a") OR (ANDROID_ABI STREQUAL "armeabi-v7a"))
    #=== 导入TNN库libTNN.so/libTNN.a
    add_library (tnn ${LIB_MODE} IMPORTED)
    if("${LIB_MODE}" STREQUAL "SHARED")
        set(LIB_TNN_FILE libTNN.so)
    endif()
    if("${LIB_MODE}" STREQUAL "STATIC")
        set(LIB_TNN_FILE libTNN.a)
    endif()
    set_target_properties(tnn PROPERTIES IMPORTED_LOCATION ${TNN_ROOT}/build_android/${LIB_MODE}/${ANDROID_ABI}/${LIB_TNN_FILE})

    #=== 编译写好的接口, 生成链接文件
    file(GLOB_RECURSE TNN_WRAPPER_SRCS ${CMAKE_SOURCE_DIR}/*.cc)    # 包含TNN的代码
    file(GLOB_RECURSE OTHER_SRCS ${CMAKE_SOURCE_DIR}/*.cpp)         # 不包含TNN的代码
    add_library( # Sets the name of the library.
            native-lib
            # Sets the library as a shared library.
            SHARED
            # Provides a relative path to your source file(s).
            ${TNN_WRAPPER_SRCS} ${OTHER_SRCS})

    #=== 将TNN库与目标文件链接. -fopenmp和-Wl,--whole-archive tnn -Wl,--no-whole-archive是gcc的编译选项
    #=== 添加动态链接库jnigraphics解决AndroidBitmap_getInfo报错
    #=== 添加fopenmp解决undefined reference to '__kmpc_fork_call错误 参考https://github.com/Tencent/ncnn/issues/292
    if("${LIB_MODE}" STREQUAL "STATIC")
        target_link_libraries( # Specifies the target library.
                native-lib
                -ljnigraphics
                -fopenmp
                -Wl,--whole-archive tnn -Wl,--no-whole-archive
                tnn)
    endif()
    if("${LIB_MODE}" STREQUAL "SHARED")
        target_link_libraries( # Specifies the target library.
                native-lib
                -ljnigraphics
                tnn)
    endif()
else()
    #=== 编译不包含TNN的接口, 生成链接文件
    file(GLOB_RECURSE OTHER_SRCS ${CMAKE_SOURCE_DIR}/native-lib.cpp) # 不包含TNN的代码
    add_library( # Sets the name of the library.
            native-lib
            # Sets the library as a shared library.
            SHARED
            # Provides a relative path to your source file(s).
            ${OTHER_SRCS})
endif()


#=== log-lib是工程建立后默认就有的
#=== 似乎用来在android中打印cpp代码的log
#=== 参考https://stackoverflow.com/questions/4629308/any-simple-way-to-log-in-android-ndk-code
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 )

target_link_libraries( # Specifies the target library.
        native-lib
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib} )

关于android studio下调用tnn的so/a库详细内容可以看这里https://blog.csdn.net/ying86615791/article/details/119828457


 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值