Android.mk简介

Android mk

NDK构建系统预留了以下的变量,在自定义变量时注意不要跟这些系统变量冲突

  • LOCAL_开头的
  • PRIVATE_, NDK_, APP开头的
  • 小写字母的如my-dir

LOCAL_PATH

每个Android.mk文件必须由LOCAL_PATH开始,用于在development tree中查找源文件

include $(CLEAR_VARS)

CLEAR_VARS指向一个指定的GNU Makefile,并清理许多LOCAL_XXX变量,比如LOCAL_MODULE, LOCAL_SRC_FILES等,它并不清理LOCAL_PATH。因为所有的编译控制文件由同一个GNU Makefile解析和执行,其变量是全局的,所以必须清理后才能避免相互影响

LOCAL_MODULE

每一个模块的名称必须是唯一的且不能包含任何空格。系统在构建shared-library时,会自动加上前缀lib和后缀.so

如果模块名称本身已经是以lib开头,则系统不会再加入前缀,只是会加入后缀

LOCAL_SRC_FILES

指明当前模块的源文件(C/C++文件)
缺省的C++源码的扩展名为.cpp. 也可以修改,通过LOCAL_CPP_EXTENSION修改

BUILD_SAHRED_LIBRARY

该变量指向一个构建脚本并收集所有通过LOCAL_XXX变量指定的关于当前模块的信息,并根据你所列出的源文件构建一个动态库(.so)
使用该变量前,你应该至少定义了LOCAL_MODULELOCAL_SRC_FILES
用法是:

include $(BUILD_SAHRED_LIBRARY)

BUILD_STATIC_LIBRARY

用来构建一个静态库(.a),用法是:

include $(BUILD_STATIC_LIBRARY)

PREBUILT_SHARED_LIBRARY

用来指定一个预先已经编译好的动态库,与BUILD_SAHRED_LIBRARYBUILD_STATIC_LIBRARY不同,该模块对应的LOCAL_SRC_FILES不能是源文件,而只能是一个已经编译好的的动态库的路径,如foo/libfoo.so,用法是:

include $(PREBUILT_SHARED_LIBRARY)

PREBUILT_STATIC_LIBRARY

用来指定一个预先已经编译好的静态库

TARGET_ARCH

指定目标CPU架构,对于大多数兼容ARM指令的构建,通常使用arm,与CPU架构版本无关

TARGET_PLATFORM

指定目标平台的Android API版本号。例如,5.1系统对应的值是:

TARGET_PLATFORM := android-22

TARGET_ARCH_ABI

指定CPU的名称和架构,你可以指定一个或多个值,可取的值有:

  • ARMv5TE -----> armeabi
  • ARMv7 -----> armeabi-v7a
  • ARMv8 AArch64 -----> arm64-v8a
  • i686 -----> x86
  • x86-64 -----> x86-64
  • mips32(r1) -----> mips
  • mips64(r6) -----> mips64
  • All -----> all

TARGET_ABI

连接了Android APIABI两个值,例如:

TARGET_ABI := android-22-arm64-v8a

LOCAL_MODULE_FILENAME

该选项可以重写模块的默认名称,例如:

LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo

系统最终会生成libnewfoo.so

LOCAL_SRC_FILES

包含了构建该模块的源文件列表。可以使用相对路径也可以使用绝对路径,不过最好不要使用绝对路径而使用相对路径,这样可以方便移植

LOCAL_CPP_EXTENSION

指出C++源文件的扩展名(可选)

LOCAL_CPP_FEATURES

该变量指明当前模块所依赖的C++特性(可选)
推荐使用该变量代替在LOCAL_CPPFLAGS选项中传入-frtti-fexception
使用该变量允许系统对于每个模块各自使用合适的flag,而使用LOCAL_CPPFLAGS则会导致编译器给所有模块都使用传入的flags

LOCAL_CPP_FEATURES := rtti --> (use Runtime Type Information)

LOCAL_CPP_FEATURES := exceptions --> (use C++ exceptions)

LOCAL_C_INCLUDES

指明编译时的include路径列表,相对于NDK ROOT目录 (可选)

LOCAL_CFLAGS

指明在编译C/C++时要添加的flags(可选)

注意:不要在这改变优化选项和调试等级,这些选项应该在Application.mk中自动指定

也可以指定include目录:

LOCAL_CFLAGS += -I<path>

这个方法比LOCAL_C_INCLUDES要好一些,因为可以被ndk-gdb所使用

LOCAL_CXXFLAGS

LOCAL_CPPFLAGS的别名

LOCAL_CPPFLAGS

指明编译C++代码时的flags(可选),这些选项在编译器的命令行中会跟在LOCAL_CFLAGS后面

LOCAL_STATIC_LIBRARIES

指明编译模块时需要的静态库列表
如果当前模块是动态库或可执行文件,该变量会告诉编译器将该变量列出的静态库连接到最终的二进制文件上
如果当前模块一个静态库,该变量只是简单的指明其他依赖当前模块的库同时也依赖该变量声明的这些库

LOCAL_SHARED_LIBRARIES

列出当前模块在runtime时依赖的动态库

LOCAL_WHOLE_STATIC_LIBRARIES

静态库全链接,不同于LOCAL_STATIC_LIBRARIES,类似于使用--whole-archive

LOCAL_LDLIBS

