I'm having some trouble using GNU ar script from a Makefile. Specifically, I'm trying to follow an answer to How can I combine several C/C libraries into one?, but ar scripting isn't well supported by make
, as most Makefiles use the ar
command-line interface and not a script. ar
needs each line to be terminated by a new line (\n
). This is not the same as multiple shell commands which can use a semicolon as a separator.
The ar commands are:
ar -M <<CREATE libab.a
ADDLIB liba.a
ADDLIB libb.a
SAVE
END
ranlib libab.a
I'm trying to merge the libraries because I'm creating a static library in a Makefile which depends on another static library, but the second one is created with CMake.
foo.a: foo.o
$(AR) $(ARFLAGS) $@ $^
final_lib.c: foo.a the_cmake_library.a
$(AR) -M <<CREATE $@
ADDLIB foo.a
ADDLIB the_cmake_library.a
SAVE
END
ranlib $@
The above doesn't work because make
is interpreting the ar
commands as its own, so I'm getting a
make: CREATE: Command not found
If these were bash commands, I could use something like this answer, but that doesn't work:
ar -M <<CREATE libab.a; ADDLIB liba.a; ADDLIB libb.a; SAVE; END
ar
doesn't have a command-line version of the ADDLIB
command.
My current solution is:
final_lib.c: foo.a the_cmake_library.a
$(shell printf "EOM\nCREATE $@\nADDLIB foo.a\nADDLIB the_cmake_library.a\nSAVE\nEND\nEOM\n" > ARCMDS.txt)
$(AR) -M < ARCMDS.txt
ranlib $@
I find that very clumsy. Does anyone know of a better way to handle ar
scripts in a Makefile? Thanks!
CodePudding user response:
You don't need to use the shell
function and you don't need to write it to a file. ar
is taking from stdin anyway so why not just use a pipe?
Either:
final_lib.c: foo.a the_cmake_library.a
printf "EOM\nCREATE $@\nADDLIB foo.a\nADDLIB the_cmake_library.a\nSAVE\nEND\nEOM\n" | $(AR) -M
ranlib $@
Or something like:
final_lib.c: foo.a the_cmake_library.a
(echo EOM; \
echo "CREATE $@"; \
echo ADDLIB foo.a; \
echo ADDLIB the_cmake_library.a; \
echo SAVE; \
echo END; \
echo EOM) \
| $(AR) -M
ranlib $@