工作了那么久,都是使用大神们写的脚本机械的编译,对于android.mk根本没去了解过。今天趁着这个机会,在网上搜索了下。虽然依然不是很名白,留做记录,以后真用到了,再深入研究

转载自

http://www.cnblogs.com/wainiwann/p/3837936.html

0. Android.mk简介:

Android.mk文件用来告知NDK Build 系统关于Source的信息。 Android.mk将是GNU Makefile的一部分,且将被Build System解析一次或多次。

所以,请尽量少的在Android.mk中声明变量,也不要假定任何东西不会在解析过程中定义。

Android.mk文件语法允许我们将Source打包成一个"modules". modules可以是:

静态库

动态库。

只有动态库可以被 install/copy到应用程序包(APK). 静态库则可以被链接入动态库。

可以在一个Android.mk中定义一个或多个modules. 也可以将同一份source 加进多个modules.

Build System帮我们处理了很多细节而不需要我们再关心。例如:你不需要在Android.mk中列出头文件和外部依赖文件。

NDK Build System自动帮我们提供这些信息。这也意味着,当用户升级NDK后,你将可以受益于新的toolchain/platform而不必再去修改Android.mk.

1. Android.mk语法:

首先看一个最简单的Android.mk的例子:

LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
 
LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c
 
include $(BUILD_SHARED_LIBRARY)

讲解如下:

LOCAL_PATH := $(call my-dir)

每个Android.mk文件必须以定义LOCAL_PATH为开始。它用于在开发tree中查找源文件。

宏my-dir 则由Build System提供。返回包含Android.mk的目录路径。

include $(CLEAR_VARS)

CLEAR_VARS 变量由Build System提供。并指向一个指定的GNU Makefile,由它负责清理很多LOCAL_xxx.

例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES等等。但不清理LOCAL_PATH.

这个清理动作是必须的,因为所有的编译控制文件由同一个GNU Make解析和执行,其变量是全局的。所以清理后才能避免相互影响。

LOCAL_MODULE    := hello-jni

LOCAL_MODULE模块必须定义,以表示Android.mk中的每一个模块。名字必须唯一且不包含空格。

Build System会自动添加适当的前缀和后缀。例如,foo,要产生动态库,则生成libfoo.so. 但请注意:如果模块名被定为:libfoo.则生成libfoo.so. 不再加前缀。

LOCAL_SRC_FILES := hello-jni.c

LOCAL_SRC_FILES变量必须包含将要打包如模块的C/C++ 源码。

不必列出头文件,build System 会自动帮我们找出依赖文件。

缺省的C++源码的扩展名为.cpp. 也可以修改,通过LOCAL_CPP_EXTENSION。

