我的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)
但它不起作用。
我编辑了完整的文件。
答案 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
文件等等?这种关系在这里没有表现出来,因此重建将不可靠。