C++ 需要了解makefile模式规则%:%的帮助。o

C++ 需要了解makefile模式规则%:%的帮助。o,c++,makefile,C++,Makefile,我想使用我在一本书中读到的模式规则将这个makefile更改为更简单的内容: VPATH = src CPPFLAGS = -I include main.o: main.cpp g++ $(CPPFLAGS) $< TwoDimensionalShape.o: TwoDimensionalShape.cpp g++ -c $(CPPFLAGS) $< Square.o: Square.cpp Square.h g++ -c $(CPPFLAGS) $<

我想使用我在一本书中读到的模式规则将这个makefile更改为更简单的内容:

VPATH = src
CPPFLAGS = -I include

main.o: main.cpp
    g++ $(CPPFLAGS) $<
TwoDimensionalShape.o: TwoDimensionalShape.cpp
    g++ -c $(CPPFLAGS) $<
Square.o: Square.cpp Square.h
    g++ -c $(CPPFLAGS) $<
Circle.o: Circle.cpp Circle.h
    g++ -c $(CPPFLAGS) $<
Rectangle.o: Rectangle.cpp Rectangle.h
    g++ -c $(CPPFLAGS) $<
Triangle.o: Triangle.cpp Triangle.h
    g++ -c $(CPPFLAGS) $<
ShapeStack.o: ShapeStack.cpp ShapeStack.h
    g++ -c $(CPPFLAGS) $<
ScreenManager.o: ScreenManager.cpp ScreenManager.h
    g++ -c $(CPPFLAGS) $<
ScreenState.o: ScreenState.cpp ScreenState.h
    g++ -c $(CPPFLAGS) $<
SquareState.o: SquareState.cpp SquareState.h
    g++ -c $(CPPFLAGS) $<
CircleState.o: CircleState.cpp CircleState.h
    g++ -c $(CPPFLAGS) $<
VPATH=src
CPPFLAGS=-I include
main.o:main.cpp
g++$(CPPFLAGS)$<
TwoDimensionalShape.o:TwoDimensionalShape.cpp
g++-c$(CPPFALGS)$<
Square.o:Square.cpp Square.h
g++-c$(CPPFALGS)$<
Circle.o:Circle.cpp Circle.h
g++-c$(CPPFALGS)$<
矩形.o:Rectangle.cpp Rectangle.h
g++-c$(CPPFALGS)$<
三角形.o:Triangle.cpp Triangle.h
g++-c$(CPPFALGS)$<
ShapeStack.o:ShapeStack.cpp ShapeStack.h
g++-c$(CPPFALGS)$<
ScreenManager.o:ScreenManager.cpp ScreenManager.h
g++-c$(CPPFALGS)$<
ScreenState.o:ScreenState.cpp ScreenState.h
g++-c$(CPPFALGS)$<
SquareState.o:SquareState.cpp SquareState.h
g++-c$(CPPFALGS)$<
CircleState.o:CircleState.cpp CircleState.h
g++-c$(CPPFALGS)$<
读完这本书后,我可以用这样的模式规则来写上面的内容。但我不明白它是如何工作的:

#source files are in "src" folder.
VPATH = src
#header files are in "include" folder.
CPPFLAGS = -I include -Wall

all: main.o TwoDimensionalShape.o Square.o Circle.o Rectangle.o Triangle.o ShapeStack.o ScreenManager.o ScreenState.o SquareState.o CircleState.o
    g++ $(CPPFLAGS) $^

%.o: %.cpp
    g++ -c $(CPPFLAGS) $<

%: %.o
    g++ $<
#源文件位于“src”文件夹中。
VPATH=src
#头文件位于“包含”文件夹中。
CPPFLAGS=-I include-Wall
全部:main.o二维形状。o正方形。o圆形。o矩形。o三角形。o形状堆栈。o屏幕管理器。o屏幕状态。o正方形状态。o圆形状态。o
g++$(CPPFLAGS)$^
%.o:%.cpp
g++-c$(CPPFALGS)$<
%:%
g++$<
这个makefile是正确的,但是我不理解它是如何工作的

  • 如果我更改了例如2个源文件,那么这个makefile如何理解为只编译更改后的两个源文件而不是所有源文件
  • 在我读的书中,例子是关于C不是C++,最后一行是代码> %:%.c<代码>。那为什么我的行是
    %:%.o
    在工作?它不应该是
    %:%.cpp
  • 这个makefile是正确的,但是我不理解它是如何工作的

    如果您的新Makefile是旧Makefile的替代品,那么它肯定不起作用

    在“旧的”一个你有

    ShapeStack.o: ShapeStack.cpp ShapeStack.h
    
    这说明ShapeStack.o依赖于.cpp和头文件。您的新Makefile与其他文件没有任何依赖关系,这将导致很多麻烦。只需触摸其中一个标题并键入make。什么都不会发生

    因此,至少您必须引入源文件依赖项,可以像在旧makefile中一样手动,或者使用一些更自动的方法,使用编译器的依赖项检查,使用gcc,它与“gcc-MM”一起使用

    要获取自动化的先决条件,请参阅

    而且使用vpath会带来很多麻烦。有一些文章,例如:

    此处已经可以找到一些示例Makefiles:

    向后工作。看看你的所有规则,那将首先被检查。接下来,make需要确定列出的每个
    .o
    依赖项是否都是最新的,因此它会查找与之匹配的规则,该规则始终是
    %.o:%.cpp
    规则。因此,它查看
    main.cpp
    以确定
    main.o
    是否是最新的,以及其他每个soh是否都是最新的,并将其与
    -d
    一起运行以调试makefile,这将显示它为每个makefile考虑的规则file@jamek-
    make
    是跨平台的。更改为cmake只会更改您询问的工具,它不会解决任何问题。如果您正确设置了
    CXX
    CXXFLAGS
    ,则可以使用Make的内置
    %.o:%.cpp
    规则。您可以设置
    LINK.o=$(LINK.cc)
    以使用内置链接器规则。Slim makefiles是更好的makefiles@Jerome-关于如何获得答案的建议是评论。只有实际的答案才应该作为答案发布。非常感谢。我使用了
    g++-MM
    但给了我很多警告。。。我必须阅读您提供的链接,手动引入头文件将导致与第一个makefile相同的文本墙…@mhm:对于小型项目,编写自动生成DEP的所有规则不仅仅是手工编制的规则。但您应该考虑编写一个具有此功能的通用Makefile,并在所有项目中使用它。每一个新项目只需要一行代码:OBJS=a.o,b.o…和一个通用的include。手动编写DEP很容易出错,根本不应该这样做@mhm:添加了一个资源,可以通过autodep生成查找简单的makefile。注意:接受的答案不正确!建议不要错误地使用
    VPATH
    。看起来它在这里用得很好。@TobySpeight:这里提到它是因为它经常被错误地使用。我并没有说它在这里被错误地使用。