百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

深入理解Android NDK 编译(二) android ndk教程

liebian365 2024-11-09 13:41 7 浏览 0 评论

使用 CMake 进行Android NDK编译的原理


介绍

Android Studio 2.2 及以后的版本默认使用CMake进行 NDK 编译 NDK, 其中最吸引人的地方是,在开发NDK程序时可以进行联机调试,这真是大在的方便了我们开发NDK程序的效率了。 那么使用CMake编译NDK程序是否与我们之前介绍的使用ndk-build编译有很大的不同呢?下面我们就来一窥它的原理吧。

前面我给大家介绍了两种交叉编译的方式,没看过的同学可以浏览一下( Linux/Mac 交叉编译 Android 程序深入理解Android NDK编译(一)

什么是CMake

CMake是个开源的跨平台自动化建构系统,它用配置文件控制建构过程(build process)的方式和Unix的Make相似,只是CMake的配置文件取名为CMakeLists.txt。Cmake并不直接建构出最终的软件,而是产生标准的建构档(如Unix的Makefile或Windows Visual C++的projects/workspaces),然后再依一般的建构方式使用

“CMake”这个名字是"cross platform make"的缩写。虽然名字中含有"make",但是CMake和Unix上常见的“make”系统是分开的,而且更为高级

Android Studio 如何使用 CMake

其实通过 CMake 进行 NDK 交叉编译的方式与我们之前介绍的两种方式的原理是相同的。 都是要先设定交叉编译各种工具的环境, 包括编译器、链接器等。 然后再通过自动化构建工具进行编译。

Android Studio在执行 CMake build 之前,会将需要的参数存放在 cmake_build_command.txt 文件中,针对每种ABI(arm, mips, x86等)及每种build类型(debug, release),Android Studio都会拷贝一份 cmake_build_command.txt 到<project-root>/<module-root>/.externalNativeBuild/cmake/<build-type>/<ABI>/目录下。

我们来看一下在 cmake_build_command.txt 里都是些什么内容:

Executable : ~/Library/Android/sdk/cmake/3.6.3155560/bin/cmake

arguments :

-H~/mytest/MyApplication/app

-B~/mytest/MyApplication/app/.externalNativeBuild/cmake/debug/arm64-v8a

-GAndroid Gradle - Ninja

-DANDROID_ABI=arm64-v8a

-DANDROID_NDK=~/Library/Android/sdk/ndk-bundle

-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=~/mytest/MyApplication/app/build/intermediates/cmake/debug/obj/arm64-v8a

-DCMAKE_BUILD_TYPE=Debug

-DCMAKE_MAKE_PROGRAM=~/Library/Android/sdk/cmake/3.6.3155560/bin/ninja

#下面这个参数特别重要

-DCMAKE_TOOLCHAIN_FILE=~/Library/Android/sdk/ndk-bundle/build/cmake/android.toolchain.cmake

-DANDROID_PLATFORM=android-21

-DCMAKE_CXX_FLAGS=-std=c++11 -frtti -fexceptions

Build ArgumentsDescription
-G < build-system ><build-system> 一般设置为 “Android Gradle - Ninja” 它指明 CMake 使用 ninja build system 编译并链接C/C++ ,同时 CMake 还会产生android_gradle_build.json 文件,该文件包含了Gradle CMake 插件使用的信息,如编译参数,产生的目标名等。
-DANDROID_ABI < abi >NDK 支持的 ABIs, 如 armeabi,armeabi-v7a,armeabi-v7a with NEON,arm64-v8a等。
-DANDROID_NDK < path >NDK安装路径
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY < path >输出库的位置
-DCMAKE_BUILD_TYPE < type >build 类型 release 或 debug
-DCMAKE_MAKE_PROGRAM < program-name >启动 native build 系统的工具
-DCMAKE_TOOLCHAIN_FILE < path >CMake 用于交叉编译 Andriod配置文件的路径。它位于 $NDK/build/cmake/ directory 目录下。
-DANDROID_PLATFORM < level >CMake 编译 Android API 级别

在这些参数里,-DCMAKE_TOOLCHAIN_FILE 这个参数特别重要,因为 Android Stuido 在这个参数指定的文件里设置了交叉编译工具的环境变量,下面我们来大体看一下它流程:

207 ......

208 # ABI.

209 set(CMAKE_ANDROID_ARCH_ABI ${ANDROID_ABI})

210 if(ANDROID_ABI MATCHES "^armeabi(-v7a)?$")

211 set(ANDROID_SYSROOT_ABI arm)

212 set(ANDROID_TOOLCHAIN_NAME arm-linux-androideabi)

213 set(ANDROID_TOOLCHAIN_ROOT ${ANDROID_TOOLCHAIN_NAME})

214 set(ANDROID_HEADER_TRIPLE arm-linux-androideabi)

215 if(ANDROID_ABI STREQUAL armeabi)

216 set(CMAKE_SYSTEM_PROCESSOR armv5te)

217 set(ANDROID_LLVM_TRIPLE armv5te-none-linux-androideabi)

218 elseif(ANDROID_ABI STREQUAL armeabi-v7a)

219 set(CMAKE_SYSTEM_PROCESSOR armv7-a)

220 set(ANDROID_LLVM_TRIPLE armv7-none-linux-androideabi)

221 endif()

222

223 ......

android.toolchain.cmake 在第 208 行根据 cmake_build_command.txt 文件中ABI的值,设置 ANDROID_SYSROOT_ABI、ANDROID_TOOLCHAIN_NAME、ANDROID_TOOLCHAIN_ROOT等参数。 然后走到 318 行,设置 CMAKE_SYSROOT 值如下:

317 ......

318 # Sysroot.

319 if(ANDROID_DEPRECATED_HEADERS)

320 set(CMAKE_SYSROOT

321 "${ANDROID_NDK}/platforms/${ANDROID_PLATFORM}/arch-${ANDROID_SYSROOT_ABI}")

322 else()

323 set(CMAKE_SYSROOT "${ANDROID_NDK}/sysroot")

324 ......

设置完 CMAKE_SYSROOT 走到 355 行,设置ANDROID_TOOLCHAIN_ROOT 和 C/C++ 编译器,代码如下:

354 ......

355 # Toolchain.

355 # 首先判断运行的宿主机是什么

356 if(CMAKE_HOST_SYSTEM_NAME STREQUAL Linux)

357 set(ANDROID_HOST_TAG linux-x86_64)

358 elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin)

