编写.cpp和.hpp c ++的makefile

时间:2016-08-30 15:17:00

标签: c++ makefile

我需要帮助为多个.hpp和.cpp文件创建一个合适的makefile(支持增量编译)。

我一直在寻找有关如何创建正确的makefile的信息,但我不确定如何做到这一点。

我有以下文件: 2048.cpp,game.cpp,game.hpp,gameutils.cpp,gameutils.hpp,menu.cpp,menu.hpp,saveandback.cpp,saveandback.hpp和tile.hpp

现在我正在使用以下makefile:

all: 2048.cpp tile.hpp menu.hpp menu.cpp gameutils.hpp gameutils.cpp saveandback.hpp saveandback.cpp game.hpp game.cpp
    g++ -g -W -Wall --pedantic -DNDEBUG 2048.cpp -o power

clean: 
    $(RM) power

感谢您的帮助。

1 个答案:

答案 0 :(得分:5)

警告:我暂时没有使用过make,所以我对POSIX与GNU-make特定的东西有点生疏。在过去几年中可能还有一些我不知道的新功能。请随时给予更正。此外大部分来自记忆。

你的知识集中缺少一些你可以用来创建一个只在需要时重新编译东西的体面文件的东西:

  • Generic Rules - 这些可用于提供一个通用规则,用于构建一个带有一个后缀的文件名。例如。以下定义了从相应的* .cpp:

    创建任何* .o的规则
    %.o: %.cpp
        stuff
    

    在POSIX中,这些规则实际上指定为:

    .cpp.o:
        stuff
    

    我正在使用下面的GNU语法,但您可以(并且可能希望)替换为POSIX语法(如果您将它们排除在外并使用隐式规则,请参见下文)。

  • Automatic Variables

    • $<将扩展为规则的输入。
    • $@将扩展到规则的目标。
  • 变量 - 您可以声明变量并赋予它们值,例如:

    SOURCES=2048.cpp gameutils.cpp saveandback.cpp
    

  • 文本替换 - 您可以使用文本替换功能替换后缀,例如:

    OBJECTS=$(SOURCES:.cpp=.o)
    

    OBJECTS设为SOURCES,但将.cpp更改为.o

  • Multiple Rules - 如果为同一目标指定了多个规则,则会合并其先决条件。

  • Phony Targets

将所有这些放在一起你就可以开始了,现在就省去了标题依赖项:

SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp
OBJECTS=$(SOURCES:.cpp=.o)

power: $(OBJECTS)
    g++ $(OBJECTS) -o $@

%.o: %.cpp
    g++ -c $< -o $@

传统上定义一个all规则,这是一个虚假的目标,因为实际上没有一个名为“all”的文件:

.PHONY: all
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp
OBJECTS=$(SOURCES:.cpp=.o)

all: power

power: $(OBJECTS)
    g++ $(OBJECTS) -o $@

%.o: %.cpp
    g++ -c $< -o $@

现在,make实际上已经有一些default rules,包括一个%.o: %.cpp,还有一些default variables。如果您愿意,可以将上述内容减少到此(我个人更喜欢明确指定规则,但这只是我):

.PHONY: all
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp
OBJECTS=$(SOURCES:.cpp=.o)

all: power

power: $(OBJECTS)
    $(CXX) $(CXXFLAGS) $(OBJECTS) -o $@

现在,至于你的标题,记住多个规则的事情,你可以根据它们的包括手工添加这些先决条件,例如:

.PHONY: all
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp
OBJECTS=$(SOURCES:.cpp=.o)

all: power

power: $(OBJECTS)
    $(CXX) $(CXXFLAGS) $(OBJECTS) -o $@

2048.o: menu.hpp game.hpp
menu.o: menu.hpp 
game.o: game.hpp

等等。您可能还需要一个“干净”规则,另一个虚假目标,将二进制名称放在一个变量中并没有什么坏处,因为您在一些地方使用它,例如:

.PHONY: all clean
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp
OBJECTS=$(SOURCES:.cpp=.o)
BINARY=power

all: $(BINARY)

clean:
    $(RM) $(BINARY) $(OBJECTS)

$(BINARY): $(OBJECTS)
    $(CXX) $(CXXFLAGS) $(OBJECTS) -o $@

实际上,如果您将-MM传递给gcc,它将根据源文件的包含自动为您生成Makefile依赖项。有关详细信息和示例,请参阅here