我有以下makefile:
CC ?= gcc
LD := gcc
CFLAGS := -Wall -Wextra -Werror -Wfatal-errors
LDFLAGS :=
LIBRARIES := m c
INCLUDEDIRS := .
LIBS = $(addprefix -l,$(LIBRARIES))
INCLUDES = $(addprefix -I,$(INCLUDEDIRS))
SRC := $(wildcard *.c)
TARGET = $(TARGETDIR)/test
OBJDIR = $(TARGETDIR)/obj/
OBJ = $(addprefix $(OBJDIR),$(SRC:%.c=%.c.o))
.SUFFIXES:
.SUFFIXES: .c.o
.PHONY: all debug i7avx i7avx-debug
all: TARGETDIR := generic
all: CFLAGS += -O3
all: LDFLAGS += -s
all: $(TARGET)
debug: CFLAGS += -Og
debug: TARGETDIR := generic/dbg
debug: $(TARGET)
$(OBJDIR):
@mkdir -p $(OBJDIR)
$(OBJ): | $(OBJDIR)
$(OBJDIR)%.c.o : %.c
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
$(TARGET) : $(OBJ)
$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
这里的特殊之处在于输出目录取决于目标。 目前,只定义了所有和调试,但这个想法是支持一大堆架构,并为每个目标定义一个outputdir。
问题:这不起作用。如果我运行这个,我得到:
cc -Wall -Wextra -Werror -Wfatal-errors -O3 -I. -c main.c -o /obj/main.c.o
Assembler messages:
Fatal error: can't create /obj/main.c.o: No such file or directory
make: *** [Makefile:37: /obj/main.c.o] Error 1
这意味着TARGETDIR变量扩展太晚了。 如果我用自动变量替换自动变量,它确实有效:
$(OBJ): | $(OBJDIR)
$(OBJDIR)%.c.o : %.c
$(CC) $(CFLAGS) $(INCLUDES) -c $(SRC) -o $(OBJ)
$(TARGET) : $(OBJ)
$(LD) $(LDFLAGS) -o $(TARGET) $(OBJ) $(LIBS)
运行这个:
cc -Wall -Wextra -Werror -Wfatal-errors -O3 -I. -c main.c -o generic/obj/main.c.o
gcc -s -o generic/test generic/obj/main.c.o -lm -lc
Sooo,如何在定义TARGETDIR后扩展自动变量?
答案 0 :(得分:0)
Make会非常巧妙地处理通配符,或者这将是一个更容易解决的问题。
实际上,我认为最好的解决方案是使用recursive Make。只需改变一下:
all: $(TARGET)
debug: $(TARGET)
到此:
all debug:
$(MAKE) $(TARGET) TARGETDIR=$(TARGETDIR) CFLAGS+='$(CFLAGS)' LDFLAGS=$(LDFLAGS)
答案 1 :(得分:0)
首先,它不起作用的原因:
您正在使用特定于目标的变量,但这些变量仅在目标配方的上下文中可用(我在此引用手册),而不是在规则评估期间:
Make将首先阅读您的Makefile,评估您的$(OBJDIR)
和$(TARGET)
规则(此时$(TARGETDIR)
尚未定义)然后,它会尝试更新all
,并且此点将$(TARGETDIR)
设置为all
的特定于目标的值(这解释了为什么您是第二个示例工作,但它应该每次重建)。
我可能会有一些提示来实现你想要做的事情(我实际上计划尽快做类似的事情):
您可以使用eval函数为每个构建/ archi生成一个规则,如下所示:
#define TARGET_RULE
$(TARGET) : $(OBJ)
$$(RECIPE)
#endif
$(foreach TARGETDIR, $(BUILD_LIST), $(eval $(TARGET_RULE))
(配方需要$$
以避免在规则评估期间将其展开)
您还应该只能为您当前构建的目标定义规则(不确定是否会产生明显的性能差异)。