我正在构建一个定制的 Android 系统 (JellyBean)。
我有一个项目(来自上游)包含一个 .tar 文件,该文件应在构建时解压,其内容应复制到生成的目录树中的某个位置。 我应该如何构建 makefile 来执行此操作?
我试过以下方法:
1) 使用 un-tar 指令并使用“PRODUCT_COPY_FILES += ...”编写 Android.mk(在带有 tar 的 git 中)
这不起作用,因为 PRODUCT_COPY_FILES 不能在 Android.mk 中使用
2) 使用解压指令和一些来自 AndroidProducts.mk 的产品定义 mk 文件编写 Android.mk,其中包含“PRODUCT_COPY_FILES += ...”
这不起作用,因为解压发生在“PRODUCT_COPY_FILES += (ls/untared/dir/*)”之后,因此 PRODUCT_COPY_FILES 结果为空。
3) 编写产品定义 mk 文件进行解压,然后“PRODUCT_COPY_FILES += ...”
这行得通但不是很好,因为构建系统在多个地方包含这个文件并且解压发生很多次(~10)这会减慢构建速度并且不是很好......
最佳答案
这可能需要几次迭代。
重述问题:
有一个变量赋值和一个创建文件的规则(通过解压一个 tar 文件)。我们事先不知道这些文件的名称是什么,但我们希望它们在变量中。对变量的赋值(和修改)往往发生在规则之外,因此它们将在规则之前执行。
这里有几种方法。 (如果不更了解您的系统,很难知道哪个是最好的。)
1) 改变初始赋值从
PRODUCT_COPY_FILES := ...
到
PRODUCT_COPY_FILES = ...
有two types of variable in Make : 简单扩展变量和递归扩展变量。 (这与递归调用 makefile 无关。)选择是通过分配 =
或 :=
来确定的。如果你有一个简单的扩展变量,比如
LIST := $(shell ls foo/)
然后它将包含一个列表,其中包含foo/
在赋值时 中的任何文件。如果您执行将文件放入 foo/
的规则,然后执行另一个使用 $(LIST)
的规则,第二条规则将只看到原始文件名。但是,如果您使用递归扩展变量:
LIST = $(shell ls foo/)
然后它将包含 $(shell ls foo/)
。在使用变量之前,这不会被扩展(评估),因此第二条规则将看到所有文件名。
如果将 PRODUCT_COPY_FILES
更改为递归扩展变量,则可以使用
PRODUCT_COPY_FILES += $(shell ls /untared/dir/*)
并且 ls
命令在使用该变量之前不会执行。
2) 使用 tar -t
tar
实用程序允许您获取 tar 文件的内容列表而无需实际解压缩它。
PRODUCT_COPY_FILES += $(shell tar -tf tarfile)
(您可能必须使用一些过滤或其他路径操作来获得您想要的内容。)
3) 递归使用 Make
Recursive use of Make是 Make 执行 Make 时,使用相同或不同的 makefile。
也许 definition.mk
解压 tar 文件,然后调用 android.mk
:
# definition.mk
all:
tar -xvf ...
$(MAKE) -f android.mk
当 android.mk
开始时,文件已经存在于 /untared/dir/
中。
或者,如果您希望 android.mk
成为调用其他 makefile 的主 makefile,您可以简单地交换名称。
关于Android构建系统: How to include prebuilt files from a . tar文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11719253/