Reputation: 2972
I'm building a customized Android system (JellyBean).
I've got a project (from the upstream) containing a .tar file which should be untar'd at the build time and it's content should be copied to a certain place in the resulting directory tree. How should I build the makefiles to do it?
I've tried the following:
1) Writing Android.mk (in the git with the tar) with un-tar instruction and using "PRODUCT_COPY_FILES += ..."
This doesn't work, because PRODUCT_COPY_FILES cannot be used in the Android.mk
2) Writing Android.mk with untar instructions and some product definition mk file included from AndroidProducts.mk, containing "PRODUCT_COPY_FILES += ..."
This doesn't work, because untar happens AFTER "PRODUCT_COPY_FILES += (ls /untared/dir/*)" and thus PRODUCT_COPY_FILES results empty.
3) Writing product definition mk file doing untar and then "PRODUCT_COPY_FILES += ..."
This works but not so good, because the build system includes this file in multiple places and the untar happens many times(~10) which slows down the build and is not nice ...
Upvotes: 1
Views: 5853
Reputation: 99144
This may take a few iterations.
To restate the problem:
There is an assignment to a variable, and a rule that creates files (by unpacking a tar file). We don't know beforehand what the names of those files will be, but we want them in the variable. Assignments to (and modifications of) variables tend to happen outside rules, so they will be executed before the rules.
Here are a couple of approaches. (It is difficult to know which is best, without greater knowledge of your system.)
1) Change the initial assignment from
PRODUCT_COPY_FILES := ...
to
PRODUCT_COPY_FILES = ...
There are two types of variable in Make: simply expanded variables and recursively expanded variables. (This has nothing to do calling a makefile recursively.) The choice is determined by assigning with =
or :=
. If you have a simply expanded variable like
LIST := $(shell ls foo/)
Then it will contain a list of whatever files are in foo/
at the time of assignment. If you execute a rule that puts files in foo/
, then another rule that uses $(LIST)
, the second rule will see only the original file names. But if you use a recursively expanded variable:
LIST = $(shell ls foo/)
then it will contain $(shell ls foo/)
. This will not be expanded (evaluated) until the variable is used, so the second rule will see all the file names.
If you change PRODUCT_COPY_FILES
to a recursively expanded variable, you can use
PRODUCT_COPY_FILES += $(shell ls /untared/dir/*)
and the ls
command will not execute until the variable is used.
2) Use tar -t
The tar
utility allows you to obtain a list of the contents of a tar file without actually unpacking it.
PRODUCT_COPY_FILES += $(shell tar -tf tarfile)
(You may have to use some filtering or other path-manipulation to get what you want.)
3) Use Make recursively
Recursive use of Make is when Make executes Make, with either the same makefile or a different one.
Maybe definition.mk
unpacks the tar file, then calls android.mk
:
# definition.mk
all:
tar -xvf ...
$(MAKE) -f android.mk
When android.mk
begins, the files are already present in /untared/dir/
.
Or if you want android.mk
to be the master makefile that calls other makefiles, you could simply swap the names.
Upvotes: 5