Application.mk语法解释(转)
转自:http://blog.csdn.net/roland_sun/article/details/46318893
Application.mk是用来描述你的应用程序需要哪些模块,以及这些模块所要具有的一些特性。而相对的Android.mk是用来描述要编译某个具体的模块,所需要的一些资源,包括要编译的源码、要链接的库等等。
Application.mk所要描述的内容主要包括:
1)你程序正常运行,所需要到模块的具体列表;
2)程序要编译成什么机器指令集的;
3)所有模块要被编译成Release版本还是Debug版本的;
4)传递给C或者C++编译器的编译参数。
Application.mk文件一般是放在$PROJECT/jni/目录下的($PROJECT代表你所写程序的项目目录),这样ndk-build命令可以自动搜索到它。
当然,Application.mk文件其实是可选的。默认情况下,如果ndk-build命令找不到Application.mk文件的话,就会使用如下规则进行编译:
1)会编译全部在Android.mk文件中列出的模块;
2)对于所有模块,NDK编译系统会根据“armeabi” ABI来生成机器代码,即指令集是ARMv5TE。
具体来说,Application.mk文件中,可以包含对下面几个变量的定义:
APP_PROJECT_PATH
这个变量会告诉编译系统,你应用程序项目的根目录的绝对路径。
一般编译出来的Native模块是要被打包成某个APK应用程序的。而APK打包工具都是在项目根目录下的某个特定子目录中搜索有没有要打包的.so文件的,所以指定了项目根目录的绝对路径后,ndk-build命令在完成编译后,会将编译好的.so模块文件拷贝到项目的特定子目录下,方便后面打包。
如果你的项目目录的组织形式是类似于$PROJECT/jni/Application.mk,则这个变量是可选的。
APP_MODULES
这个变量是可选的。如果APP_MODULES变量没有被定义的话,NDK将编译在Android.mk文件中定义的所有模块,以及所有其包含的子MakeFile文件。
如果APP_MODULES变量被定义了的话,则NDK只会编译明确列出的这几个模块。
注意,所有模块的名字要以空格分割,并且NDK会自动计算每个模块之间的依赖关系。
另外,从NDK r4开始改变了这个变量的行为。再这个版本之前Application.mk中必须定义这个变量(即其是强制的),并且必须明确列出所有模块的名字列表。而在这个版本之后,取消了这个限制。
APP_OPTIM
这个变量是可选的,可以被定义成“release”或"debug",用来告诉NDK将所有的模块编译成Release版本还是Debug版本。
如果这个变量被定义成“release”的话,则NDK会将所有模块编译成Release版本的,也就是会对代码进行深度优化,并且去除所有调试信息。这样的结果就是,编译出的代码执行效率高且文件比较小,但不利于调试。
如果这个变量被定义成“debug”的话,则NDK会将所有模块编译成Debug版本的,和Release版本相反,不会对代码进行任何优化,并且会加上很多调试信息。这样的结果就是,编译出的代码执行效率比较低且文件相对较大,但调试起来很方便。
如果没有特别指定这个变量,则NDK会自动查看你的应用程序是否是可调试的(即查看你项目目录下的AndroidManifest.xml文件,看是否在<application>标签中是否将android:debuggable属性设置成了"true")来决定到底编译Release版本还是Debug版本的。
但是,如果你定义了这个变量的话,则以这个变量定义的情况为准。无论你的应用程序是否是可调试的,都不会产生影响。
APP_CFLAGS
如果想在编译所有模块的C或者C++源码时,都需要指定一些特殊的编译选项的话,可以通过定义这个变量实现。
在Android.mk文件中,也可以分别为每个模块指定特定于这个模块的编译选项。但是,如果在Application.mk文件中定义了这个变量的话,其作用域是所有模块,而不是某个特定的模块。
比如,你要编译的某几个模块,如果都需要在一个特定目录下搜索头文件定义的话,你可以有两种做法。一是修改各个模块的Android.mk文件,为每个模块都定义LOCAL_CFLAGS变量,包含那个目录;二是只修改应用程序的Application.mk文件,定义APP_CFLAGS变量,包含那个目录。
注意,在Android NDK 1.5 r1版中,这个变量只会对编译C源文件起作用,而对编译C++源文件没有任何影响。这个问题已经在后面的NDK版本中得到了纠正。
APP_CPPFLAGS
和前面说明的APP_CFLAGS变量类似,它也是用来指定一些特殊的编译选项,但只对编译C++源文件其作用。
注意,在Android NDK 1.5 r1版本中,这个变量不仅对C源文件的编译,而且对C++源文件的编译都会起作用。这个问题已经在后面的NDK版本中得到了纠正。
现在,如果想对编译C和C++源文件都指定相同的编译选项,可以使用前面介绍的APP_CFLAGS变量。
APP_CXXFLAGS
它是APP_CPPFLAGS变量的一个别名,但它已经过时了,在未来的NDK版本中有可能不再使用。因此,建议尽量不要使用它,而是使用APP_CPPFLAGS变量。
APP_BUILD_SCRIPT
默认情况下,NDK编译系统会自动在$(APP_PROJECT_PATH)/jni目录下寻找名为Android.mk文件,作为模块定义文件。
如果你的Android.mk文件被放到别的位置的话,或者甚至你的模块定义文件不叫Android.mk,则可以通过修改这个变量的值,来让NDK使用你指定的模块定义文件。
注意,一个非绝对路径,总是会被解释为相对于NDK顶层目录的路径。
APP_ABI
默认情况下,NDK编译系统会根据“armeabi” ABI来生成机器代码,即一个使用ARMv5TE指令集并且支持软件浮点操作的CPU。
你可以通过定义APP_ABI变量来选择一个不同的ABI。
比如,如果你的程序想在使用ARMv7指令集,且支持硬件FPU的设备上运行,可以使用:
- APP_ABI := armeabi-v7a
或者你的程序想支持IA-32指令集,可以使用:
- APP_ABI := x86
或者你的程序想支持MIPS指令集,可以使用:
- APP_ABI := mips
或者,想同时支持这四种平台,可以使用:
- APP_ABI := armeabi armeabi-v7a x86 mips
当然,你也可以使用任意某几个ABI,只要每个ABI之间用空格隔开即可。
或者,如果你使用NDK r7以上版本的话,还可以使用“all”来表示支持所有ABI平台:
- APP_ABI := all
APP_STL
默认情况下,NDK编译系统只为最小的C++运行时库(/system/lib/libstdc++.so)提供C++头文件。
然而,NDK还带有其它一些可选的C++运行时库的实现,你可以选择在你自己的应用程序中,通过在Application.mk中定义APP_STL变量,来使用或链接其中某一个。
这个变量可以被设置成如下几个值:
1)system
2)gabi++_static
3)gabi++_shared
4)stlport_static
5)stlport_shared
6)gnustl_static
7)gnustl_shared
如果不特别定义的话,“system”运行时库是默认的值。除此之外,凡是后面带“_static”的,表示其是一个静态链接的运行时库(运行时库的代码包含在编译后的程序中);而凡是后面带“_shared”的,表示其是一个动态链接的运行时库(运行时库在程序运行时被动态加载进来)。如果去除动态或静态链接的因素,则除了默认的“system”运行时库之外,还有所谓的“gabi++”运行时库、“stlport”运行时库和“gunstl”运行时库。这四种运行时库所支持的C++特性各不相同,总结如下表:
C++异常 | C++ RTTI | C++标准库 | |
---|---|---|---|
System | 不支持 | 不支持 | 不支持 |
gabi++ | 不支持 | 支持 | 不支持 |
stlport | 不支持 | 支持 | 支持 |
gnustl | 支持 | 支持 | 支持 |
可以看出,如果想支持C++异常的话,必须要使用gunstl运行时库。
APP_GNUSTL_FORCE_CPP_FEATURES
在NDK r7b之前的版本中,如果指定使用了gnustl运行时库,则默认在编译之后的代码中,都会加上对C++异常和C++ RTTI的支持代码。
这样做有可能会造成一定的问题。并且即使你的程序没有使用C++异常和C++ RTTI这些特性,支持它们的代码还是会加到你的模块中去,这样会大大增加模块的大小。
这个问题已经在NDK r7b及以后的版本中被修复了。不过,这样也就意味着,如果你真的需要使用C++异常或C++ RTTI特性的话,必须明确的告知NDK编译系统(可以通过在Application.mk中定义APP_CPPFLAGS变量,或在Android.mk中定义LOCAL_CPPFLAGS或LOCAL_CPP_FEATURES变量来告知)。
但是,这样带来的问题就是兼容性问题,同一个编译脚本要根据不同的NDK版本来做区分操作。
为了让这种过度更加的顺畅,可以在Application.mk文件中定义APP_GNUSTL_CPP_FEATURES变量来指定到底要支持哪些C++的特性。
这个变量可以被设置成如下两个值:
1)exceptions:表示编译后的代码要支持C++异常特性;
2)rtti:表示编译后的代码要支持C++ RTTI特性。
例如,如果你想让你的程序既获得C++异常的支持,也得到C++ RTTI的支持,可以使用:
- APP_GNUSTL_FORCE_CPP_FEATURES := exceptions rtti
Application.mk语法解释(转)的更多相关文章
- 【转】Application.mk 文件语法规范
原文网址:http://blog.sina.com.cn/s/blog_4c451e0e0100s6q4.html Application.mk file syntax specification A ...
- Android NDK学习(二):编译脚本语法Android.mk和Application.mk
一.Android.mk Android.mk分为一下几部分: LOCAL_PATH:= $(call my-dir), 返回当前文件在系统中的路径,Android.mk文件开始时必须定义该变量. i ...
- Android NDK开发指南---Application.mk文件和android.mk文件
https://android.googlesource.com/platform/development/+/donut-release/ndk/docs/OVERVIEW.TXT https:// ...
- Android NDK开发指南(一) Application.mk文件
http://www.cnblogs.com/yaozhongxiao/archive/2012/03/06/2381586.html Application.mk目的是描述在你的应用程序中所需要的模 ...
- 关于jni编译32位、64位动态库(Android.mk和Application.mk文件)
最近新项目需要编译64位的动态库,这里记录如何配置. 在jni目录下加入Android.mk和Application.mk文件. Application.mk APP_ABI := armeabi a ...
- NDK(9)Application.mk各属性介绍
本文参考 : http://blog.csdn.net/grimraider/article/details/7587816 在NDK中编写的是本地程序,这个程序的源码在 jni 下,这个本地项目的配 ...
- NDK开发之Application.mk文件详解
做过NDK开发的同学应该都知道有个Application.mk文件,这是android NDK构建系统使用的一个可选构建文件.它的目的是描述应用程序需要哪些模块,也定义了所有模块的一些通用变量.主要有 ...
- Application.mk中APP_ABI 的含义
我们在编写JNI代码时有一个可选的文件Application.mk ,这个文件你可以不创建,但是有时候是有必要写一个这样的文件的. Application.mk文件用于描述应用程序本身的一些属性信息, ...
- Android NDK Application.mk(中文翻译)
作者:阿宝 更新:2016-08-31 来源:彩色世界(https://blog.hz601.org/2016/07/26/android-NDK-application-mk/index.html) ...
随机推荐
- Oracle之分页问题
前面的Top-N问题使用了reownum,但是又遇到个分页问题,将表emp的4行为1页输出,前4行很好做: select rownum,empno,ename,sal from emp ; 但是4-- ...
- Sass--嵌套选择器
Sass 中还提供了选择器嵌套功能,但这也并不意味着你在 Sass 中的嵌套是无节制的,因为你嵌套的层级越深,编译出来的 CSS 代码的选择器层级将越深,这往往是大家不愿意看到的一点.这个特性现在正被 ...
- tomcat-性能优化参考
转摘 http://blog.csdn.net/lifetragedy/article/details/7708724. ###jdk1.6.未验证.仅供参考### linux环境下Tomcat调优 ...
- HTML+CSS+JS是什么
html:整合网页结构和内容显示的一种语言 css:是一种用来表现HTML或XML等文件样式的计算机语言 js:增加表现力的脚本 做网页前台设计的标准套装,html是一些网页控件,css是美化这些控件 ...
- 21.Semaphore信号量
Semaphore是一种基于计数的信号量.它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞.Semaphore可以用来构建一些对象池,资 ...
- python3.x filter,map,reduce浅析
#map用法: #传递函数api进入map去执行,把字符串第一个字母变大写, #其他变小写返回 def format_name(s): s=s.lower() print(s) return s[0] ...
- SQL 左连接
SQL左链接LEFT JOIN关键字返回左表(表1)中的所有行,即使在右表(表2)中没有匹配.如果在正确的表中没有匹配,结果是NULL. SQL LEFT JOIN 语法 SELECT _column ...
- Linux安装系统
服务器与PC 服务器本质上也是以太计算机,相比较家用电脑而言区别如下: 1.服务器更加稳定 2.通常性能比家用机更高 运维工程师的核心职责 保证服务器不间断运行 提升访问效率 保证数据安全 要完成上面 ...
- docker监控方案实践(cadvisor+influxdb+grafana)
一.概要 1.1 背景 虚拟化技术如今已经非常热门,如果你不知道什么是虚拟化,那你应该了解虚拟机.虚拟化技术如同虚拟机一样,用于将某些硬件通过软件方式实现"复制",虚拟出" ...
- Java虚拟机解析篇之---垃圾回收器
上一篇说了虚拟机的内存模型,在说到堆内存的时候我们提到了,堆内存是Java内存中区域最大的一部分,而且垃圾回收器主要就是回收这部分的内容.那么这篇就来介绍一下垃圾回收器的原理以及回收的算法. Java ...