• 深入浅出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))之前定义
  • 相关阅读:
    C#开发微信门户及应用(18)-微信企业号的通讯录管理开发之成员管理
    C#开发微信门户及应用(17)-微信企业号的通讯录管理开发之部门管理
    C#开发微信门户及应用(16)-微信企业号的配置和使用
    C#开发微信门户及应用(15)-微信菜单增加扫一扫、发图片、发地理位置功能
    会员管理系统的设计和开发(3)--主界面的设计思路分享
    会员管理系统的设计和开发(2)-- RDLC报表的设计及动态加载
    Winform开发中常见界面的DevExpress处理操作
    在WCF数据访问中使用缓存提高Winform字段中文显示速度
    双指针算法模板和一些题目
    尾递归 递归函数中,递归调用是整个函数体中最后的语句,且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归,空间复杂度是O(1)
  • 原文地址:https://www.cnblogs.com/lance-ehf/p/4184596.html
Copyright © 2020-2023  润新知