359 set(ANDROID_HOST_TAG darwin-x86_64)

360 elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows)

361 set(ANDROID_HOST_TAG windows-x86_64)

362 endif()

362 # 设置 ANDROID_TOOLCHAIN_ROOT

363 set(ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_ROOT}-4.9/prebuilt/${ANDROID_HOST_TAG}")

364 set(ANDROID_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_NAME}-")

365 ......

368

369 set(ANDROID_HOST_PREBUILTS "${ANDROID_NDK}/prebuilt/${ANDROID_HOST_TAG}")

370 # 如果编译器是 clang

371 if(ANDROID_TOOLCHAIN STREQUAL clang)

372 set(ANDROID_LLVM_TOOLCHAIN_PREFIX "${ANDROID_NDK}/toolchains/llvm/prebuilt/${ANDROID_HOST_TAG}/bin/")

373 set(ANDROID_C_COMPILER "${ANDROID_LLVM_TOOLCHAIN_PREFIX}clang${ANDROID_TOOLCHAIN_SUFFIX}")

374 set(ANDROID_CXX_COMPILER "${ANDROID_LLVM_TOOLCHAIN_PREFIX}clang++${ANDROID_TOOLCHAIN_SUFFIX}")

375 set(ANDROID_ASM_COMPILER "${ANDROID_LLVM_TOOLCHAIN_PREFIX}clang${ANDROID_TOOLCHAIN_SUFFIX}")

376 ......

396 # 如果编译器是 gcc

397 elseif(ANDROID_TOOLCHAIN STREQUAL gcc)

398 set(ANDROID_C_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}gcc${ANDROID_TOOLCHAIN_SUFFIX}")

399 set(ANDROID_CXX_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}g++${ANDROID_TOOLCHAIN_SUFFIX}")

400 set(ANDROID_ASM_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}gcc${ANDROID_TOOLCHAIN_SUFFIX}")

所以通过上面的分析我们可以了解到,Android Studio 通过cmake_build_command.txt指定的 android.toolchain.cmake 文件就把交叉编译的环境设置好了。

CMake NDK 编译过程

当我们在Android Studio中build我们的NDK工程时,AS会通过上面的步骤为我们设置好交叉编译环境,然后再将CMakelists.txt文件传给 CMake, CMake解析里面的内容,并最终调用不同平台的工具,编译出我们需要的目标环境程序。

小结

通过上面的分析,我们知道了 Android Studio 在开发 NDK 程序时,是如何使用 CMake Gradle plugin 设置交叉编译环境的,也基本了解了 CMake 编译 NDK 程序的基本流程。希望本篇文章可以帮助大家理解最新的 Andriod Studio 是如何使用 CMake进行交叉编译的。

相关推荐

快递查询教程,批量查询物流,一键管理快递

作为商家,每天需要查询许许多多的快递单号,面对不同的快递公司,有没有简单一点的物流查询方法呢?小编的回答当然是有的,下面随小编一起来试试这个新技巧。需要哪些工具?安装一个快递批量查询高手快递单号怎么快...

