Cmake学习记录(九)--使用Cmake交叉编译Android .so库

这篇具有很好参考价值的文章主要介绍了Cmake学习记录(九)--使用Cmake交叉编译Android .so库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前言

注意:本教程没有关于JNI接口的写法,只是把C代码编译成适合android平台的so库,想查看完整代码可以参考文末的第9条参考链接
目前Android编译.so的话使用Android Studio比较简单,但是有时候时候Android Studio的话还需要创建一个Android的项目,这里记录下脱离Android Studio单纯使用Cmake和C++开发工具Clion(或者其他的开发工具也行,这些开发工具和Android Studio不一样,哪一种工具都行)。
实际上编译.so还有比较简单的方式。比如直接在linux环境下面使用cmake编译c++项目即可,这时候出现的就是.so库。但是如果开发环境是Mac或者Windows的话,就会生成dylib或者exe文件,不是我们想要的文件,所以就需要使用交叉编译的技术。
Cmake对于编译Android的.so文件提供了两种方式: NDK或者交叉工具链。不管使用NDK或者交叉工具链哪种方式都需要跟NDK进行关联,不会出现脱离NDK就编译处.so的问题

二、使用NDK进行编译的相关代码

开发工具为CLion,需要注意的是Android Studio和CLion都采用了ninja构建系统,如果使用其他构建系统需要进行修改,不过文中代码已经有该代码,到时候改下路径即可
整体项目结构如下:
cmake链接so,C++,学习,android,android studio
这其中的核心代码为:
需要注意的是该代码中的set部分需要写在project(untitled VERSION 1.0)函数调用之前

# control where the static and shared libraries are built so that on windows
# we don't need to tinker with the path to run the executable
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 21) # API level
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_ANDROID_NDK /Users/c/Documents/sdk/android/ndk/25.1.8937393)
#set(CMAKE_TOOLCHAIN_FILE /Users/c/Documents/sdk/android/ndk/25.1.8937393/build/cmake/android.toolchain.cmake)
set(CMAKE_MAKE_PROGRAM /Users/c/Documents/sdk/android/cmake/3.22.1/bin/ninja)
#set(CMAKE_ANDROID_STL_TYPE gnustl_static) # 需要注意的是NDK不支持这个属性,可能是NDK版本原因,所以使用c++_shared,
set(CMAKE_ANDROID_STL_TYPE c++_shared)
set(CMAKE_EXPORT_COMPILE_COMMANDS NO)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")

aux_source_directory(. SRC_LIST) #把当前目录(.)下所有源代码文件和头文件加入变量SRC_LIST
#ADD_EXECUTABLE(hello ${SRC_LIST}) #生成应用程序 hello (在windows下会自动生成hello.exe)

# 将相关文件添加到SqrtLibrary库 ,最终编译成共享库 .so
add_library(SqrtLibrary SHARED
        ${SRC_LIST}
        )

CMakeLists.txt

cmake_minimum_required(VERSION 3.23) # 这是Cmake版本

#======这一段来自Android开发者平台:https://developer.android.google.cn/ndk/guides/cmake?hl=zh-cn#using_prebuilt_libraries 
#-DCMAKE_FIND_ROOT_PATH=${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/.cxx/cmake/universalDebug/prefab/armeabi-v7a/prefab
#-DCMAKE_BUILD_TYPE=Debug
#-DCMAKE_TOOLCHAIN_FILE=${HOME}/Android/Sdk/ndk/22.1.7171670/build/cmake/android.toolchain.cmake
#-DANDROID_ABI=armeabi-v7a
#-DANDROID_NDK=${HOME}/Android/Sdk/ndk/22.1.7171670
#-DANDROID_PLATFORM=android-23
#-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a
#-DCMAKE_ANDROID_NDK=${HOME}/Android/Sdk/ndk/22.1.7171670
#-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
#-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/build/intermediates/cmake/universalDebug/obj/armeabi-v7a
#-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/build/intermediates/cmake/universalDebug/obj/armeabi-v7a
#-DCMAKE_MAKE_PROGRAM=${HOME}/Android/Sdk/cmake/3.10.2.4988404/bin/ninja
#-DCMAKE_SYSTEM_NAME=Android
#-DCMAKE_SYSTEM_VERSION=23

#====== end ======


# control where the static and shared libraries are built so that on windows
# we don't need to tinker with the path to run the executable
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 21) # API level
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_ANDROID_NDK /Users/c/Documents/sdk/android/ndk/25.1.8937393)
set(CMAKE_MAKE_PROGRAM /Users/c/Documents/sdk/android/cmake/3.22.1/bin/ninja)
#set(CMAKE_ANDROID_STL_TYPE gnustl_static) # 需要注意的是NDK不支持这个属性,可能是NDK版本原因,所以使用c++_shared,
set(CMAKE_ANDROID_STL_TYPE c++_shared)
set(CMAKE_EXPORT_COMPILE_COMMANDS NO)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")

