`
nfer.zhuang
  • 浏览: 61631 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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

 
阅读更多

 

一、说明
上文我们对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文件:
# 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

请注意,这里明确的说明了LOCAL_PATH的定义必须要放在任何include $(CLEAR_VARS)语句之前,如果不这么做的话,编译就直接报错,停止不干了。
 
可是它是怎么判断LOCAL_PATH的定义是在任何include $(CLEAR_VARS)语句之前呢,我们看到有这么一句话:
$(if $(filter $(CLEAR_VARS),$(md_file_))
 这个判断语句是个关键,我们先看看CLEAR_VARS变量的定义
 
三、CLEAR_VARS
在build/core/config.mk中有如下明确的定义:
CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk
BUILD_SYSTEM的定义在build/core/main.mk文件中:
BUILD_SYSTEM := $(TOPDIR)build/core
BUILD_SYSTEM := $(TOPDIR)build/core
紧接着:
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))之前定义
分享到:
评论

相关推荐

    cmake-3.23.1-linux-x86_64.tar.gz

    echo "export PATH=/usr/local/cmake-3.23.1-linux-x86_64/bin:\$PATH" >> ~/.bashrc source ~/.bashrc ``` 这将确保每次启动终端时,CMake的可执行文件都能被找到。 5. **验证安装**:最后,可以通过运行`...

    cmake-3.9.1-linux-x86_64.tar.gz

    2. **移动到适当位置**:为了使CMake可在全球范围内使用,你可能想要将其安装到`/usr/local`目录下。你可以使用`mv`命令将解压后的目录移动至此: ```bash sudo mv cmake-3.9.1-Linux-x86_64 /usr/local/ ``` 3....

    Android Makefile_讲解.doc

    - **LOCAL_PATH**: 此变量用于标识当前Makefile文件所在的目录路径。在Android.mk中通常这样定义: ```make LOCAL_PATH := $(call my-dir) ``` 这行代码通过`my-dir`宏获取当前文件所在的绝对路径,并将其赋值给...

    qtcreator4.4.1.zip

    D'RELATIVE_LIBEXEC_PATH="../libexec/qtcreator"' -D'RELATIVE_DATA_PATH="../share/qtcreator"' -D'RELATIVE_DOC_PATH="../share/doc/qtcreator"' -DIDE_LIBRARY_BASENAME=\"lib\" -DQT_CREATOR -DQT_NO_CAST_TO_...

    blink-led-stm8s103-makefile-master_stm32_labview_blink_

    标题“blink-led-stm8s103-makefile-master_stm32_labview_blink_”涉及了几个关键概念,包括STM8S103微控制器、Makefile、STM32系列芯片以及LabVIEW编程环境。这个项目似乎是一个基于STM8S103的LED闪烁程序,使用了...

    blink-led-stm8s103-makefile-master_stm32_labview_blink_源码.zip

    这个压缩包文件“blink-led-stm8s103-makefile-master_stm32_labview_blink_源码.zip”包含了一个项目,该项目涉及到STM8S103微控制器、Makefile构建系统以及与STM32和LabVIEW相关的LED闪烁程序。我们可以从以下几个...

    u-boot-1.1.6__Makefile.new

    u-boot-1.1.6__Makefile.new

    cmake-3.17.1-Linux-x86_64.tar.gz

    3. **设置环境变量**:添加软链接以将CMake命令添加到PATH环境变量中,如`sudo ln -s /usr/local/cmake-3.17.1/bin/cmake /usr/local/bin/cmake`。 4. **验证安装**:通过运行`cmake --version`来检查CMake是否已...

    shell-and-Makefile.rar_makefile_makefile shell_shell_shell Makef

    通过阅读《跟我一起写Makefile.pdf》和《Linux主要shell命令详解.doc》这两份文档,你可以深入理解并掌握这两个关键工具的使用。这将极大地提高你在Linux开发中的效率和生产力,无论是简单的文件操作还是复杂的项目...

    openjdk-7-fcs-src-b147-27_jun_2011.zip

    2. **钻石操作符(Diamond Operator)**:在创建匿名类或实例化泛型类时,可以使用钻石操作符自动推断类型,简化了代码,如`new ArrayList()`。 3. **尝试-捕获-最后(Try-with-resources)**:Java 7引入了try-...

    makefile-doc.rar_doc_linux makefile_makefile_unix makefile

    本资源包"makefile-doc.rar"专注于讲解`Linux`和`Unix`系统下的`Makefile`编写指南,对于开发者来说是极有价值的参考资料。 `Makefile`的基本结构和语法是它的重要组成部分。在`Linux`和`Unix`环境下,`make`命令...

    cmake-3.9.6-Linux-x86_64.tar.gz

    你可以将这个目录移动到 `/opt` 或其他合适的地方,或者创建符号链接到系统的 PATH 环境变量中,使得在任何地方都可以直接运行 CMake。例如: ``` sudo mv cmake-3.9.6-Linux-x86_64 /opt/ sudo ln -s /opt/cmake...

    Cmake-3.22.0-linux-x86_64安装包

    在`.bashrc`或`.bash_profile`文件中添加一行`export PATH=$PATH:/usr/local/bin`,然后运行`source ~/.bashrc`或`source ~/.bash_profile`使更改生效。 6. **验证安装**:最后,通过运行`cmake --version`来验证...

    cmake-3.25.2-linux-x86_64.tar.gz

    在bash中,可以在`.bashrc`或`.bash_profile`文件中添加类似`export PATH=$PATH:/usr/local/cmake-3.25.2/bin`的行。 4. 检验安装: 安装完成后,运行`cmake --version`来确认CMake已经正确安装并显示版本号。 ...

    Android.mk文档规范

    通过深入理解 Android.mk 文档规范,开发者能够更好地掌握 Android 编译流程的核心概念。 #### 二、基本概念与术语 1. **GNUMakefile**:Android.mk 是 GNUMakefile 的一部分,它由 Android 构建系统解析并执行。 ...

    android编译系统makefile(Android.mk)写法.pdf

    include $(CLEAR_VARS) CLEAR_VARS 由编译系统提供,指定让 GNU MAKEFILE 为你清除除 LOCAL_PATH 以外的所有 LOCAL_XXX 变量,如 LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_SHARED_LIBRARIES,LOCAL_STATIC_LIBRARIES ...

    cmake-3.9.3-Linux-x86_64.tar.gz

    2. 移动或链接到PATH:为了能在命令行中直接调用CMake,你需要将其可执行文件路径添加到系统的PATH环境变量中。一种常见做法是将解压后的`bin`目录链接到`/usr/local/bin`。这可以通过以下命令完成: ``` sudo cp ...

    U-Boot_Makefile-analyse.zip_uboot

    《深入剖析U-Boot Makefile编译机制》 在嵌入式系统开发中,U-Boot作为一款广泛应用的引导加载程序,其构建过程至关重要。本文将深入探讨U-Boot的Makefile,解析其背后的编译逻辑,帮助读者理解并掌握U-Boot的构建...

    gpio-test.rar_ARM Linux GPIO_gpio linux makefile_gpio_test.c_led

    3、#export PATH=$PATH:/usr/local/arm/2.95.3/bin //取决于你宿主机上的交叉编译工具路径 #arm-linux-gcc -o gpio_test gpio_test.c //编译应用程序 最终在你的当前文件夹下会生成gpiodrv.o与gpio_test两个文件。...

    NDK-build-under-ubuntu.rar_Ubuntu!

    在Android开发领域,NDK(Native Development Kit)是一个不可或缺的工具,它允许开发者使用C、C++等原生代码来编写部分应用,以提高性能,尤其是处理图形计算、物理模拟等计算密集型任务时。本资源"NDK-build-under...

Global site tag (gtag.js) - Google Analytics