转自:http://nfer-zhuang.iteye.com/blog/1752387

  一、说明
上文我们对acp的Android.mk文件做了一个大致的描述,使得大家对Android.mk文件有了一个初步的认识,下面我们就重点分析下第一行: LOCAL_PATH:= $(call my-dir)

 
二、LOCAL_PATH
有人就问了,在本Android.mk中又没有使用到LOCAL_PATH,为什么先 要定义这么一个变量呢?为什么规定必须放在所有的include $(CLEAR_VARS)之前呢?
 
在Android.mk中我们发现有LOCAL_SRC_FILES := acp.的定义,NDK文件中对LOCAL_SRC_FILES 的说明如下:
This is a list of source files that
will be built for your module. Only list the files that will be passed
to a compiler, since the build system automatically computes
dependencies for you.
Note that  source files names are all relative to LOCAL_PATH and you can use path components .
因此在定义LOCAL_SRC_FILES 时已经间接的使用到了LOCAL_PATH变量,即定义LOCAL_SRC_FILES是用的基于当前路径的相对路径。
 
我们接着看看为什么LOCAL_PATH的定义必须要放到所有的include $(CLEAR_VARS)之前。
LOCAL_PATH通过调用my-dir函数来获取当前的路径,my-dir函数的定义位于core/definitions.mk文件:
Makefile代码
<span style="font-size: small;"># Figure out where we are.
define my-dir
$(strip \
$(eval md_file_ := $$(lastword $$(MAKEFILE_LIST))) \
$(if $(filter $(CLEAR_VARS),$(md_file_)), \
$(error LOCAL_PATH must be set before including $$(CLEAR_VARS)) \
, \
$(patsubst %/,%,$(dir $(md_file_))) \
) \
)
endef</span>
请注意,这里明确的说明了LOCAL_PATH的定义必须要放在任何include $(CLEAR_VARS)语句之前,如果不这么做的话,编译就直接报错,停止不干了。
 
可是它是怎么判断LOCAL_PATH的定义是在任何include $(CLEAR_VARS)语句之前呢,我们看到有这么一句话:

Makefile代码