project(untitled VERSION 1.0)

add_subdirectory(libscanner)
configure_file(square.h.in square.h)

# specify the C++ standard
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)


# 通过BUILD_SHARED_LIBS 创建共享库,后面值需要设置为ON,
# 这个属性写到这里,如果libscanner使用这个值的话有时候会报找不到的错误,如果经过反复Build后无法解决,将该属性写到相关的libscanner的CMakeLists.txt。但是这样的话最终rebuld后只会生成libscanner的.so。不过这也是预想的情况本身顶层目录也没有要求生成.so文件
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)

add_executable(untitled square_main.cpp)

target_link_libraries(untitled PUBLIC scanner tutorial_compiler_flags)
target_include_directories(untitled PUBLIC
        "${PROJECT_BINARY_DIR}"
        "${PROJECT_SOURCE_DIR}/libscanner"
        )

# 打印日志
message("---PROJECT_BINARY_DIR--${PROJECT_BINARY_DIR}")
message("---PROJECT_SOURCE_DIR--${PROJECT_SOURCE_DIR}")
message("---libscanner头文件--${PROJECT_SOURCE_DIR}/libscanner")

libscanner/CMakeLists.txt

add_library(scanner scanner.cpp) # 默认编译成静态库
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
target_include_directories(scanner
        INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
        )

#add_executable(MakeTable scanner.cpp)
#target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
aux_source_directory(. SRC_LIST) #把当前目录(.)下所有源代码文件和头文件加入变量SRC_LIST
#ADD_EXECUTABLE(hello ${SRC_LIST}) #生成应用程序 hello (在windows下会自动生成hello.exe)


# 将相关文件添加到SqrtLibrary库
add_library(SqrtLibrary SHARED
       ${SRC_LIST}
        )


# 文件应该去哪个路径下面查找
target_include_directories(SqrtLibrary PRIVATE
        ${CMAKE_CURRENT_BINARY_DIR}
        )

# 将tutorial_compiler_flags库链接到SqrtLibrary
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)

# 将SqrtLibrary库链接到libscanner
target_link_libraries(scanner PRIVATE SqrtLibrary)

# 将tutorial_compiler_flags库链接到libscanner
target_link_libraries(scanner PUBLIC tutorial_compiler_flags)


message("YM--->${BUILD_SHARED_LIBS}")

# state that SqrtLibrary need PIC when the default is shared libraries
set_target_properties(SqrtLibrary PROPERTIES
        POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
        )

写完后重新ReBuild后即可在build文件夹下找到生成的.so库

四、使用交叉工具链进行编译

如果使用交叉工具链的话,编译跟上述方式相比只需要更改一行代码,由于NDK 新版r-19之后的改动,所以使用起来会更加简单。只要指定CMAKE_TOOLCHAIN_FILE属性即可文章来源地址https://www.toymoban.com/news/detail-657345.html

#set(CMAKE_ANDROID_NDK /Users/c/Documents/sdk/android/ndk/25.1.8937393)
set(CMAKE_TOOLCHAIN_FILE /Users/c/Documents/sdk/android/ndk/25.1.8937393/build/cmake/android.toolchain.cmake)

