I have a bunch of static libraries and I need to combine into a single file using ar
in Makefile
.
For example,
ar -M <<EOM
CREATE app.a
ADDLIB lib1.a
ADDLIB lib2.a
ADDLIB lib3.a
....
....
....
ADDLIB libN.a
SAVE
END
EOM
This is fine and works as long as I know all the libraries that I need to add as ADDLIB libX.a
.
I want to automate this. I have a variable in Makefile which stores all these libraries.
Inside Makefile target, I want to do,
my_target:
# Get all libraries from the variable $(libraries).
# Combine all of them into a single file using archiver as above
I couldn't find a way to do it since each 'line' or sub-command inside target is run in it's own shell.
I'm assuming this is a Makefile variable as opposed to a bash one. I'm also assuming that it is a space delimited list of files. You could do something like:
#Makefile trickery to create a variable that holds a single space:
space :=
space +=
my_target:
ar -M CREATE $(subst $(space), ADDLIB ,$(strip $(variables))
This uses some makefile text processing to add the string ADDLIB
between each entry (and we manually previx the first entry with CREATE
. The $(strip)
simply removes duplicate whitespaces (along with trailing/leading whitespaces) to prevent any unexpected side effects.
Alternatively though, if you wanted to do something more complex, and you only knew how to do it in bash, you could do as @MadScientist suggest, and catinate several recipe lines together:
target:
parmList="CREATE $$(echo "$(variables)" | sed s/ / ADDLIB /g)"; \
ar -M $${parmList}
Note the use of $$
in front of $${parmList}
and $$(shell ...)
, and the trailing \
and ';' at the end of the first recipe line.
(There's also some setting that makes make run all recipe lines in a single shell, but I would highly recommend against using it)