Makefile命令行参数无法解析

时间:2019-07-04 13:28:39

标签: command-line makefile

我的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)变量中却无法解决。有人可以帮我吗?

1 个答案:

答案 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