我有以下 Makefile,它从多个源文件构建一个小型库:
# Source files
libABC_src := $(src_dir)/libABC_file1.c \
$(src_dir)/libABC_file2.c \
$(src_dir)/libABC_file3.c
# Object files
libABC_obj := $(patsubst $(src_dir)/%.c, $(obj_dir)/%.o, $(libABC_src))
# Build object files
define rule
$(libABC_obj): $(obj_dir)/%.o: $(src_dir)/%.c
$(CC) $(CFLAGS) -c -o $$@ $$<
endef
$(eval $(rule))
正如您在上面看到的,我有一个构建所有目标文件的规则。这非常整洁且易于维护。
我有一个要求,只需使用特殊的编译器标志构建
libABC_file3.c
。所以我研究了目标特定变量,但是像这样重写规则似乎不起作用,并且在构建 CFLAGS_EXTRA
时 libABC_file3.o
始终为空:
# Build object files
define rule
$(obj_dir)/libABC_file3.o: private CFLAGS_EXTRA := -fno-inline
$(libABC_obj): $(obj_dir)/%.o: $(src_dir)/%.c
$(CC) $(CFLAGS) $(CFLAGS_EXTRA) -c -o $$@ $$<
endef
$(eval $(rule))
我认为这是因为规则
$(libABC_obj): $(obj_dir)/%.o: $(src_dir)/%.c
已经包含此目标,并且它只是覆盖了目标特定规则。
我可以有两个单独的规则 - 一个用于构建
libABC_file3.o
,另一个用于使用默认值 CFLAGS
构建其余的目标文件。然而,这很难阅读和维护。
有谁知道 GNU Make 是否可以被告知这样做 - “如果有目标特定规则,那么它具有优先级,并且优先于具有相同目标的任何其他规则”。或者是否有其他方法可以解决这个问题。
谢谢。
经过一番调试,我找到了问题的原因。由于规则已定义并随后使用
eval
进行评估,因此我需要转义 $
字符。这就是它应该的样子,现在有 $$(CFLAGS_EXTRA)
:
# Build object files
define rule
$(obj_dir)/libABC_file3.o: private CFLAGS_EXTRA := -fno-inline
$(libABC_obj): $(obj_dir)/%.o: $(src_dir)/%.c
$(CC) $(CFLAGS) $$(CFLAGS_EXTRA) -c -o $$@ $$<
endef
$(eval $(rule))
不确定为什么变量扩展可以正确地使用
$(CC)
和 $(CFLAGS)