我正在编写一个make文件以在源代码树中编译代码。在我的make文件中,我有以下内容:
MK = make
CC = g++
PWD = $(shell pwd)
CFLAGS = -std=c++11 -g -Wall
SRCDIR = $(PWD)/src
TSTDIR = $(PWD)/tests
export MK CC SRCDIR TSTDIR CFLAGS
tests:
$(MK) -C $(TSTDIR)
然后TSTDIR
目录中的是另一个makefile:
OBJS = $(notdir $(shell find $(SRCDIR) | grep .o))
IFLAGS = -I$(SRCDIR)
all: ts_tst
%: %.cc $(OBJS)
$(CC) $(CFLAGS) $(IFLAGS) $(LFLAGS) -o $@ $^
我从运行此命令得到的输出是:
make -C <pwd>/tests
make[1]: Entering directory `<pwd>/tests'
g++ ts_tst.cc -o ts_tst
ts_tst.cc:8:31: fatal error: packets/ts_packet.h: No such file or directory
#include "packets/ts_packet.h"
^
compilation terminated.
make[1]: *** [ts_tst] Error 1
make[1]: Leaving directory `<pwd>/tests'
make: *** [tests] Error 2
请注意,g ++命令与make文件中的模板不匹配。现在,如果我从变量$(PWD)/
和SRCDIR
中删除TSTDIR
,我会得到这个……
make -C tests
find: ‘src’: No such file or directory
make[1]: Entering directory `<pwd>/tests'
g++ -std=c++11 -g -Wall -Isrc -o ts_tst ts_tst.cc
ts_tst.cc:8:31: fatal error: packets/ts_packet.h: No such file or directory
#include "packets/ts_packet.h"
^
compilation terminated.
make[1]: *** [ts_tst] Error 1
make[1]: Leaving directory `<pwd>/tests'
make: *** [tests] Error 2
如您所见,搜索源目录显然失败,原因是该路径现在是本地路径,因此它不存在,但是g ++命令现在与我的模板匹配...有人知道这是为什么发生以及如何处理解决吗?
答案 0 :(得分:0)
考虑一下:
OBJS = $(notdir $(shell find $(SRCDIR) | grep .o))
%: %.cc $(OBJS)
$(CC) $(CFLAGS) $(IFLAGS) $(LFLAGS) -o $@ $^
设置SRCDIR
可能会找到一些目标文件(顺便说一句,我不知道为什么您在这里使用grep
而不是仅将-name \*.o
添加到{{ 1}}命令:find
有问题,因为它也将与grep
之类的文件匹配。)
假设它找到了目标文件foo.ohno
。在其上运行/my/path/to/src/foo.o
,并将notdir
设置为OBJS
。
这意味着模式变为:
foo.o
现在make想要搜索将匹配的模式规则。它将不符合此规则,因为尽管模式%: %.cc foo.o
$(CC) $(CFLAGS) $(IFLAGS) $(LFLAGS) -o $@ $^
和%
匹配,但其他先决条件%.cc
不存在(不在本地目录中)。结果,该模式被忽略,make将继续寻找其他模式。它将找到匹配的内置模式,这就是为什么要获得输出的原因。
在没有找到目标文件的情况下(错误的foo.o
命令),find
变量为空,因此模式规则匹配。
如果您删除了OBJS
,它应该可以工作,但是我不知道为什么要添加它,所以也许还有其他问题。
其他说明:
notdir
或$(MAKE)
,而不要使用${MAKE}
或其他变量。make
或其他速度较慢的功能时,应使用:=
。