该变量包含了在编译动态库或可执行文件时的附加连接选项列表。它允许你使用-l前缀来传递指定的系统库,例如:

LOCAL_LDLIBS := -lz

上面的代码告诉编译器在编译模块时还要连接/system/lib/libz.so

LOCAL_ALLOW_UNDEFIEND_SYMBOLS

默认情况下,系统在编译动态库时遇到undefined reference错误时,会抛出undefined symbol error
如果将该变量设为true,则会关闭undefined reference检查

如果你在编译静态库时指定该变量,系统会忽略该变量

LOCAL_ARM_MODE

默认情况下,系统产生的二进制文件是thumb模式,每个指令是16位,并且连接这/thumbSTL libraries。通过将该变量设为arm,可以让产生的指令变为32位,例如:

LOCAL_ARM_MODE := arm

也可以将某一个源文件以.arm结尾以此来指定该文件要被编译成arm模式,例如:

LOCAL_SRC_FILES := foo.c bar.c.arm

注意:也可以在Application.mk中指定APP_OPTIM := debug来达到同样的目的

LOCAL_ARM_NEON

该变量只有在将ABI指定为armeabi-v7a时才有效。设置为true时,会讲浮点编译成neon指令,这会极大地加快浮点运算(前提是硬件支持)
同时,也可以将某一个源文件以.neon结尾来指定该源文件支持neon,例如:

LOCAL_SRC_FILES := foo.c.neon bar.c zoo.c.arm.neon

上面的代码指明了zoo.c设为arm模式同时支持neon

LOCAL_DISABLE_NO_EXECUTE

Android NDK r4添加了NX bit安全特性,该选项默认是开启的,如果要关闭,可以将LOCAL_DISABLE_NO_EXECUTE这个变量设为true
该变量并不改变ABI,同时只在ARMv6+ CPU的设备开启

LOCAL_DISABLE_RELRO

默认情况下, NDK在编译代码时会加入read-only relocationsGOT protection
该变量指明runtime linkerrelocation之后确保内存为read-only,同时确保security exploit更为困难。

这些保护只在Android API 16及以上才起作用

将这个变量LOCAL_DISABLE_RELRO设为true,可以将上述机制关闭

LOCAL_DISABLE_FORMAT_STRING_CHECKS

默认情况下, 系统在编译时会进行string格式的检查。这个检查默认是开启的,不过可以将LOCAL_DISABLE_FORMAT_STRING_CHECKS这个变量设为true来取消这个检查

LOCAL_EXPORT_CFLAGS

在该变量中声明的所有flags都会添加到在那些以LOCAL_STATIC_LIBRARIES或者LOCAL_SHARED_LIBRARIES声明依赖当前静态库或动态库的模块的LOCAL_CFLAGS中,例如:

include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_CFLAGS := -DFOO=1
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_CFLGAS := -DBAR=2
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SAHRED_LIBRARY)

这里,系统会将-DFOO=1-DBAR=2都传入给bar.c
另外,所有依赖关系都是传递的,如果zoo依赖bar,而bar又依赖foo,则zoo同样继承了foo模块的所有exported flags
系统并不会传递exported flags给当前模块,举例来说,-DFOO=1并不会传递给foo

LOCAL_EXPORT_CPPFLAGS

作用同LOCAL_EXPORT_CFLAGS,只是针对C++

LOCAL_EXPORT_C_INCLUDES

导出include paths,例如,该变量会告诉bar.c应该包含foo模块的头文件

LOCAL_EXPORT_LDFLAGS

该变量作用同LOCAL_EXPORT_CFLAGS,只不过是针对linker flags

LOCAL_EXPORT_LDLIBS

该变量告诉系统传递指定的的系统库给编译器,系统会添加导入的的连接属性给LOCAL_LDLIBS,例如:

include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)

系统会在编译libbar.so时将-llog放在连接命令行末端

LOCAL_SHORT_COMMANDS

当你的模块中有大量源文件或依赖库时,可以将此变量设为true,之后系统会使用@语法来直接包含对象文件或二进制文件,这个特性在Windows会有用,也可以在Application.mk中定义APP_SHORT_COMMANDS来为每个模块开启这一属性

LOCAL_THIN_ARCHIVE

构建静态库时,可以将此变量设为true,系统会产生一个'瘦身了的archive文件',在该库文件中并不包含对象文件,而只是包含每个对象文件对应的路径

my-dir

这个宏返回最后一个makefile的路径,一般都是当前Android.mk的路径,这个宏一般用来在Android.mk开头定义LOCAL_PATH变量,例如:

LOCAL_PATH := $(call my-dir)

all-subdir-makefiles

返回当前my-dir路径下所有子目录的所有Android.mk

this-makefile

返回当前makefile的路径

parent-makefile

返回包含当前makefile的父makefile的路径

grand-parent-makefile

返回包含当前makefile的祖父makefile的路径

import-module

可以用来包含一个指定模块的Android.mk,用法是:

$(call import-module,<name>)

使用Prebuilt Libraries

你必须声明每个prebuilt library作为一个独立的模块,步骤为以下几步:

  1. 定义一个模块名称,该名称不必同prebuilt library本身的名字一致
  2. Android.mk中,将LOCAL_SRC_FILES置为prebuilt library的路径
  3. include PREBUILT_SHARED_LIBRARY or PREBUILT_STATIC_LIBRARY

例子:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.so
include $(PREBUILD_SHARED_LIBRARY)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容