我的makefile如下:
CC = gcc
CFLAGS = -g3
LIBS = `pkg-config --cflags --libs glib-2.0`
BINDIR = bin
OUTOBJ = $(addprefix $(BINDIR)/, main.o)
$(info INCLUDE_PATH:$(INCLUDE_PATH))
$(BINDIR)/%.o : %.c
$(CC) -c $< $(CFLAGS) -o $@ $(LIBS)
# TODO: Merge with above rule
$(BINDIR)/%.o : */%.c
$(CC) -c $(INCLUDE_PATH) $< $(CFLAGS) -o $@ $(LIBS)
all: $(OUTOBJ)
$(OUTOBJ): | $(BINDIR)
$(BINDIR):
mkdir $(BINDIR)
.PHONY : clean
clean:
rm bin/*
当我这样调用make时:
make INCLUDE_PATH="/my/proj/dir"
我得到这样的输出:
INCLUDE_PATH:/my/proj/dir
gcc -c main.c -g3 -o bin/main.o `pkg-config --cflags --libs glib-2.0`
.....
.....
因此,查看输出,文件开头的$(info INCLUDE_PATH:$(INCLUDE_PATH))语句基本上可以很好地解决,但是在任务$(INCLUDE_PATH)变量中却无法解决。有人可以帮我吗?
答案 0 :(得分:1)
因此,从输出来看,文件开头的$(info INCLUDE_PATH:$(INCLUDE_PATH))语句基本上可以很好地解决,但是在任务$(INCLUDE_PATH)变量中却无法解决。
不,不是全部。作为@GM在注释中观察到,您在$(BINDIR)
中使用两种不同的模式规则来构建目标文件,并且它们的配方是否引用$(INCLUDE_PATH)
方面也有所不同。您呈现的输出与应用的第一个而不是第二个一致。而这正是我所期望的,因为第二条规则*/%.c
中的先决条件模式与实际使用的先决条件{{ 1}},其名称不包含main.c
字符。
对于您的示例makefile,可以用此规则替换两个/
规则...
$(BINDIR)/%.o
...解决此问题,但实际上这是一种较差的形式,原因有两个。首先,最重要的是,makefile本身应至少提供一个默认值$(BINDIR)/%.o : %.c
$(CC) -c -I$(INCLUDE_PATH) $(CFLAGS) -o $@ $< $(LIBS)
,尤其是当它引用同一项目的另一部分时。其次,将INCLUDE_PATH
(和-I
,-D
以及其他一些指令)收集到名为-U
的变量中并使用 在您的构建规则中:
CPPFLAGS
生成的规则与CPPFLAGS = -I$(INCLUDE_PATH)
$(BINDIR)/%.o : %.c
$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< $(LIBS)
的内置规则非常相似,该规则用于从单个对应的源文件构建目标文件。
总的来说,我不喜欢在与相应目录不同的目录中构建对象,因为它与实际情况背道而驰,因此需要更多的工作来进行设置,而且更加麻烦。无论您的实际项目是大还是小,我真的不知道如何付出努力。如果您要使用源代码以外的版本,请一路使用VPATH。