我将尝试设置一个Makefile,根据目标文件扩展名来构建静态(.a)和动态(.so)库。
以前我只用过如下Makefile来构建静态库:
我的主要目标是只通过更改
如果我将
以前我只用过如下Makefile来构建静态库:
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 $@
我的主要目标是只通过更改
LIB
和NAME
变量来编译多个库。一切都正常工作,所以我添加了以下内容用于动态库:LDFLAGS += -shared
%.so: CFLAGS += -fPIC
%.so: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
将$(LIB):
规则更改为以下通用规则:
%.a: %.a($(OBJ))
ranlib $@
如果我将
LIB
更改为lib$(NAME).so
,一切都按预期工作,但是使用.a
扩展名时,make会打印出以下错误:
make: *** 没有找到目标文件 'libconfig.a',需要 'all'。 停止。
我发现的唯一解决方案是添加另一个显式规则,如下所示:
%.a($(OBJ)): $(OBJ)
$(AR) rv $@ $^
现在一切都正常了。
但是添加这个明确规则会防止我仅依赖于GNU make的隐式规则,并使我必须显式地调用ar,而这正是我想避免的。
这是某种类型的错误还是我漏掉了什么?
GNU Make 3.82
Built for x86_64-unknown-linux-gnu