为.cpp和.hpp c ++编写makefile [英] Write makefile for .cpp and .hpp c++

查看:207
本文介绍了为.cpp和.hpp c ++编写makefile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要帮助来为多个.hpp和.cpp文件创建正确的Makefile(支持增量编译).

I need help to create a proper makefile (supporting incremental compilation) for multiple .hpp and .cpp files.

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

I've been looking for information about how to create a proper makefile, but I'm not really sure on how to do it.

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

I have the following files: 2048.cpp, game.cpp, game.hpp, gameutils.cpp, gameutils.hpp, menu.cpp, menu.hpp, saveandback.cpp, saveandback.hpp and tile.hpp

现在我正在使用以下makefile:

Right now I'm using the following 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

谢谢您的帮助.

推荐答案

注意:我已经有一段时间没用过make了,所以我可能对POSIX和GNU make的某些东西有些不了解.过去几年中可能还发布了一些我不知道的新功能.请随时进行更正.同样,大多数是从内存中获取的.

Caveat: I haven't used make in a while so I may be a little rusty on POSIX vs. GNU-make specific stuff. There may also be new features released in the last few years that I'm not aware of. Please feel free to give corrections. Also most of this is from memory.

这里的知识集中缺少一些东西,可用于创建一个不错的makefile,该文件仅在需要时才重新编译它们:

There are a few things missing from your knowledge set here that you can use to create a decent makefile that only re-compiles things when needed:

  • 通用规则-可以使用这些规则提供了一个通用规则,用于使用一个后缀来自另一个后缀来构建文件名.例如.下面定义了一个从其对应的* .cpp创建任何* .o的规则:

  • Generic Rules - These can be used to provide a generic rule for building a filename with one suffix from another. E.g. the following defines a rule for creating any *.o from its corresponding *.cpp:

%.o: %.cpp
    stuff

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

.cpp.o:
    stuff

我在下面使用GNU语法,但是您可以(并且可能想)用POSIX语法替换(如果不使用它们,则使用隐式规则,那么请注意,请参见下文).

I'm using GNU syntax below but you can (and might want to) replace with POSIX syntax (moot if you leave them out and use the implicit rules, though, see below).

自动变量

  • $<将扩展到规则的输入.
  • $@将扩展到规则的目标.
  • $< will expand to the input of the rule.
  • $@ will expand to the target of the rule.

变量-您可以声明变量并为其赋值,例如:

Variables - You can declare variables and give them values, e.g.:

SOURCES=2048.cpp gameutils.cpp saveandback.cpp

等等.

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

Text Replacement - You can use text replacement functions to replace suffixes, e.g.:

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

OBJECTS设置为等于SOURCES,但是将.cpp更改为.o.

Will set OBJECTS equal to SOURCES but with the .cpp's changed to .o.

多个规则-如果多个规则是针对同一目标指定的,其前提条件已合并.

Multiple Rules - If multiple rules are specified for the same target, their prerequisites are merged.

语音目标

放在一起,您可以开始,暂时不包括头文件依赖项:

Putting that all together you can get a start, leaving out header dependencies for now:

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"的文件:

And it's traditional to define an all rule, which is a phony target since there isn't actually a file named "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实际上有一些默认规则,其中包括一个%.o: %.cpp,并且还有一些默认变量.因此,您可以根据需要将以上内容简化为此类(个人而言,我更愿意明确指定规则,但这只是我自己):

Now, make actually has some default rules already, including one for %.o: %.cpp, and also it has some default variables. So you can reduce the above to this if you'd like (personally I prefer to explicitly specify rules, but that's just me):

.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 $@

现在,对于标题,请记住多个规则,您只需根据其包含条件手动添加这些先决条件即可,例如:

Now, as for your headers, keeping in mind the multiple rules thing, you can simply add those prerequisites by hand based on their includes, e.g.:

.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

以此类推.您可能还想要一个干净"规则,另一个伪造目标,并且将二进制名称放在变量中也没有什么坏处,因为您可以在几个地方使用它,例如:

And so on. You probably also want a "clean" rule, another phony target, and it doesn't hurt to put your binary name in a variable since you use it in a few places, e.g.:

.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依赖项.有关详细信息和示例,请参见此处.

And actually if you pass -MM to gcc it'll generate Makefile dependencies automatically for you, based on the source file's includes. See here for details and an example.

这篇关于为.cpp和.hpp c ++编写makefile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