chr*_*nos 2 makefile build targets
我有一个二进制文件,需要使用不同的编译器标志多次构建。因此,我有一个 Makefile 声明如下:
OBJECTS_A := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.a.o))
OBJECTS_B := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.b.o))
OBJECTS_C := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.c.o))
Run Code Online (Sandbox Code Playgroud)
我还定义了一个规则来更改每个 OBJECTS_x 的标志:
$(OBJECTS_B): DEFINES+=-D_B
$(OBJECTS_C): DEFINES+=-D_C
Run Code Online (Sandbox Code Playgroud)
这就是问题发生的地方:如果我单独说明目标,如:
$(OBJFOLDER)/%.a.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $@
$(OBJFOLDER)/%.b.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $@
$(OBJFOLDER)/%.c.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $@
Run Code Online (Sandbox Code Playgroud)
所有作品。但是,如果我将所有规则合并为一个,则仅评估第一个规则:
$(OBJFOLDER)/%.a.o $(OBJFOLDER)/%.b.o $(OBJFOLDER)/%.c.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $@
Run Code Online (Sandbox Code Playgroud)
我在试运行中得到的是,只有 $(OBJFOLDER)/%.ao 对象被构建,但在链接规则上,每个二进制文件都需要它的对象(因此 b 和 c 二进制文件无法构建)。
有任何想法吗?谢谢!
您可以使用二次扩展来实现这一点:
.SECONDEXPANSION:
$(OBJFOLDER)/%.o: $$(basename $$*).cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $@
Run Code Online (Sandbox Code Playgroud)
请注意,这是不是这样做的很地道的方式,更常见的define/ call/eval组合可用于生成规则在您的第一个解决方案:
VARIANTS=a b c
DEFINES_FOR_a=
DEFINES_FOR_b=-D_B
DEFINES_FOR_c=-D_C
define make_target =
$$(OBJFOLDER)/%.$(1).o: %.cpp
$$(COMPILER) $$(CFLAGS) $$(INCFOLDER) $$(DEFINES_FOR_$(1)) -c $$< -o $$@
endef
$(eval $(foreach variant,$(VARIANTS),$(call make_target,$(variant))))
Run Code Online (Sandbox Code Playgroud)