【问题标题】:"make" fails when using pattern matching使用模式匹配时“make”失败
【发布时间】:2016-04-12 16:52:27
【问题描述】:

我正在尝试创建一个通用的 make 文件,以便我可以独立于我添加多少文件以及我决定将它们放在项目树中的什么位置来编译我的项目。

在我一步一步的方法中,我找到了这个运行良好的 makefile。

CC=g++
OBJECTS=main.o board.o
VPATH=src:\
            src/board:\
            include/board:\
            build:\
            bin

boardG : main.o board.o
    $(CC) -o bin/boardG build/main.o build/board.o

main.o : main.cpp board.hpp
    $(CC) -c -I include $< -o build/$@

board.o : board.cpp board.hpp
    $(CC) -c -I include $< -o build/$@

这个版本可以很好地完成这项工作。请参阅下面的输出:

me@01:~/code/projects/boardG$ make
g++ -c -I include src/main.cpp -o build/main.o
g++ -c -I include src/board/board.cpp -o build/board.o
g++ -o bin/boardG build/main.o build/board.o

这里的问题是我必须为每个 .cpp 文件创建一个规则。这正是我试图避免的。因此,我尝试使用这样的匹配模式来调整上面的版本:

CC=g++
OBJECTS=main.o board.o
VPATH=src:\
            src/board:\
            include/board:\
            build:\
            bin

boardG : main.o board.o
    $(CC) -o bin/boardG build/main.o build/board.o

%.o : %.cpp %.hpp
    $(CC) -c -I include $< -o build/$@

当我现在运行 make 时,我得到以下输出:

me@01:~/code/projects/boardG$ make
g++    -c -o main.o src/main.cpp
src/main.cpp:2:27: fatal error: board/board.hpp: No such file or directory
compilation terminated.
<builtin>: recipe for target 'main.o' failed
make: *** [main.o] Error 1

我的项目中有以下结构/文件。

./bin/
./build/
./include/board/board.hpp
./src/main.cpp
./src/board/board.cpp
./makefile

我想知道为什么 make 在使用模式匹配时会更改命令?或者,也许更准确地说,我做错了什么导致 make 失败?

【问题讨论】:

  • 这可能是使用内置的%.o: %.cpp 规则,因为它找不到与您的目标匹配的%.hpp 文件。禁用这些规则 (-r),您应该会看到它以不同的方式失败。运行 make -d 可能有助于向您展示 make 在找到您的目标时试图做什么。 (我不确定 VPATH 如何在单个目标中处理多个模式先决条件。)
  • 你有一些规则来构建文件而不是他们承诺构建的文件(例如build/board.o而不是board.o),以及与这个小说一起玩的另一个规则,声称需要未构建的文件,然后使用已构建的文件。当您尝试对其进行概括时,这自然会中断。

标签: c++ makefile g++ gnu-make


【解决方案1】:

当涉及到目标文件时,请避免使用VPATH。发生的事情是 make 实际上使用了 %.o 的内置规则,而根本没有使用您的规则。

如果您在所有对象前面加上目录,这应该可以:

CC=g++
OBJDIR = build
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/board.o
VPATH = src:\
            src/board:\
            include/board:\

bin/boardG : $(OBJECTS)
    $(CC) -o $@ $^

$(OBJDIR)/%.o : %.cpp %.hpp
    $(CC) -c -I include $< -o $@

这是helpful resource,它或多或少准确地描述了您遇到的问题。

【讨论】:

  • 值得注意的是,使用 VPATH 来查找 object files 本身并没有什么问题。问题是 VPATH 对查找尚不存在的文件没有帮助。
  • 不幸的是,我现在遇到了一个新错误:“...没有规则来制作目标 'build/main.o','bin/boardG' 需要...”。总之,你提供的资源很有意思。主要是Paul’s Rules of Makefiles帮了大忙。根据third one,目标应该在当前目录中构建,因此我的生活似乎变得不必要地复杂。我会将一些尊重该规则的东西放在一起,看看结果如何。
  • 好的,我现在开始工作了。依赖项中的 % 将匹配来自目标的词干。因此,在编译 main.o 时,make 假定依赖项是 main.hpp,而实际上它是 board.hpp。结果它失败了,因为 main.hpp 不存在。我将依赖项从 %.hpp 更改为 board.hpp ,现在它工作正常。我现在需要一种更简洁的方法来处理依赖关系,以及一种允许我不违反 Paul 规则 #3 的方法,但这与手头的问题是不同的主题。 @Barry,感谢您为我的文件夹/VPATH 问题提供答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-05
  • 2012-07-03
相关资源
最近更新 更多