Android高级开发工程师-NDK开发

997 阅读4分钟

一、编译原理

将高级语言转换为二进制机器码

编译流程

  1. 预处理
  • 完成宏替换、文件引入,以及去除空行、注释等,为下一步的编译做准备。
  • 对各种预处理命令进行处理,包括投文件的包含、宏定义的扩张、条件编译的选择等。
  1. 编译
  • 将预处理后的代码编译成汇编代码。在这个阶段,首先要检查代码的规范性、是否有语法错误等,以确定代码实际要做的工作,在检查无误后,再把代码翻译成汇编语言。
  • 编译程序执行时,先分析,后综合。分析,就是指词法分析、语法分析、语义分析和中间代码生成。综合,就是指代码优化和代码生成。
  • 大多数的编译程序直接产生机器语言的目标代码,形成可执行的目标文件,也有的是先产生汇编语言一级的符号代码文件,再用汇编程序进行翻译和加工处理,最后产生可执行的机器语言文件。
  1. 汇编
  • 就是将汇编代码文件转成二进制代码文件,即机器代码文件(01序列)。
  1. 链接
  • 就是将多个目标文件及所需的库文件链接生成可执行文件的过程。

二、动态库和静态库

  1. 静态库
  • 就是一些目标文件(.o结尾)的集合,静态库一般以.a结尾,只用于生成可执行文件阶段。
  • 在链接步骤中,链接器将从库文件取得所需代码,复制到生成的可执行文件中。
  • 特点是可执行文件中包含了库代码的一份完整拷贝,在编译过程中被载入程序中。缺点就是多次使用会有多分冗余拷贝,而且因为是在编译阶段进行的拷贝,如果静态库有更新,所有使用它的程序都需要重新编译、发布。
  • 静态库的编译的可执行文件的依赖,静态库不需要被依赖。
  1. 动态库
  • 一般以.so结尾。
  • 在链接阶段没有被复制到程序中,而是在程序运行时有系统动态加载到内存中供程序调用。
  • 系统只需载入一次动态库,不同的程序可以得到内存中相同动态库的副本。
  • 动态库的编译的可执行文件的依赖,动态库是需要依赖的。
  1. 区别
  • 静态库,在程序编译时会复制代码到目标代码中,程序运行时不再需要静态库,因此体积较大。而且每次编译都需要载入静态代码,因此内存开销大。
  • 动态库,在程序编译时不会复制代码到目标代码中,而是在程序运行时才被载入,程序运行时需要动态库存在,因此体积较小。而且系统只需载入一次动态库,不同程序可以得到内存中相同的动态库副本,因此内存开销小。

三、Android.mk简介

Android.mk是一个面向Android NDK构建系统描述NDK项目的GNU makefile片段。主要用来编译生成以下内容:

  • APK程序:一般的Android应用程序,系统级别的直接push即可。
  • JAVA库:JAVA类库,编译打包生成JAR文件。
  • C/C++应用程序:可执行的C/C++应用程序。
  • C/C++静态库:编译生成C/C++静态库,并打包成.a文件。
  • C/C++动态库:编译生成C/C++动态库,并打包成.so文件。
#定义模块当前路径(必须定义在文件开头,只需定义一次)
#利用该变量来定位源文件
# my-dir是编译系统提供的宏函数,返回当前Android.mk的路径
LOCAL_PATH := $(call my-dir)

#清空当前环境变量(LOCAL_PATH除外)
#CLEAR_VARS是编译系统提供的变量,指向特定的GNU的makefile片段,清除环境变量
#使用该语法原因是,编译系统在单次执行中会解析多个构建文件和模块定义。而LOCAL开头的变量是全局变量。所以每次都要先清除下环境变量,避免冲突
include $(CLEAR_VARS)

#当前模块名(这里会生成libhello-jni.so)
#必须唯一,不能包含空格
LOCAL_MODULE := hello-jni

#当前模块包含的源代码文件
#多个文件,空格分隔
LOCAL_SRC_FILES := hello-jni.c

#表示当前模块被编译成库的类型。静态库、共享库。
#当前为共享库
Include $(BUILD_SHARED_LIBRARY)

示例

预编译模块不需要编译。该预编译模块会被拷贝到 PROJECT/obj/local 下面,还会被拷贝到PROJECT/libs/<abi> 下面(这里的库被strip过)。

四、CMake

CMakeLists.txt简介

AndroidStudio3.4以后,创建C/C++Support的项目,会再src/main目录生成cpp目录,包含CMakeLists.txt。

改动或新增.cpp文件,要重新调用gradle同步,才会编译,否则.cpp文件提示错误。

示例

CMakeLists.txt配置

使用第三方库
gradle配置

介绍

#指定CMake最低支持的版本(可选)
#如果使用了高版本的命令,则需要指定最低的版本
cmake_minimum_required(VERSION 3.4.1)

NDK开发步骤

Android Native Developmeng Kit (NDK)是一系列的开发工具,运行程序开发人员在Android应用程序中嵌入C/C++编写的代码。你可以使用它去构建自己的源码或利用现有的库。

  1. 通过AndroidStudio下载NDK
  2. 配置NDK环境变量
  • 如何验证,使用ndk-build命令
  1. 编译JNI的方式
  • android.mk
  • cmake(AndroidStudio2.2以后默认方式)