深入浅出Android makefile(2)--LOCAL_PATH(转载)

  转自: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))之前定义

时间: 2024-10-09 17:07:37

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

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

转载:http://nfer-zhuang.iteye.com/blog/1752368 一.说明 android build system是一个非常庞大的系统,要编译Android工程.修改或新增Android模块都需要对这个编译系统有一定的了解.但是由于它实在是太庞大了,大家往往是不知道从哪里切入进去,对Android的编译系统进行一个系统的学习. 下面我们尝试从一个小模块逐步对android build system做一个深入剖析.选择的这个模块名字叫做acp ,源码位于build\too

android Makefile把jar包打到apk里

这个是经常的需求,我就是经常忘,关键不理解啊. 反反复复的也看看了android makefile. 太复杂了. 慢慢来吧.哎.工作十年.啥也不会.咋整? ## Copyright (C) 2008 The Android Open Source Project## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance

【转】深入浅出Android Support Annotation

[转自]http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0427/2797.html 英文链接:http://anupcowkur.com/posts/a-look-at-android-support-annotations/ 译文链接 深入浅出Android Support Annotations 导读:如果你之前遇到过在方法参数前面有@NonNull的情况却不知道它是干什么的,这篇文章将解答你的疑问. 原文如下: 在Androi

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

深入浅出 - Android系统移植与平台开发(一) 分类: Android移植2012-09-05 14:16 16173人阅读 评论(12) 收藏 举报 androidgitgooglejdkubuntu 目录(?)[+] +-------------------------------------------------+ +      本系列为连载,不定期会更新       + +-------------------------------------------------+ 一.A

深入浅出Android Gradle构建系统(三:build task)

接上一篇  深入浅出Android Gradle构建系统(二:项目结构) 构建任务(Build Tasks) java和Android通用的任务 在build文件中使用了Android或者Java插件之后就会自动创建一系列可以运行的任务. Gradle中有如下一下默认约定的任务: 1. assemble 该任务包含了项目中的所有打包相关的任务,比如java项目中打的jar包,Android项目中打的apk 2. check 该任务包含了项目中所有验证相关的任务,比如运行测试的任务 3. buil

Android Makefile中是 如何识别 TARGET_PRODUCT 的

http://blog.csdn.net/stevenliyong/article/details/5285334 今天有时间小看一下Android 的Makefile, 终于稍有明白Android 编译系统是如何通过环境变量 TARGET_PRODUCT 来决定编译定制product. 首先, 编译Android 代码 通常情况下使用: # make showcommands 这实际上等价于下面的完整命令 (具体参见 build/core/envsetup.mk ) # TARGET_ARCH

Android 设计原则【转载】

原文地址 本文内容 吸引我的眼球 简化我的生活 让我眼前一亮 在使用过大量 Android APP 后,你会发现,遵循了下面这些原则的 APP 将会有更好的用户体验. 我们知道,往往国企的那些软件,都很难用,比如银行手机客户端,操作繁杂.界面难看.功能有限--基本上,那就是糊弄领导的东西,完全不是给用户用的,农业银行手机客户端,在我所用过的所有银行手机客户端中算是不错的了(而且,转账没有手续费),操作有点不便,尤其是"返回"操作,有种"不知身在何处"的感觉:而建设银

如何使用JS来检测游览器是什么类型,或android是什么版本号- 转载

var brower = { versions:function(){ var u = window.navigator.userAgent; var num ; if(u.indexOf('Trident') > -1){ //IE return "IE"; }else if(u.indexOf('Presto') > -1){ //opera return "Opera"; }else if(u.indexOf('Gecko') > -1 &a

深入浅出 - Android系统移植与平台开发(十一)- Android系统的定制【转】

本文转载自: 4.3定制Android平台系统 通常产品厂商在拿到Android源码后会在android源码基础上进行定制修改,以匹配适应自己的产品,从本节开始,我们从最原始的Android源码系统里一步一步定制出自己的Android系统.本节主要内容包含:根据Android源码,添加新产品编译项,定制系统启动界面和文字,定制系统启动动画和声音,定制系统桌面. 4.3.1 添加新产品编译项 Android系统的源代码是一个逻辑结构非常独立工程,在一套Android源码中可以编译出多个产品映像,在