Android NDK学习(二):编译脚本语法Android.mk和Application.mk
一、Android.mk
Android.mk分为一下几部分:
- LOCAL_PATH:= $(call my-dir), 返回当前文件在系统中的路径,Android.mk文件开始时必须定义该变量。
- include $(CLEAR_VARS), 表明清楚上一次构建过程中的所有全局变量,因为在一个Makefile编译脚本中,会使用到大量的全局变量,使用这行脚本表明需要清除所有的全局变量。
- LOCAL_SRC_FILES,要编译的C或者CPP的文件,注意这里不需要列举头文件,构建系统会自动帮助开发者依赖这些文件。
- LOCAL_STATIC_LIBRARIES,所依赖的静态库文件
- LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib -llog -lOPENSLES -lGLESv2 -lEGL -lz,指定编译过程所依赖的NDK提供的动态和静态库,SYSROOT变量代表的是NDK_ROOT下面的目录$NDK_ROOT/platforms/android-18/arch-arm,而在这个目录的usr/lib/目录下有很多对应的so的动态库以及.a的静态库。
- LOCAL_CFLAGS,编译C或者cpp的编译标志,在实际编译的时候会发送给编译器。比如常用的实例是加上-DAUTO_TEST,然后在代码中就可以利用条件判断#ifdef AUTO_TEST来做一些与自动化测试相关的事情。
- LOCAL_LDFLAGS,链接标志的可选列表,当对目标文件进行链接以生成输出文件的时候,将这些标志带给链接器。该指令与LOCAL_LDLIBS有些类似,一般情况下,该选项会用于指定第三方编译的静态库,LOCAL_LDLIBS经常用于指定系统的库(比如log,OpenGL ES, EGL等)。
- LOCAL_MODULE,该模块的编译的目标名,用于区分各个模块,名字必须是唯一并且不包含空格的,如果编译目标是so库,那么该so库的名字就是lib项目名.so。
- include$(BUILD_SHARED_LIBRARY),其实类似的include还有很多,都是构建系统提供的内置变量,该变量的意义就是构建动态库,其他的内置变量还包括如下几种:
--- BUILD_STATIC_LIBRARY:构建静态库
--- PREBUILD_STATIC_LIBRARY:对已有的静态库进行包装,使其成为一个模块。
--- PREBUILD_SHARE_LIBRARY:对已有的动态库进行包装,使其成为一个模块。
--- BUILD_EXECUTABLE:构建可执行文件。
构建系统提供好的这些内置变量在哪里能看大呢?他们都是在$NDK-ROOT/build/core/目录下,这里会有所有预先定义好的Makefile,开发者include一个变量,实际上就是把对应的Makefile包含到Android.mk中,包括前面提到的CLEAR_VARS,其也是该目录下面的一个Makefile。
- include$(call all-makefiles-under, $(LOCAL_PATH)), 也是构建系统提供的变量,该命令会返回该目录下所有子目录的Android.mk列表。
LOCAL_SHARED_LIBRARIES 与 LOCAL_LDLIBS,LOCAL_LDFLAGS的区别?
- LOCAL_LDLIBS :链接的库不产生依赖关系,一般用于不需要重新编译的库,如库不存在,则会报错找不到。且貌似只能链接那些存在于系统目录下本模块需要连接的库。如果某一个库既有动态库又有静态库,那么在默认情况下是链接的动态库而非静态库。如:LOCAL_LDLIBS += -lm –lz –lc -lcutils –lutils –llog …如果你的Android.mk文件中只有这么一行,那么将会采用动态链接。
- LOCAL_SHARED_LIBRARIES 会生成依赖关系,当库不存在时会去编译这个库。
- LOCAL_LDFLAGS:这个编译变量传递给链接器一个一些额外的参数,比如想传递给外面的库和库路径给ld,或者传递给ld linker的一些链接参数,-On,-EL{B}(大小端字节序),那么就要加到这个上面,如:LOCAL_LDFLAGS += -L(LOCALPATH)/lib/−lHWrecog–EBEL–On…或者直接加上绝对路径库的全名:LOCALLDFLAGS+=(LOCALPATH)/lib/−lHWrecog–EBEL–On…或者直接加上绝对路径库的全名:LOCALLDFLAGS+=(LOCAL_PATH)/lib/libHWrecog.a –EB{EL} –O{n}
注:如果是非系统的第三方库,貌似只能用LOCAL_LDFLAGS方式,LOCAL_LDLIBS方式不行。
二、Application.mk
Application.mk 分为以下几个部分:
- APP_ABI :=xxx , 这里的xxx是指不同的平台,可以选填的有x86、mips、armeabi、armeabi-v7a,all等,值得一提的是若选择all会构建出来所有平台的so,如果不填写此项,默认构建为armeabi平台下的库。
- APP_STL := gnustl_static, NDK构建系统提供了由Android系统给出的最小C++运行时库(/system/lib/libstdc++.so)的C++头文件。然后NDK带有另一个C++实现,开发者可以在自己的应用程序中使用或链接它,定义APP_STL可以选择他们中的一个,包括stlport_static、stlport_shared、gnustl_static.
- APP_CPPFLAGS := -std=gnu++11 -fexceptions,指定编译过程中的flag,可以在该选项中开启 exception rtti 等特性,但为了效率,最好关闭rtti。
- NDK_TOOLCHAIN_VERSION = 4.8,指定交叉工具编译链里面的版本号,这里指定使用4.8。
- APP_PLATFORM:= android-9,指定创建的动态库的平台。
- APP_OPTIM := release, 该变量是可选的,用来定义‘release’或者‘debug’,‘release’模式是默认的,并会生成高度优化的二进制代码,’debug‘模式生成的是未优化的二进制代码,但是可以检测出很多的bug,经常用于调试阶段,也相当于在ndk-build指令后面加上参数 NDK-DEBUG=1。
三、实例分析
1. 在上面我们了解了Android.mk里的基本语法规则,那么在输入ndk-build之后,,系统到底会使用哪些编译器以及打包器和链接器来编译我们的程序呢?
答:会使用$NDK_ROOT/toolChains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/ 目录下面的gcc、g++、ar、ld等工具。同样在该目录下的strip工具将会用于清除so包里面的源码,nm工具可以供开发者查看静态库下的符号列表。
2. 那么进行gcc编译的时候,头文件放在哪里呢?
答:$NDK_ROOT/platforms/android-18/arch-arm/usr/include/ 目录下会存放编译过程所依赖的头文件。
3. 链接过程中,经常使用的log或者OpenGL ES等库又将存放在哪里呢?
答:/platforms/android-18/arch-arm/usr/lib 目录下会存放链接过程中所依赖的库文件。
Android NDK学习(二):编译脚本语法Android.mk和Application.mk的更多相关文章
- Android JNI学习(二)——实战JNI之“hello world”
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
- Android NDK 学习之在C中调用Java的变量和静态变量
本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...
- Android NDK 学习之Android.mk
Android.mk file syntax specification Introduction: This document describes the syntax of Android.mk ...
- Android: NDK中的Android.mk和Application.mk
1. 简介 Android.mk 可用来描述要编译的某个具体模块的相关信息.比如:指定编译该模块时所需要的源文件.编译该模块时要链接的库文件.该模块编译完成后生成的库的名字等等.Applicatio ...
- 关于jni编译32位、64位动态库(Android.mk和Application.mk文件)
最近新项目需要编译64位的动态库,这里记录如何配置. 在jni目录下加入Android.mk和Application.mk文件. Application.mk APP_ABI := armeabi a ...
- Android NDK学习(2)Windows下NDK开发环境配置
转:http://www.cnblogs.com/fww330666557/archive/2012/12/14/2817386.html 一.配置好Android开发环境 二.下载安装安卓NDK ...
- Gradle Android它自己的编译脚本教程的最新举措(提供demo源代码)
一.前言 Gradle 是以 Groovy 语言为基础,面向Java应用为主.基于DSL(领域特定语言)语法的自己主动化构建工具. 上面这句话我认为写得非常官方,大家仅仅需知道Gradle能够用来an ...
- Android NDK学习总结
一.android NDK编程步骤 java文件中声明native方法. android工程根目录新建jni文件夹. 调用javah命令为第一步声明的native方法生成相应的.h头文件. 通过win ...
- Android NDK学习(一):目录结构解析
我们配置好NDK环境后,基本可以看到其目录结构如下图: 下面我们来分析一下NDK根目录的结构: ndk-build:该Shell脚本是Android NDK构建系统的起始点,一般在项目中仅仅执行这一个 ...
随机推荐
- JAVA EE 环境配置——JAVA8 下载安装和 Eclipse EE的下载安装
说明:我的电脑是win10 64位操作系统 步骤1:下载Java8 浏览器输入www.oracle.com,点击 Downloads,选择 Java ,选择 Java (JDK) for Develo ...
- Unity 角色移动贴墙行走
直接贴上代码,旋转角色角度检测碰撞 Vector2 v2Normal = new Vector2(normal.x, normal.y); float fAngle = Vector2.SignedA ...
- Go的并发调度原理
Go语言是为并发而生的语言,Go语言是为数不多的在语言层面实现并发的语言:也正是Go语言的并发特性,吸引了全球无数的开发者. 并发(concurrency)和并行(parallellism) 并发 ...
- POJ 2368 Buttons
题目链接:http://poj.org/problem?id=2368 Bash game (巴什博弈):当K是(L+1)的倍数时可以确保second player赢.所以这道题要找的就是在K的因子中 ...
- 【Java】学习笔记(1)
Java数据类型: 基本数据类型:(变量在栈中)数值型:byte(1个字节) short(2个字节) int(四个字节) long(8个字节) ,float(4字节) double(8字节) 字符型: ...
- bugku题目“cookie欺骗”
先上成功截图 题目写的cookie欺骗,但其实是一道考察写脚本能力和代码审计类的题目,首先观察开始的页面 可以看到只有这一串字母,粗略观察可以认为这绝对不是密码,而是胡乱写上的字符,在观察页面源代码后 ...
- python 调用shell hive sql
def generate_csv_source(data_file): #判断文件是否存在 if not os.path.exists(data_file): # 拉取hive表数据 cmd_sql ...
- 今天我给你们推荐一本书《Linux就该这么学》!!!
本书是由全国多名红帽架构师(RHCA)基于最新Linux系统共同编写的高质量Linux技术自学教程,极其适合用于Linux技术入门教程或讲课辅助教材,目前是国内最值得去读的Linux教材,也是最有价值 ...
- python列表和字符串的三种逆序遍历方式
python列表和字符串的三种逆序遍历方式 列表的逆序遍历 a = [1,3,6,8,9] print("通过下标逆序遍历1:") for i in a[::-1]: print( ...
- Python 处理 json
Python在处理json数据中有四个重要的函数:dump,load:dumps,loads. 序列化(dict 包装成 json文件) dump(转储):将字典dic对象 转化为 json文件 AP ...