makefile - 如何在 Makefile 工作中使用 foreach 和 eval 函数?
问题描述
我正在尝试了解 AOSP 的 Makefile 语法和 Makefile 系统。但是,像我这样的初学者很难。我了解 fereach 函数的工作原理,但不了解何时与 eval 函数一起使用,如下所示。有人可以解释下面的 Makefile 代码吗?它是如何一步一步工作的以及每一步的输出?变量的最终值all_product_configs
?非常感谢!
all_product_configs := $(call get-product-makefiles,\
$(SRC_TARGET_DIR)/product/AndroidProducts.mk)
这是get-product-makefiles
函数的定义:
define get-product-makefiles
$(sort \
$(foreach f,$(1), \
$(eval PRODUCT_MAKEFILES :=) \
$(eval LOCAL_DIR := $(patsubst %/,%,$(dir $(f)))) \
$(eval include $(f)) \
$(PRODUCT_MAKEFILES) \
) \
$(eval PRODUCT_MAKEFILES :=) \
$(eval LOCAL_DIR :=) \
)
endef
解决方案
eval
接受它的参数并将其评估为 Makefile 语法——变量和规则的定义,以及任何其他 GNUmake 语法——并扩展为空(一个空字符串)
foreach
接受它的第三个参数并为第二个参数中的每个单词重复一次,每次将第一个参数定义为相应的单词。结果是那个(大)字符串。
call
将其第一个参数作为变量的名称,并将该变量扩展为$(1)
,$(2)
等设置为call
因此,从顶部开始,您get-product-makefiles
使用$(1)
set to扩展$(SRC_TARGET_DIR)/product/AndroidProducts.mk
这实际上是 foreach 的第二个参数,并且只有一个单词,因此foreach
将扩展第三个参数一次,$(f)
设置为该字符串 ( $(SRC_TARGET_DIR)/product/AndroidProducts.mk
)。所以这只是
$(eval PRODUCT_MAKEFILES :=) \
$(eval LOCAL_DIR := $(patsubst %/,%,$(dir $(SRC_TARGET_DIR)/product/AndroidProducts.mk))) \
$(eval include $(SRC_TARGET_DIR)/product/AndroidProducts.mk) \
$(PRODUCT_MAKEFILES) \
所以它运行那些定义这些变量(PRODUCT_MAKEFILES
和LOCAL_DIR
)的评估,然后包含另一个makefile(推测定义PRODUCT_MAKEFILES
为非空的东西,可能会附加一些东西)。然后它扩展为任何内容,然后是最后两个eval
命令,清除这两个变量并扩展为空。因此,最终结果将只是$(PRODUCT_MAKEFILES)
AndroidProducts.mk 中定义的任何内容,而该变量本身实际上不再设置。然后它对其进行排序(sort
命令——在排序后偶然删除重复的单词),这就是整个事情的最终结果——这就是all_product_configs
设置的内容。
如果命令中有多个 makefile,这会更有趣call
。然后它最终会读取所有这些并提取它们在 中定义的所有内容PRODUCT_MAKEFILES
,连接并排序该批次。
推荐阅读
- docker - 将 GCP 永久磁盘挂载为 NFS
- mysql - 如何使用 wamp 在本地访问我的 react js 应用程序并允许访问其他计算机?
- r - 循环数据帧以模拟正常的数据分布
- wordpress - WordPress如何重定向私人自定义帖子类型
- java - Java listIterator - 我如何让它只迭代一次?
- kotlin - Swagger 不包含 import kotlinx.serialization.Serializable 到生成的类中
- c++ - UWP 应用程序在使用应用程序包但在本地机器工作时不发送请求
- graphql - 使用 GraphQL 在 react-admin 列表组件中过滤
- java - Hibernate 从存储的函数中获取结果而不使用外键和 SerializationException
- sql - cte 表中的不同值