Build Makefile-文件夹中的依赖项文件;没有这样的文件或目录;
我有一个Makefile,到目前为止运行良好。虽然,随着它的发展,每次重新编译所有源代码开始花费太长时间。以下是工作版本的一个片段:Build Makefile-文件夹中的依赖项文件;没有这样的文件或目录;,build,makefile,dependencies,Build,Makefile,Dependencies,我有一个Makefile,到目前为止运行良好。虽然,随着它的发展,每次重新编译所有源代码开始花费太长时间。以下是工作版本的一个片段: CC=$(CROSS_COMPILE)g++ CFLAGS=-Wall -I./include -pg -O2 VPATH=./src:./include all: dotgazer.cpp dotgazer/Dot.cpp $(CC) $(CFLAGS) $^ -o dotgazer.out `pkg-config --libs opencv` 还有
CC=$(CROSS_COMPILE)g++
CFLAGS=-Wall -I./include -pg -O2
VPATH=./src:./include
all: dotgazer.cpp dotgazer/Dot.cpp
$(CC) $(CFLAGS) $^ -o dotgazer.out `pkg-config --libs opencv`
还有更多的依赖关系,但这两个足以说明问题所在。我试图将每个cpp
文件的编译阶段移动到一个单独的目标。对于顶级文件(dotgazer.cpp
),这不是问题,一般规则是%.o:%.cpp
。但是我无法让第二个依赖项工作。下面是它现在的样子:
CC=$(CROSS_COMPILE)g++
CFLAGS=-Wall -I./include -pg -O2
VPATH=./src:./include
all: dotgazer.o dotgazer/Dot.o
$(CC) $(CFLAGS) $^ -o dotgazer.out `pkg-config --libs opencv`
%.o: %.cpp
$(CC) -c $(CFLAGS) $^ -o $@
dotgazer/Dot.o: dotgazer/Dot.cpp
$(CC) -c $(CFLAGS) $^ -o $@
我尝试了不同的Dot.o
规则,但似乎都不起作用。上面的错误是:
Fatal error: can't create dotgazer/Dot.o: No such file or directory
我该怎么做?我最喜欢将
.o
文件与其源文件放在同一文件夹中。此外,我还要感谢一般规则(如%.o:%.cpp
),因为有很多源文件,我不希望Makefile过于臃肿。谢谢大家! 我认为您的Makefile
有点过于具体,因此容易出错。我建议看我下面的例子,它比你的例子更一般
我的示例利用了make
对隐式规则的概括。对于cpp
-文件已存在通用隐式规则。那么为什么人们不应该使用它呢
参考手册对其描述如下:
<强>编译C++程序>P/> n、 o由n.cc、n.cpp或n.C自动生成,其配方为
$(CXX)$(CPPFLAGS)$(cxflags)-C
因此,如果您有%.o
文件作为先决条件,如规则dotgazer.out:$(OBJS)
make
将上述隐式规则自动应用于所有这些文件。假设您已为CXX
、CPPFLAGS
和/或cxflags
设置了有效值
此外,您通常不需要手动将源添加到变量中。大多数情况下,构建可执行文件需要项目目录树中的所有源。如果不是这样的话,你应该考虑建立一个合适的树来反映这一点。
由于find
负责将源分配给CPPFILES
我们也不需要设置VPATH
。由于使用了find
和patsubst
,我们在Makefile
中只有一个显式文件名。这使得在拥有大量不同来源的真实项目中工作更加顺利
当然,您不需要all
和clean
规则。我只是为了方便才加上这些
CXX=$(CROSS_COMPILE)g++
CPPFLAGS=-I./include
CXXFLAGS=-Wall -pg -O2
LDLIBS=`pkg-config --libs opencv`
CPPFILES=$(shell find . -name "*.cpp")
OBJS=$(patsubst %.cpp, %.o, $(CPPFILES))
all: dotgazer.out
@echo $(CPPFILES)
@echo $(OBJS)
dotgazer.out: $(OBJS)
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDLIBS)
clean:
rm -f $(OBJS)
我可能很傻,但是
%.o:%.cpp
和dotgazer/Dot.o:dotgazer/Dot.cpp
规则不是加倍了吗?比如,后一个目标不是已经被前一个处理了吗?@AdamGoodwin我认为它会这样工作(只需要%.o:%.cpp
规则)。但事实证明——没有。所以我特别为第二个依赖项添加了第二条规则,但它仍然不起作用。只使用%.o:%.cpp
规则,消息是相同的:无法创建dotgazer/Dot.o:没有这样的文件或目录
嗯,我刚刚尝试了你的makefile,它对我来说很好。即使只有%.o
目标,而没有dotgazer/Dot.o
目标,它也能工作。您在文件名或目录方面没有犯错误,是吗?或者你正在做一些事情,比如从它自己的目录以外的其他地方运行makefile?我很确定没有拼写错误或任何东西。我是从Netbeans运行它的,所以我认为它运行在Makefile文件夹中的make
。无论如何,这个被接受的答案比我预期的要好得多。非常棒的答案,谢谢!它有我所需要的一切,所有文件都是单独编译的,.o
文件在各自的文件夹中。但是有一个问题,尽管有LDLIBS
设置,OpenCV函数还是无法识别。以下是输出:dotgazer.out
规则应该如下所示:$(CXX)$^-o$@$(LDLIBS)
。但是,这仍然是一个很好的答案!您是对的,我应该将$(CXX)$(LDLIBS)$^-o$@
更改为$(CXX)$(LDLIBS)-o$$^
g++--help
sai表示输入文件应位于选项之后。最好注意这不是问题所在。-o
可以随时出现。问题是库必须排在最后(库的列出顺序也很重要)。另外,CPPFLAGS
用于C预处理器标志(-I
/-D
);编译器标志如-Wall-pg-O2
属于cxflags
(对于C++)。要链接,请使用类似于$(CXX)$(cxflags)$(LDFLAGS)-o$@$^$(LDLIBS)
@madcasciient:谢谢您的评论。特别是您指出了不同之处。cxflags
和CPPFLAGS
(我将相应地编辑我的答案)。直到现在我才意识到这一点。您的声明有任何参考资料吗…库必须在最后一个。直到今天,我的方法从来没有任何问题,但谢谢你在将来为我省去了麻烦。。。