android.mk ndk编译选项优化,Android NDK 编译脚本分析 之一

版权信息:本文为本人原创,欢迎转载,但请著明出处,并保留本版权信息。

Android NDK编译脚本编写起来还是是比较简单条理的,然而它的语法和传统的linux GNU Make编译脚本的编写似乎有很大的不同,这让习惯了GNU Makefile的用户很不习惯。有许多人会用它,但对其工作原理却不理解,笔者甚至一度误认为那是一套全新脚本语言。我将在后文中对这一编译管理系统做一些分析,试着分析一下它和传统GNU Makefile的关系。

本文假设您已经拥有 Linux命令和GNU Makefile的基础知识,当然您也可以边阅读,边查找参考相关的知识。参考资料2是徐海兵先生整理的 GNU Makefile 中文手册,推荐英文不太好的朋友拿来作为参考。

这篇文章是对自己前段时间所学知识的一个记录整理,以期与大家互相交流,希望朋友们不要吝于来信,指出本文的错漏之处或者你们不同理解(绝非客气,真的期望能收到您的信件,我的邮箱 techres#163.com,请把 # 换成 @)。

====================================================================

Android NDK 的编译脚本系统,实际上并不是什么新东西,就是对 GNU MakeFile 系统的封装。Android NDK 自带了很多 .mk  文件(保存在ndk的 NDK_ROOT/build 目录中),文件中预定义了很多 Make  脚本函数和变量,以供用户编写自己的编译脚本时使用。另外,NDK为所有应用统一提供了一个固定的编译入口--即大家熟悉的ndk-build。

我们首先从每个应用编译时都需要用到的编译入口开始分析。

一、ndk-build分析

(一)、脚本内容分析

该文件存在于ndk安装根目录中,实际上是一个 shell 脚本。其有效内容如下:

PROGDIR=`dirname $0`

PROGDIR=`cd $PROGDIR && pwd`

# If GNUMAKE is defined, check that it points to a valid file

if [ -n "$GNUMAKE" ] ; then

ABS_GNUMAKE=`which $GNUMAKE 2> /dev/null`

if [ $? != 0 ] ; then

echo "ERROR: Your GNUMAKE variable is defined to an invalid name: $GNUMAKE"

echo "Please fix it to point to a valid make executable (e.g. /usr/bin/make)"

exit 1

fi

GNUMAKE="$ABS_GNUMAKE"

else

# Otherwise, use 'make' and check that it is available

GNUMAKE=`which make 2> /dev/null`

if [ $? != 0 ] ; then

echo "ERROR: Cannot find 'make' program. Please install Cygwin make package"

echo "or define the GNUMAKE variable to point to it."

exit 1

fi

fi

# On Windows, when running under cygwin, check that we are

# invoking a cygwin-compatible GNU Make binary. It is unfortunately

# common for app developers to have another non-cygwin compatible

#

if [ "$OSTYPE" = "cygwin" ] ; then

GNUMAKE=`cygpath -u $GNUMAKE`

PROGDIR_MIXED=`cygpath -m $PROGDIR`

CYGWIN_GNUMAKE=`$GNUMAKE -f $PROGDIR_MIXED/build/core/check-cygwin-make.mk 2>&1`

if [ $? != 0 ] ; then

echo "ERROR: You are using a non-Cygwin compatible Make program."

echo "Currently using: `cygpath -m $GNUMAKE`"

echo ""

echo "To solve the issue, follow these steps:"

echo ""

echo "1. Ensure that the Cygwin 'make' package is installed."

echo "   NOTE: You will need GNU Make 3.81 or later!"

echo ""

echo "2. Define the GNUMAKE environment variable to point to it, as in:"

echo ""

echo "     export GNUMAKE=/usr/bin/make"

echo ""

echo "3. Call 'ndk-build' again."

echo ""

exit 1

fi

fi

$GNUMAKE -f $PROGDIR/build/core/build-local.mk "$@"

下面我们对这些有效代码逐一进行分析:

PROGDIR=`dirname $0`

PROGDIR=`cd $PROGDIR && pwd`

在GNU makefile中,两个反引号相当于 shell  函数,反引号括起来的内容相当于 shell 函数的参数。而shell函数的功能就是调用操作系统的命令。

PROGDIR=`dirname $0`

linux 命令 dirname, 功能是获取后面参数的路径。例如:

#dirname ../../../ndk-build

执行的结果是:"../../.."。顺便提一下,这里不能用pwd命令,pwd 命令,是获得当前路径,获取的是当前路径的绝对路径。所以,上面两条语句的结果就是在 PROGDIR 变量中保存 ndk-build 所在的路径。有了这两条语句之后,就可以在任何位置执行 ndk-build ,而不必非要在 ndk 根目录中执行。

再之后的两段语句,是用来确定不同平台下正确的 make 工具。

# If GNUMAKE is defined, check that it points to a valid file

if [ -n "$GNUMAKE" ] ; then

ABS_GNUMAKE=`which $GNUMAKE 2> /dev/null`

if [ $? != 0 ] ; then

echo "ERROR: Your GNUMAKE variable is defined to an invalid name: $GNUMAKE"

echo "Please fix it to point to a valid make executable (e.g. /usr/bin/make)"

exit 1

fi

GNUMAKE="$ABS_GNUMAKE"

else

# Otherwise, use 'make' and check that it is available

GNUMAKE=`which make 2> /dev/null`

if [ $? != 0 ] ; then

echo "ERROR: Cannot find 'make' program. Please install Cygwin make package"

echo "or define the GNUMAKE variable to point to it."

exit 1

fi

fi

# On Windows, when running under cygwin, check that we are

# invoking a cygwin-compatible GNU Make binary. It is unfortunately

# common for app developers to have another non-cygwin compatible

#

if [ "$OSTYPE" = "cygwin" ] ; then

GNUMAKE=`cygpath -u $GNUMAKE`

PROGDIR_MIXED=`cygpath -m $PROGDIR`

CYGWIN_GNUMAKE=`$GNUMAKE -f $PROGDIR_MIXED/build/core/check-cygwin-make.mk 2>&1`

if [ $? != 0 ] ; then

echo "ERROR: You are using a non-Cygwin compatible Make program."

echo "Currently using: `cygpath -m $GNUMAKE`"

echo ""

echo "To solve the issue, follow these steps:"

echo ""

echo "1. Ensure that the Cygwin 'make' package is installed."

echo "   NOTE: You will need GNU Make 3.81 or later!"

echo ""

echo "2. Define the GNUMAKE environment variable to point to it, as in:"

echo ""

echo "     export GNUMAKE=/usr/bin/make"

echo ""

echo "3. Call 'ndk-build' again."

echo ""

exit 1

fi

fi

最后一条语句,是调用:

$GNUMAKE -f $PROGDIR/build/core/build-local.mk "$@"

这是真正开始执行 make ,指定 Makefile 为 build-local.mk 文件。同时,将 ndk-build 的所有参数($@)原封不动地都传递进去。

总之ndk-build 是对 make 指令的封装,并不对各个参数作处理,具体参数原封不动地传给 make 和Makefile。由此可见,ndk-build,只是对make命令的一个封装,为编译提供一个统一的且适应性更强的编译入口。

(二)、技巧

二、 build-local.mk文件分析

=======================================================================================================================

一、Android.mk文件内容分析

典型的 Android.mk 文件一般会包含如下内容:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

下面逐一对之作分析

1、LOCAL_PATH := $(call my-dir)

宏 my-dir 定义在 difinitions.mk 文件中,其功能是获取当前文件所在的路径。

2、include $(CLEAR_VARS)

在文件 build-all.mk 文件中有如下定义:

CLEAR_VARS                := $(BUILD_SYSTEM)/clear-vars.mk

build/core/clear-vars.mk 内容如下:

# this file is included repeatedly from Android.mk files in order to clean

# the module-specific variables from the environment,

NDK_LOCAL_VARS := \

LOCAL_MODULE \

LOCAL_SRC_FILES \

LOCAL_C_INCLUDES \

LOCAL_CFLAGS \

LOCAL_CXXFLAGS \

LOCAL_CPPFLAGS \

LOCAL_LDFLAGS \

LOCAL_LDLIBS \

LOCAL_ARFLAGS \

LOCAL_CPP_EXTENSION \

LOCAL_STATIC_LIBRARIES \

LOCAL_STATIC_WHOLE_LIBRARIES \

LOCAL_SHARED_LIBRARIES \

LOCAL_MAKEFILE \

LOCAL_ALLOW_UNDEFINED_SYMBOLS \

LOCAL_ARM_MODE \

LOCAL_ARM_NEON \

LOCAL_DISABLE_NO_EXECUTE \

$(call clear-src-tags)

$(call clear-vars, $(NDK_LOCAL_VARS))

注释中说得很清楚,该文件的功能就是将一些模块内部的变量的内容清除。最后两条语句是实际的清除操作:

$(call clear-src-tags)

宏 clear-src-tags 没有搜到其定义,不知道其确切功能是什么。不过,从名字来看,应该是对文件名的tags进行清理的。例如编译是为文件名加上的 .neon .arm 等等tags。

最后那条语句是真正清除上面罗列出的这些变量的值。从上面的列表中可以看出,都是一些 LOCAL 变量。【参考资料】

1、GNU Makefile 英文手册:http://www.gnu.org/software/make/manual/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/302614.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

丘成桐:完全不懂数学,才会有“数学无用”的说法

全世界有3.14 % 的人已经关注了数据与算法之美▲中国科学院院长白春礼(右)与数学家丘成桐(左)为晨兴数学金奖获得者李思(中)颁奖培养第一流的学生,首先要有对于学问的兴趣,而非奔着考…

Hadoop 2.0.0-alpha尝鲜安装和hello world

仅供测试学习的文章,不推荐在生产环境使用2.0,因为2.0采用YARN,hive,hbase,mahout等需要map/reduceV1的可能无法使用hadoop 2.0或者会出现意外情况。5月23日,apache发布了hadoop 2.0的测试版。正好跟家呆着…

动手实现一个适用于.NET Core 的诊断工具

前言大家可能对诊断工具并不陌生,从大名鼎鼎的 dotTrace,到 .NET CLI 推出的一系列的高效诊断组件(dotnet trace,dotnet sos,dotnet dump)等, 这些工具提升了对程序Debug的能力和效率,可以让开发人员从更高层次的维度来…

android 强制下线功能,Android学习之基础知识八—Android广播机制实践(实现强制下线功能)...

强制下线功能算是比较常见的了,很多的应用程序都具备这个功能,比如你的QQ号在别处登录了,就会将你强制挤下线。实现强制下线功能的思路比较简单,只需要在界面上弹出一个对话框,让用户无法进行任何操作,必须…

USB权限的设置

USB设备给我们日常生活中带了很多的方便,能够在不同的不同的移动设备中传递数据。但也给我们的数据安全带来了隐患,它可以拷贝走我们计算机中很机密的信息!通过下面的操作后,将使我们有用的信息增加更大安全性,至小也能…

漫谈高数——泰勒级数的物理意义

全世界有3.14 % 的人已经关注了数据与算法之美高等数学干吗要研宄级数问题?是为了把简单的问题弄复杂来表明自己的高深? No,是为了把各种简单的问题/复杂的问题,他们的求解过程用一种通用的方法来表示。提一个问题,99*99等于多少&…

保持学习,从这几个公众号开始!

全世界有3.14 % 的人已经关注了数据与算法之美关注了几百个公众号无目的的看文章却如鸡肋一般食之无味弃之可惜你是否也觉得时间被浪费?生命被辜负了?点击关注下面几个公众号它们每天更新有态度、有温度的原创文字每一篇推文都值得你点开长按二维码&…

IPV6迎来商业元年 运营商短期盈利模式成难点

6月6日,新一代因特网协议IPv6正式上线。据统计,截至4日,中国参加IPv6Launch的网站有65%可在IPv6上存取。 副院长邬贺铨在接受《证券日报》记者采访时表示:“IPV6本身发展过程还有很多问题需要解决,但这不妨碍进行IPV4向…

回顾 | 在 GitHub 上贡献到开源项目

点击蓝字关注我们精彩回顾GitHub 是世界上最大的开源社区,拥有数百万个开源项目。GitHub 的优势之一是在项目上进行协作非常容易。在本研讨会中,我们将介绍在 GitHub 上找到开源项目并为其做出贡献的难易程度。我们将向您展示如何创建拉取请求&#xff0…

html assign无效,Object.assign的一些用法

Object.assign的一些用法2020/11/12 20:19:03  字体:大 中 小 浏览 1289 我要评论需要定制网站程序、公众号程序、微信小程序可以联系:565449214或者加微信13961347334(备注:需要技术)或者在处理一些技术问题时,有什么不懂的地…

R语言和 Python —— 一个错误的分裂

全世界有3.14 % 的人已经关注了数据与算法之美最近有一些文章提出与年龄相关的问题:“崭露头角的年轻数据科学家们是学习R语言还是Python更好?”答案似乎都是“视情况而定”,在现实中没有必要在R和Python中做出选择,因为你两个都用得到。推荐…

.Net之配置文件自定义

前文讲获取配置文件内容的时候,是获取默认的appsettings.json配置文件的配置,下面说明下如何进行自定义配置文件获取1. Json Provider1.1 构建独立的IConfiguration编写方法public static IConfigurationRoot LoadSettings(this IHostEnvironment env){r…

c# 读取大文件方法

/// <summary>/// 读取大文件方法/// </summary>/// <param name"initialPath">原文件绝对地址</param>/// <param name"aimPath">新文件绝对地址</param>private static void CopyFile(string initialPath, string a…

快速修改HTML5,HTML5无刷新修改URL(示例代码)

HTML5新添加了两个api分别是pushState和replaceState&#xff0c;DOM中的window对象通过window.history方法提供了对浏览器历史记录的读取&#xff0c;可以在用户的访问记录中前进和后退&#xff0c;我们可以开始操作这个历史记录堆栈。实例一、通过pushState修改URL通过这句代…

这一平台只要把握住风口期,自己就能当老板!

我是电商珠珠 短视频渐渐走进大家的视野&#xff0c;改变了大家的日常娱乐方式。从19年开始&#xff0c;抖音开始发展电商平台-抖音小店。 在改变大家娱乐方式的同时&#xff0c;还将直播电商的热度掀了起来&#xff0c;由此改变了大家的购物方式&#xff0c;给大家带来了方便…

如何用TensorFlow实现人工智能?

自 2015 年 11 月 9 号发布之后&#xff0c;TensorFlow 逐渐成为人工智能领域最广泛运用的深度学习框架。那么TensorFlow框架到底是什么&#xff1f;TensorFlow 是一个大规模机器学习的开源框架&#xff0c;提供了多种深度神经网络的支持。不仅 Google 在自己的产品线使用 Tens…

一不小心,知乎炸了!

阅读本文大概需要7分钟。昨天晚上加完班发完原创文章&#xff1a;如何成为一个搞垮公司的程序员&#xff1f;就准备回家了&#xff0c;突然发现知乎一堆咨询消息&#xff0c;看了看原来是之前回答的一个问题突然火了&#xff0c;就是这个&#xff1a;好家伙&#xff0c;一天不到…

[转载]Android Layout标签之-viewStub,requestFocus,merge,include

定义Android Layout(XML)时&#xff0c;有四个比较特别的标签是非常重要的&#xff0c;其中有三个是与资源复用有关&#xff0c;分别是<viewStub/>, <requestFocus />, <merge /> and<include />。可是以往我们所接触的案例或者官方文档的例子都没有着…

查询2021抚顺高考成绩,2021年抚顺高考状元是谁分数多少分,历年抚顺高考状元名单...

2020年抚顺一年一度的高考考试已经结束&#xff0c;今年抚顺高考状元是谁呢&#xff0c;抚顺高考状元出自哪个高中学校&#xff0c;文理科分数是多少分&#xff0c;一起来了解。一、2020年抚顺高考状元名单资料2020年抚顺高考状元名单和学校相关信息&#xff0c;截至目前发文时…

面试的一点心得

下班路上&#xff0c;一个武汉的朋友发我一份简历&#xff0c;问这个简历值多少。打开简历&#xff0c;九年工作经验&#xff0c;但只有两个项目经验&#xff0c;看着没啥亮点&#xff0c;建议他根据面试情况综合考虑。正好趁机分享一点自己的面试心得。1、编码能力这是做技术最…