五、参考链接

  1. Android 官网的CMake介绍
  2. 深入理解使用CMake编译 NDK 程序
  3. cmake-toolchains(7)
  4. android/ndk-samples
  5. CMAKE 在Linux下 构建android 编译、打包、发布环境
  6. android 交叉编译常用库(cmake
  7. 10、NDK交叉编译小记
  8. cmake : add_library详解
  9. MAC环境编译Android环境下的FFmpeg6.0版本

到了这里,关于Cmake学习记录(九)--使用Cmake交叉编译Android .so库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • CMake rv1109交叉编译环境搭建

    准备安装包VMware-workstation-full-15.5.1-15018445.exe 下载地址 安装 参考资料 准备安装包ubuntu-18.04.4-desktop-amd64.iso 下载地址 安装 参考资料 准备安装包rv1109_toolchain_release.tar.bz2 下载地址 解压安装包rv1109_toolchain_release.tar.bz2 运行安装包脚本安装 配置环境变量~/.bashrc 安装结果检查 如下

    2024年02月10日
    浏览(37)
  • Ubuntu下VsCode+CMake 交叉编译

    参考连接: Ubuntu下VsCode+CMake 交叉编译 VSCode与CMake搭配使用之基本配置 VSCode与CMake搭配使用之交叉编译 step1: Ctrl+Shift+p打开VSCode的指令面板,然后输入cmake:q ; 在窗口搜索:“ CMake:Edit user-loacl CMake kits ”会打开一个cmake-tools-kits.json的文件. 如果搜索不到这个文件,先把cmake :qui

    2024年02月02日
    浏览(34)
  • CMake学习笔记-VSCode使用Cmake编译C++工程

    Win + MinGW + CMake + Git 官方教程1: https://cmake.org/cmake/help/latest/guide/tutorial/A%20Basic%20Starting%20Point.html 官方教程2: https://cmake.org/cmake/help/book/mastering-cmake/cmake/Help/guide/tutorial/index.html 官方练习材料1:https://github.com/Kitware/CMake.git 官方练习材料2:https://github.com/Kitware/CMake/blob/master/Help/guide

    2024年02月11日
    浏览(58)
  • 【交叉编译踩坑指北(一)】windows10下Vscode与Cmake编译生成文件

      工具链版本如下 C:UsersLenovocmake -version cmake version 3.24.2 C:UsersLenovomingw32-make -v GNU Make 4.2.1 Built for x86_64-w64-mingw32   若没有以上工具则进行安装,将bin文件加入到环境变量中, 注意:有的交叉编译器在安装时选择自动加入环境变量可能并不会加入,还是需要手动加入环

    2023年04月15日
    浏览(47)
  • 安装交叉编译工具链aarch64-linux-gnu-g++ 以及cmake测试

       测试文件结构    CMakeLists.txt  参考文章: linux 交叉编译 C和C++_aarch64-linux-gnu-gcc查看版本_weixin_45302027的博客-CSDN博客 ubuntu16.04 安装交叉编译工具aarch64-linux-gnu-gccg++_ubuntu 安装aarch64-linux-gnu-gcc_普通网友的博客-CSDN博客

    2024年02月12日
    浏览(47)
  • 4.Linux下Cmake交叉编译Qt项目到Jetson Orin Nano(arm)

    由于3:Ubuntu上配置QT交叉编译环境并编译QT程序到Jetson Orin Nano(ARM)_月上林梢的博客-CSDN博客  这一篇文章只用手动配置,一直在点、点、点。比较 LOW,现在在Ubuntu上使用Cmake实现交叉编译QT程序到Jetson Orin Nano上。 提醒: 我的工作环境是 Visual Studio+QT+arm 由于 Ubuntu 下没有V

    2024年02月12日
    浏览(42)
  • Linux conan+cmake管理的项目如何进行多架构编译(x86_64及交叉编译arm64)

    Conan 和 CMake 是两个非常流行的跨平台开发工具,它们可以让开发者轻松管理依赖和构建项目,支持多种操作系统和架构。下面是一些关于 conan 和 cmake 的介绍: Conan Conan 是一个用于管理 C++ 依赖项的开源工具。它可以从公共或私有存储库中自动下载和安装依赖项。Conan 可以轻

    2024年02月09日
    浏览(44)
  • Android Studio利用CMake生成.so文件并且可供其他项目引用

    CMake是一个主要用于CPP的构建工具。 CMake语言是平台无关的中间编译工具。同一个CMake编译规则在不同系统平台构建出不同的可执行构建文件,所有操作都是通过编译CMakeLists.txt来完成的。在Linux产生MakeFile,在Windows平台产生Visual Studio工程等。 CMake 旨在解决各平台的不同Make工

    2024年02月12日
    浏览(45)
  • Cmake 之Android库编译

    一 检测库和执行程序能否在Android上用 1.1 我们知道Cmake不止能编译Linux库程序,也能编译出其它系统的库,如windows,ios和android等,那么上一篇生成的Linux的库程序能否直接用于Android上呢,下面先来做个测试。 1.2 我们先在Linux平台生成一个最简单的C语言可执行程序,main.c 创建

    2024年01月21日
    浏览(36)
  • 宇树机器人Unitree-go1学习记录-CMake编译与Gazebo仿真(解决虚拟机运行gazebo帧率低问题)

    前言:环境的安装省略,一般缺什么包就sudo apt-get install xxx安装就行 (推荐使用鱼香ROS一键安装,会帮你更换源) 创建ROS工作空间:mkdir xxx_ws(一般以ws为后缀)(不能有中文路径,否则编译不通过) 切换到工作空间文件夹:执行以下命令,将终端的当前目录切换到工作空间的

    2024年01月23日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包