制定多个类似的规则

时间:2014-01-15 19:10:05

标签: makefile

我的makefile中有以下规则:

pieces = King Queen Knight Rook Bishop Pawn

Chess: ChessMain.o ChessBoard.o
g++ -Wall -g ChessMain.o ChessBoard.o -o Chess

ChessMain: ChessBoard.hpp ChessMain.cpp
g++ -Wall -g -c ChessMain.cpp -o ChessMain.o

ChessBoard: ChessBoard.hpp ChessBoard.cpp
g++ -Wall -g -c ChessBoard.cpp -o ChessBoard.o

Piece: Piece.cpp Piece.hpp
g++ -c Piece.cpp -o Piece.o

King: King.cpp King.hpp Piece
    g++ -c King.cpp -o King.o

Rook: Rook.cpp Rook.hpp Piece
    g++ -c Rook.cpp -o Rook.o

...

和所有其他国际象棋棋子类似(Piece的子类)。如何将这些特定的规则缩短为一般规则?我试过了

$(pieces): $($@:=.cpp) $($@:=.hpp)
    g++ -c $($@:=.cpp) -o $($@:=.o)

但它不起作用。


我编辑了完整的文件。

1 个答案:

答案 0 :(得分:2)

您显示的makefile不对。所有规则都应使用它们实际构建的文件名作为目标名称。因此,使用生成Piece输出文件的目标名称为Piece.o的规则是错误的。

其次,您不需要依赖于其他目标文件的目标文件。目标文件只依赖于它们的源文件和头文件。

第三,当然你可以创建这样的规则(参见关于隐式规则的GNU make手册部分,例如模式规则):

all: King.o Piece.o Rook.o

%.o : %.cpp %.h
        $(COMPILE.cpp) -o $@ $<

你已经完成了。显然你的makefile还有更多(大概是你把这些目标文件链接到一个程序中)但是因为你没有显示任何其他我们可以帮助的东西。

ETA:您在上面显示的(第一个)makefile是不对的。例如,您有Chess目标列表ChessMain.o作为先决条件,但您的makefile中没有规则说明如何构建该文件(您说明如何构建ChessMain但是显然不是一回事.Make可能会使用自己的内置规则,这是可以的,除了没有任何先决条件,所以当标题改变时它不会重建文件。

您可以像这样编写makefile:

CXX      = g++
CXXFLAGS = -Wall -g

pieces = King Queen Knight Rook Bishop Pawn

Chess: ChessMain.o ChessBoard.o $(addsuffix .o,$(pieces))
        $(CXX) $(CXXFLAGS) -o $@ $^ $(LDLIBS)

%.o : %.cpp %.hpp
        $(COMPILE.cpp) -o $@ $<

就是这样,那就是整个makefile。摆脱其他一切(基于上面的例子)。

我应该指出,这可能不够好。例如,如果此处列出的先决条件足够,我会感到震惊。当然,除了.cpp以外,没有.hpp文件包含任何头文件,这是不正确的?当然ChessMain.cpp文件必须#include King.hpp文件等等?这种关系在这里没有表现出来,因此重建将不可靠。