I am trying to setup a Makefile to build either static (.a) and dynamic (.so) libraries depending on the target file extension.
I previously used the following Makefile for static libraries only :
NAME := config
LIB := lib$(NAME).a
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
CFLAGS += -W -Wall
.PHONY: all clean fclean re
all: $(LIB)
clean:
@$(RM) $(OBJ)
fclean: clean
@$(RM) $(LIB)
re: fclean all
$(LIB): $(LIB)($(OBJ))
ranlib $@
My main goal is to be able to compile multiple libraries by only changing the LIB
and NAME
variables.
Everything worked fine, so I added the following for the dynamic libraries :
LDFLAGS += -shared
%.so: CFLAGS += -fPIC
%.so: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
And changed the $(LIB):
rule by the following generic rule :
%.a: %.a($(OBJ))
ranlib $@
If I change LIB
to lib$(NAME).so
everything works as expected, but with the .a
extension, make prints me this error :
make: *** No rule to make target 'libconfig.a', needed by 'all'. Stop.
The only solution I found was to add another explicit rule like that :
%.a($(OBJ)): $(OBJ)
$(AR) rv $@ $^
And now everything works.
But adding this explicit rule prevents me from relying only upon GNU make's implicit rules, and makes me call explicitly ar, which I wanted to avoid.
Is this some kind of bug or am I missing something ?
GNU Make 3.82
Built for x86_64-unknown-linux-gnu
Some quick testing seems to indicate that this can't be done. It appears that the specialized make archive support is a makefile parse time feature. That is the literal archive name must exist in the actual makefile for it to take effect.
I tried a couple of workarounds but wasn't able to get any of them to work correctly. The closest I could manage was:
$(foreach a,$(filter %.a,$(MAKECMDGOALS) $(.DEFAULT_GOAL)),$(eval $a: $a($$(OBJ)); ranlib $$@))
which doesn't work for a default goal of all
but would if the default was the library name and/or if the library name is an explicit make target. You could stick any other known library names in there too and then they should work even as implicit requirements of other targets but that's a manual process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With