$(if $(filter $(CLEAR_VARS),$(md_file_))  

这个判断语句是个关键,我们先看看CLEAR_VARS变量的定义

 
三、CLEAR_VARS
在build/core/config.mk中有如下明确的定义:

Makefile代码

CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk  
而BUILD_SYSTEM的定义在build/core/main.mk文件中:

BUILD_SYSTEM := $(TOPDIR)build/core

Makefile代码

BUILD_SYSTEM := $(TOPDIR)build/core 
紧接着:

Makefile代码

TOPDIR :=  

即TOPDIR为android源码的根目录, BUILD_SYSTEM= build/core, 所以CLEAR_VARS变量的值就为build/core/clear_vars.mk,当然这个也是相对于Android源码根路径。

得到了CLEAR_VARS变量的值,我们再回到my-dir函数中。
 
四、my-dir
根据gnu make定义,gnu make 会自动将所有读取的makefile路径都会加入到MAKEFILE_LIST变量中,而且是按照读取的先后顺序添加。
 
那么,在运行本makefile文件时,$(MAKEFILE_LIST) 字符串中最后一个makefile肯定是最后读取的makefile,即$(lastword $(MAKEFILE_LIST))则会返回build/tools/acp/Android.mk,此字符串经过$(eval md_file_ := $$(lastword $$(MAKEFILE_LIST))运算,赋值给了临时变量md_file_。
 
判断md_file_中是否包含CLEAR_VARS变量的值$(if $(filter $(CLEAR_VARS),$(md_file_)),肯定也就会返回失败,再通过$(patsubst %/,%,$(dir $(md_file_)))函数,则会得到当前路径,即build/tools/acp
 
如果我们在include $(CLEAR_VARS)之后,再调用my-dir函数,那么$$(lastword $$(MAKEFILE_LIST))肯定就会返回$(BUILD_SYSTEM)/clear_vars.mk,同时,$(patsubst %/,%,$(dir $(md_file_))) 也就会返回$(BUILD_SYSTEM)的值build/core,而不是当前的路径build/tools/acp。
 
这么一来得到的LOCAL_PATH的值就是错误的值,依赖LOCAL_PATH的其他变量也就更加不可能是正确的了!所以说 ,LOCAL_PATH必须要在任何including $(CLEAR_VARS))之前定义

深入浅出Android makefile(2)--LOCAL_PATH(转载)的更多相关文章

  1. 深入浅出Android makefile(1)--初探(转载)

    转载:http://nfer-zhuang.iteye.com/blog/1752368 一.说明 android build system是一个非常庞大的系统,要编译Android工程.修改或新增A ...

  2. android Makefile把jar包打到apk里

    这个是经常的需求,我就是经常忘,关键不理解啊. 反反复复的也看看了android makefile. 太复杂了. 慢慢来吧.哎.工作十年.啥也不会.咋整? ## Copyright (C) 2008 ...

  3. Android makefile编写基础

    首先来看一个简单的Android makefile,这个是我上篇文章写的,重新摘出来: LOCAL_PATH:=$(call my-dir) include $(CLEAR_VARS) LOCAL_M ...

  4. 【转】深入浅出Android Support Annotation

    [转自]http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0427/2797.html http://www.flysnow.org/201 ...

  5. 深入浅出 - Android系统移植与平台开发(一)

    深入浅出 - Android系统移植与平台开发(一) 分类: Android移植2012-09-05 14:16 16173人阅读 评论(12) 收藏 举报 androidgitgooglejdkub ...

  6. Android Makefile中是 如何识别 TARGET_PRODUCT 的

    http://blog.csdn.net/stevenliyong/article/details/5285334 今天有时间小看一下Android 的Makefile, 终于稍有明白Android ...

  7. 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统(瘋耔修改篇二)

    第四章.Android编译系统与定制Android平台系统 4.1Android编译系统 Android的源码由几十万个文件构成,这些文件之间有的相互依赖,有的又相互独立,它们按功能或类型又被放到不同 ...

  8. 深入浅出 - Android系统移植与平台开发(十一)- Android系统的定制(瘋耔修改篇一)

    首先非常感谢原文作者为我们提供的知识库,因为有你们的贡献,我们的开发难度更显简单 原文 :   http://blog.csdn.net/mr_raptor/article/details/30113 ...

  9. Android makefile 组织结构

    下面是main.mk文件包含关系,本文档主要说明的就是这些文件里到底做了什么.(这个文件被根目录下的makefile文件包含) 一.     main.mk BUILD_SYSTEM=build/co ...

随机推荐

  1. 集训第五周 动态规划 B题LIS

      Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Des ...

  2. linux 常见名词及命令(五)

    计划任务服务之一次性任务: at <时间> 安排一次性任务 atq 或at -l 查看任务列表 at -c 序号 预览任务与设置环境 atrm 序号 删除任务 安排任务示例: 在23:30 ...

  3. 【electron系列之一】创建右下角通知栏小图标

    electron 用Tray对象来实现右下角通知栏小图标 一.先引入app, BrowserWindow来实现浏览器功能,接着引入Tray, Menu来实现右下角 二. new Tray('./pag ...

  4. Orcle定时生成表数据作业

    --建表 create table table41( id ) not null, --主键 col1 ), col2 ), col3 ), col4 int, col5 timestamp, col ...

  5. HDOJ 4259 Double Dealing

    找每一位的循环节.求lcm Double Dealing Time Limit: 50000/20000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  6. 戴尔iDRAC服务器远程控制设置

    对于远程的服务器,我们不能经常性的去机房维护,所以远程控制对于服务器来说就显得至关重要.那么你是用什么方式对服务器进行远程控制呢?远程桌面?还是KVM切换器?NO,你OUT了!如果你用的是戴尔的服务器 ...

  7. openstack页面自己定义插件使用具体解释(django、ajax、post)(zTree为例)

    感谢朋友支持本博客,欢迎共同探讨交流.因为能力和时间有限,错误之处在所难免,欢迎指正! 如有转载.请保留源作者博客信息. Better Me的博客:blog.csdn.net/tantexian 如需 ...

  8. HDU 1231——最大连续子序列(DP)

    最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  9. java.io.IOException: read failed, socket might closed or timeout, read ret: -1

    近期项目中连接蓝牙之后接收蓝牙设备发出的指令功能,在连接设备之后,创建RfcommSocket连接时候报java.io.IOException: read failed, socket might c ...

  10. Java内存问题的一些见解

    在Java中,内存泄露和其它内存相关问题在性能和可扩展性方面表现的最为突出.我们有充分的理由去具体地讨论他们. Java内存模型--或者更确切的说垃圾回收器--已经攻克了很多内存问题. 然而同一时候, ...