一键自动查询所有快递的物流信息 支持圆通、韵达等多家快递

对于各位商家来说拥有一个好的快递软件,能够有效的提高自己的工作效率,在管理快递单号的时候都需要对单号进行表格整理,那怎么样能够快速的查询所有单号信息,并自动生成表格呢?1、其实方法很简单,我们不需要一...

快递查询单号查询,怎么查物流到哪了

输入单号怎么查快递到哪里去了呢?今天小编给大家分享一个新的技巧,它支持多家快递,一次能查询多个单号物流,还可对查询到的物流进行分析、筛选以及导出,下面一起来试试。需要哪些工具?安装一个快递批量查询高手...

3分钟查询物流,教你一键批量查询全部物流信息

很多朋友在问,如何在短时间内把单号的物流信息查询出来,查询完成后筛选已签收件、筛选未签收件,今天小编就分享一款物流查询神器,感兴趣的朋友接着往下看。第一步,运行【快递批量查询高手】在主界面中点击【添...

快递单号查询,一次性查询全部物流信息

现在各种快递的查询方式,各有各的好,各有各的劣,总的来说,还是有比较方便的。今天小编就给大家分享一个新的技巧,支持多家快递,一次能查询多个单号的物流,还能对查询到的物流进行分析、筛选以及导出,下面一起...

快递查询工具,批量查询多个快递快递单号的物流状态、签收时间

最近有朋友在问,怎么快速查询单号的物流信息呢?除了官网,还有没有更简单的方法呢?小编的回答当然是有的,下面一起来看看。需要哪些工具?安装一个快递批量查询高手多个京东的快递单号怎么快速查询?进入快递批量...

快递查询软件,自动识别查询快递单号查询方法

当你拥有多个快递单号的时候,该如何快速查询物流信息?比如单号没有快递公司时,又该如何自动识别再去查询呢?不知道如何操作的宝贝们,下面随小编一起来试试。需要哪些工具?安装一个快递批量查询高手快递单号若干...

教你怎样查询快递查询单号并保存物流信息

商家发货,快递揽收后,一般会直接手动复制到官网上一个个查询物流,那么久而久之,就会觉得查询变得特别繁琐,今天小编给大家分享一个新的技巧,下面一起来试试。教程之前,我们来预览一下用快递批量查询高手...

简单几步骤查询所有快递物流信息

在高峰期订单量大的时候,可能需要一双手当十双手去查询快递物流,但是由于逐一去查询,效率极低,追踪困难。那么今天小编给大家分享一个新的技巧,一次能查询多个快递单号的物流,下面一起来学习一下,希望能给大家...

物流单号查询,如何查询快递信息,按最后更新时间搜索需要的单号

最近有很多朋友在问,如何通过快递单号查询物流信息,并按最后更新时间搜索出需要的单号呢?下面随小编一起来试试吧。需要哪些工具?安装一个快递批量查询高手快递单号若干怎么快速查询?运行【快递批量查询高手】...

连续保存新单号功能解析,导入单号查询并自动识别批量查快递信息

快递查询已经成为我们日常生活中不可或缺的一部分。然而,面对海量的快递单号,如何高效、准确地查询每一个快递的物流信息,成为了许多人头疼的问题。幸运的是,随着科技的进步,一款名为“快递批量查询高手”的软件...

快递查询教程,快递单号查询,筛选更新量为1的单号

最近有很多朋友在问,怎么快速查询快递单号的物流,并筛选出更新量为1的单号呢?今天小编给大家分享一个新方法,一起来试试吧。需要哪些工具?安装一个快递批量查询高手多个快递单号怎么快速查询?运行【快递批量查...

掌握批量查询快递动态的技巧,一键查找无信息记录的两种方法解析

在快节奏的商业环境中,高效的物流查询是确保业务顺畅运行的关键。作为快递查询达人,我深知时间的宝贵,因此,今天我将向大家介绍一款强大的工具——快递批量查询高手软件。这款软件能够帮助你批量查询快递动态,一...

从复杂到简单的单号查询,一键清除单号中的符号并批量查快递信息

在繁忙的商务与日常生活中,快递查询已成为不可或缺的一环。然而,面对海量的单号,逐一查询不仅耗时费力,还容易出错。现在,有了快递批量查询高手软件,一切变得简单明了。只需一键,即可搞定单号查询,一键处理单...

物流单号查询,在哪里查询快递

如果在快递单号多的情况,你还在一个个复制粘贴到官网上手动查询,是一件非常麻烦的事情。于是乎今天小编给大家分享一个新的技巧,下面一起来试试。需要哪些工具?安装一个快递批量查询高手快递单号怎么快速查询?...

取消回复欢迎 发表评论: