Archives and shared libraries don't share the same prerequisites syntax, so it is not possible to have a single rule that handle both.
The simplest solution is to use a conditional on the target extension:
ifeq "$(suffix $(LIB))" ".a"
$(LIB): $(LIB)($(OBJ))
else ifeq "$(suffix $(LIB))" ".so"
$(LIB): override CFLAGS += -fPIC
$(LIB): $(OBJ)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
endif
A working Makefile that meets the requirements looks now like this:
NAME := config
LIB := lib$(NAME).so
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(OBJ:.o=.d)
CPPFLAGS := -MMD -MP
CFLAGS := -W -Wall
LDFLAGS := -shared
ARFLAGS := rs
.PRECIOUS: $(OBJ)
.PHONY: all clean fclean re
all: $(LIB)
clean:
$(RM) $(OBJ) $(DEP)
fclean: clean
$(RM) $(LIB)
re: fclean all
ifeq "$(suffix $(LIB))" ".a"
$(LIB): $(LIB)($(OBJ))
else ifeq "$(suffix $(LIB))" ".so"
$(LIB): override CFLAGS += -fPIC
$(LIB): $(OBJ)
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
endif
ifeq "$(MAKECMDGOALS)" ""
-include $(DEP)
endif
Note that the ARFLAGS
variable controls which flags are passed to the invocation of ar
. Here I use the r
flag to replace existing object if it exists and the s
flag to build or update the index (ranlib
is not necessary anymore with this).