include $(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY:是Build System提供的一个变量,指向一个GNU Makefile Script。

它负责收集自从上次调用 include $(CLEAR_VARS)  后的所有LOCAL_XXX信息。并决定编译为什么。

BUILD_STATIC_LIBRARY:编译为静态库。
BUILD_SHARED_LIBRARY :编译为动态库
BUILD_EXECUTABLE:编译为Native C可执行程序

2. NDK Build System变量:

NDK Build System 保留以下变量名:

以LOCAL_  为开头的

以PRIVATE_ ,NDK_ 或者APP_ 开头的名字。

小写字母名字:如my-dir

如果想要定义自己在Android.mk中使用的变量名,建议添加 MY_ 前缀。

2.1: NDK提供的变量:

此类GNU Make变量是NDK Build System在解析Android.mk之前就定义好了的。

2.1.1:CLEAR_VARS:

指向一个编译脚本。必须在新模块前包含之。

include $(CLEAR_VARS)

2.1.2:BUILD_SHARED_LIBRARY:

指向一个编译脚本,它收集自从上次调用 include $(CLEAR_VARS)  后的所有LOCAL_XXX信息。

并决定如何将你列出的Source编译成一个动态库。 注意,在包含此文件前,至少应该包含:LOCAL_MODULE and LOCAL_SRC_FILES 例如:

include $(BUILD_SHARED_LIBRARY)      

2.1.3:BUILD_STATIC_LIBRARY:

与前面类似,它也指向一个编译脚本,

收集自从上次调用 include $(CLEAR_VARS)  后的所有LOCAL_XXX信息。

并决定如何将你列出的Source编译成一个静态库。 静态库不能够加入到Project 或者APK中。但它可以用来生成动态库。

LOCAL_STATIC_LIBRARIES and LOCAL_WHOLE_STATIC_LIBRARIES将描述之。    
include $(BUILD_STATIC_LIBRARY) 

2.1.4: BUILD_EXECUTABLE: 
与前面类似,它也指向一个编译脚本,收集自从上次调用 include $(CLEAR_VARS)  后的所有LOCAL_XXX信息。
并决定如何将你列出的Source编译成一个可执行Native程序。
include $(BUILD_EXECUTABLE) 

2.1.5:PREBUILT_SHARED_LIBRARY:
把这个共享库声明为 “一个” 独立的模块。

指向一个build 脚本,用来指定一个预先编译好多动态库。 与BUILD_SHARED_LIBRARY and BUILD_STATIC_LIBRARY不同,

此时模块的LOCAL_SRC_FILES应该被指定为一个预先编译好的动态库,而非source file.  LOCAL_PATH := $(call my-dir)
    
include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt     # 模块名
LOCAL_SRC_FILES := libfoo.so     # 模块的文件路径(相对于 LOCAL_PATH)
    
include $(PREBUILT_SHARED_LIBRARY) # 注意这里不是 BUILD_SHARED_LIBRARY

这个共享库将被拷贝到 $PROJECT/obj/local 和 $PROJECT/libs/<abi> (stripped)  主要是用在将已经编译好的第三方库

使用在本Android Project中。为什么不直接将其COPY到libs/armabi目录呢?因为这样做缺陷很多。下一节再详细说明。

2.1.6: PREBUILT_STATIC_LIBRARY: 预先编译的静态库。 同上。

2.1.7: TARGET_ARCH: 目标CPU架构名。如果为 “arm” 则声称ARM兼容的指令。与CPU架构版本无关。

2.1.8: TARGET_PLATFORM:  目标平台的名字。

2.1.9:TARGET_ARCH_ABI

Name of the target CPU+ABI  
armeabi For ARMv5TE  armeabi-v7a
2.1.10:TARGET_ABI 2.2: NDK提供的功能宏:
GNU Make 提供的功能宏,只有通过类似: $(call function)   的方式来得到其值,它将返回文本化的信息。 2.2.1: my-dir: $(call my-dir):
返回最近一次include的Makefile的路径。通常返回Android.mk所在的路径。它用来作为Android.mk的开头来定义LOCAL_PATH.
LOCAL_PATH := $(call my-dir) 
请注意:返回的是最近一次include的Makefile的路径。所以在Include其它Makefile后,再调用$(call my-dir)会返回其它Android.mk 所在路径。   例如:  
LOCAL_PATH := $(call my-dir)   ... declare one module   include $(LOCAL_PATH)/foo/Android.mk   LOCAL_PATH := $(call my-dir)   ... declare another module
则第二次返回的LOCAL_PATH 为:$PATH/foo。 而非$PATH.   

2.2.2: all-subdir-makefiles:
返回一个列表,包含'my-dir'中所有子目录中的Android.mk。
例如: 结构如下:
sources/foo/Android.mk   sources/foo/lib1/Android.mk   sources/foo/lib2/Android.mk 
在If sources/foo/Android.mk 中, include $(call all-subdir-makefiles)  那则自动include 了sources/foo/lib1/Android.mk and sources/foo/lib2/Android.mk。

2.2.3:this-makefile: 
当前Makefile的路径。

2.2.4:
parent-makefile:
返回include tree中父Makefile 路径。 也就是include 当前Makefile的Makefile Path。 2.2.5:import-module:
允许寻找并inport其它modules到本Android.mk中来。 它会从NDK_MODULE_PATH寻找指定的模块名。
$(call import-module,<name>)
2.3: 模块描述变量: 
此类变量用来给Build System描述模块信息。在'include $(CLEAR_VARS)' 和 'include $(BUILD_XXXXX)'之间。必须定义此类变量。
include $(CLEAR_VARS) script用来清空这些变量。   
include $(BUILD_XXXXX)收集和使用这些变量。    

2.3.1: LOCAL_PATH:  
这个值用来给定当前目录。必须在Android.mk的开是位置定义之。
例如: LOCAL_PATH := $(call my-dir) LOCAL_PATH不会被include $(CLEAR_VARS) 清理。 2.3.2: LOCAL_MODULE: 
modules名。在include $(BUILD_XXXXX)之前,必须定义这个变量。此变量必须唯一且不能有空格。
通常,由此变量名决定最终生成的目标文件名。 2.3.3: LOCAL_MODULE_FILENAME:
可选。用来override LOCAL_MODULE. 即允许用户重新定义最终生成的目标文件名。
LOCAL_MODULE := foo-version-1  LOCAL_MODULE_FILENAME := libfoo
2.3.4:LOCAL_SRC_FILES: 
为Build Modules而提供的Source 文件列表。不需要列出依赖文件。 注意:文件相对于LOCAL_PATH存放,
且可以提供相对路径。 例如:
LOCAL_SRC_FILES := foo.c               \ toto/bar.c
2.3.5: LOCAL_CPP_EXTENSION: 
指出C++ 扩展名。(可选)
LOCAL_CPP_EXTENSION := .cxx 从NDK R7后,可以写多个:  
LOCAL_CPP_EXTENSION := .cxx .cpp .cc      

2.3.6:LOCAL_CPP_FEATURES: 
可选。用来指定C++ features。
LOCAL_CPP_FEATURES := rtti  
LOCAL_CPP_FEATURES := exceptions
2.3.7:LOCAL_C_INCLUDES: 
一个可选的path列表。相对于NDK ROOT 目录。编译时,将会把这些目录附上。
LOCAL_C_INCLUDES := sources/foo  LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo
2.3.8: LOCAL_CFLAGS:
一个可选的设置,在编译C/C++ source 时添加如Flags。
用来附加编译选项。 注意:不要尝试在此处修改编译的优化选项和Debug等级。它会通过您Application.mk中的信息自动指定。
也可以指定include 目录通过:LOCAL_CFLAGS += -I<path>。 这个方法比使用LOCAL_C_INCLUDES要好。因为这样也可以被ndk-debug使用。 2.3.9: LOCAL_CXXFLAGS: 
LOCAL_CPPFLAGS的别名。          
2.3.10: LOCAL_CPPFLAGS:  
C++ Source 编译时添加的C Flags。这些Flags将出现在LOCAL_CFLAGS flags 的后面。 2.3.11: LOCAL_STATIC_LIBRARIES:
要链接到本模块的静态库list。(built with BUILD_STATIC_LIBRARY) 2.3.12: LOCAL_SHARED_LIBRARIES: 
要链接到本模块的动态库。 2.3.13:LOCAL_WHOLE_STATIC_LIBRARIES: 静态库全链接。 不同于LOCAL_STATIC_LIBRARIES,类似于使用--whole-archive 2.3.14:LOCAL_LDLIBS:   linker flags。 可以用它来添加系统库。 如 -lz: 
LOCAL_LDLIBS := -lz   

2.3.15: LOCAL_ALLOW_UNDEFINED_SYMBOLS:      

2.3.16: LOCAL_ARM_MODE:  
缺省模式下,ARM目标代码被编译为thumb模式。每个指令16位。如果指定此变量为:arm。 则指令为32位。
LOCAL_ARM_MODE := arm   其实也可以指定某一个或者某几个文件的ARM指令模式。  
2.3.17: LOCAL_ARM_NEON:   
设置为true时,会讲浮点编译成neon指令。这会极大地加快浮点运算(前提是硬件支持)
只有targeting 为 'armeabi-v7a'时才可以。 2.3.18:LOCAL_DISABLE_NO_EXECUTE: 2.3.19: LOCAL_EXPORT_CFLAGS:
定义这个变量用来记录C/C++编译器标志集合,
并且会被添加到其他任何以LOCAL_STATIC_LIBRARIES和LOCAL_SHARED_LIBRARIES的模块的LOCAL_CFLAGS定义中 
LOCAL_SRC_FILES := foo.c bar.c.arm 

android.mk-编译文件学习(转载)的更多相关文章

  1. NDK(11)Android.mk编译APK模板

    转自 :  http://hubingforever.blog.163.com/blog/static/1710405792011656434982/ 以下仅是使用Android.mk编译APK程序的 ...

  2. Android.mk编译APK范例

    以下仅是使用Android.mk编译APK程序的一些范例. 如果你想了解Android.mk的更多内容请参考<Android.mk简介> 一.编译一个简单的APK    LOCAL_PAT ...

  3. 01 android ndk入门实例之android.mk编译

    前言 1 环境 android studio2.3 , window系统 2 ndk https://dl.google.com/android/repository/android-ndk-r16- ...

  4. Android.mk各种文件编译汇总

    一.源代码编译 1.1 so预编译 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libAppArea LOCAL ...

  5. 安卓之Android.mk多文件以及动态库编译

    1.多文件编译 多文件编译共有两种方式: (1) 在Android.mk中一一添加 LOCAL_PATH:= $(call my-dir) #定义当前模块的相对路径 include $(CLEAR_V ...

  6. Cocos移植到Android-Android.mk编译文件

    我们在上一篇博客中年使用的cocos工具对于C和C++源代码进行编译.事实上cocos工具读取<游戏工程目录>\proj.android\jni\目录中的Android.mk文件,进行交叉 ...

  7. Android.mk编译.apk .so .jar .a第三方.apk .so .jar .a的方法

    一.编译一个简单的APK LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Build all java files in the java s ...

  8. Android.mk编译的写法

    更多Android.mk的 用法见 :http://blog.csdn.net/fengbingchun/article/details/38705519 如何修改Android.mk 为Androi ...

  9. Android.mk编译App源码

    在Andriod源码环境编译APP主要考虑如何引入第三方jar包和arr包的问题,初次尝试,步步是坑,这里给出一个模板: LOCAL_PATH := $(call my-dir) include $( ...

  10. Android NDK开发之Android.mk文件

    Android NDK开发指南---Android.mk文件 博客分类: Android NDK开发指南   Android.mk文件语法详述 介绍: ------------ 这篇文档是用来描述你的 ...

随机推荐

  1. RequestMapping、Responsebody、RequestBody

    预备知识:@RequestMappingRequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径.@RequestM ...

  2. idea里新建maven项目时,在new module页面,一直显示loading archetype list...

    不知道什么时候开始,在idea里新建maven项目时,在new module页面,一直显示loading archetype list....,导致一直没办法新建.后来我以为是防火墙问题,各种设置还是 ...

  3. Convolution & Pooling exercise

    convolution First, we want to compute σ(Wx(r,c) + b) for all valid (r,c) (valid meaning that the ent ...

  4. 963B:Destruction of a Tree

    You are given a tree (a graph with n vertices and n - 1 edges in which it's possible to reach any ve ...

  5. 彻底解决Linux索引节点(inode)占用率高的告警

    今天邮箱里发现有一封某服务器inode使用率发生告警的邮件 登录到服务器上df -i查看,发现/路径下91%,磁盘使用率却不高,猜测可能是某个目录下的小文件过多,进而造成inode占用率过高,但不清楚 ...

  6. [Python] Understand Mutable vs. Immutable objects in Python

    In this lesson, you will learn what mutable and immutable objects are, and the difference between th ...

  7. Justinmind使用教程(5)——Justinmind破解

    今天继续用Justinmind的时候.提示快到期啦. 所以今天学习的课题比較简单了,就是怎样破解Justinmind. 眼下没有无敌的注冊码,大家依照例如以下方式操作一定就解决全部问题了 1.删除两个 ...

  8. onvif开发总结

    ONVIF开发经验总结 ONVIF开发经验总结............................................................................. ...

  9. 量化派基于Hadoop、Spark、Storm的大数据风控架构--转

    原文地址:http://www.csdn.net/article/2015-10-06/2825849 量化派是一家金融大数据公司,为金融机构提供数据服务和技术支持,也通过旗下产品“信用钱包”帮助个人 ...

  10. LAMP环境搭建成功后的部分相关配置

    LAMP环境搭建成功后,通常还需要做一些其他配置来完善,本文主要记录常用到的一些设置. 所有的配置是基于Ubuntu 16.04 + Apache2.4 + Mysql5.7 + Php7.0,对于其 ...