1

我正在构建一个定制的 Android 系统(JellyBean)。

我有一个项目(来自上游),其中包含一个 .tar 文件,该文件应在构建时解压缩,其内容应复制到生成的目录树中的某个位置。我应该如何构建makefile来做到这一点?

我尝试了以下方法:

1) 使用 un-tar 指令并使用“PRODUCT_COPY_FILES += ...”编写 Android.mk(在带有 tar 的 git 中)

这不起作用,因为 PRODUCT_COPY_FILES 不能在 Android.mk 中使用

2) 使用 untar 指令和 AndroidProducts.mk 中包含的一些产品定义 mk 文件编写 Android.mk,其中包含“PRODUCT_COPY_FILES += ...”

这不起作用,因为解压缩发生在 "PRODUCT_COPY_FILES += (ls /untared/dir/*)" 之后,因此 PRODUCT_COPY_FILES 结果为空。

3) 编写产品定义 mk 文件进行解压缩,然后 "PRODUCT_COPY_FILES += ..."

这行得通,但不是很好,因为构建系统在多个位置包含此文件,并且 untar 发生了很多次(~10),这会减慢构建速度并且不好......

4

1 回答 1

5

这可能需要几次迭代。

重申问题:

有一个对变量的赋值,以及一个创建文件的规则(通过解压缩 tar 文件)。我们事先不知道这些文件的名称是什么,但我们希望它们在变量中。对变量的赋值(和修改)往往发生在规则之外,因此它们将在规则之前执行。

这里有几种方法。(如果不深入了解您的系统,很难知道哪个是最好的。)

1) 将初始分配

PRODUCT_COPY_FILES := ...

PRODUCT_COPY_FILES = ...

Make中有两种类型的变量简单扩展变量和递归扩展变量。(这与递归调用 makefile 无关。)选择是通过使用=or分配来确定的:=。如果您有一个简单的扩展变量,例如

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

Make 的递归使用是当 Make 使用相同的 makefile 或不同的 makefile 执行 Make 时。

也许definition.mk解压缩 tar 文件,然后调用android.mk

# definition.mk

all:
    tar -xvf ...
    $(MAKE) -f android.mk

开始时android.mk,文件已经存在于/untared/dir/.

或者,如果您想android.mk成为调用其他 makefile 的主 makefile,您可以简单地交换名称。

于 2012-07-30T15:20:55.280 回答