用 GNU make 编译
介绍
GNU Make(样式为 make
)是一个专门用于执行 shell 命令自动化的程序。GNU Make 是属于 Make 系列的一个特定程序。在类 Unix 和类似 POSIX 的操作系统中仍然很受欢迎,包括那些源自 Linux 内核,Mac OS X 和 BSD 的操作系统。
GNU Make 特别值得注意的是附加到 GNU 项目,GNU 项目附加到流行的 GNU / Linux 操作系统。GNU Make 还具有在各种版本的 Windows 和 Mac OS X 上运行的兼容版本。它也是一个非常稳定的版本,具有历史意义,仍然很受欢迎。出于这些原因,GNU Make 经常与 C 和 C++一起教授。
基本规则
要使用 make 进行编译,请在项目目录中创建 Makefile。你的 Makefile 可以像下面这样简单:
Makefile 文件
# Set some variables to use in our command
# First, we set the compiler to be g++
CXX=g++
# Then, we say that we want to compile with g++'s recommended warnings and some extra ones.
CXXFLAGS=-Wall -Wextra -pedantic
# This will be the output file
EXE=app
SRCS=main.cpp
# When you call `make` at the command line, this "target" is called.
# The $(EXE) at the right says that the `all` target depends on the `$(EXE)` target.
# $(EXE) expands to be the content of the EXE variable
# Note: Because this is the first target, it becomes the default target if `make` is called without target
all: $(EXE)
# This is equivalent to saying
# app: $(SRCS)
# $(SRCS) can be separated, which means that this target would depend on each file.
# Note that this target has a "method body": the part indented by a tab (not four spaces).
# When we build this target, make will execute the command, which is:
# g++ -Wall -Wextra -pedantic -o app main.cpp
# I.E. Compile main.cpp with warnings, and output to the file ./app
$(EXE): $(SRCS)
@$(CXX) $(CXXFLAGS) -o $@ $(SRCS)
# This target should reverse the `all` target. If you call
# make with an argument, like `make clean`, the corresponding target
# gets called.
clean:
@rm -f $(EXE)
注意:确保压痕带有标签,而不是四个空格。否则,你会收到
Makefile:10: *** missing separator. Stop.
的错误
要从命令行运行此命令,请执行以下操作:
$ cd ~/Path/to/project
$ make
$ ls
app main.cpp Makefile
$ ./app
Hello World!
$ make clean
$ ls
main.cpp Makefile
增量构建
当你开始拥有更多文件时,make 会变得更有用。如果你编辑了 a.cpp 而不是 b.cpp 怎么办?重新编译 b.cpp 会花费更多时间。
使用以下目录结构:
.
+-- src
| +-- a.cpp
| +-- a.hpp
| +-- b.cpp
| +-- b.hpp
+-- Makefile
这将是一个很好的 Makefile:
Makefile 文件
CXX=g++
CXXFLAGS=-Wall -Wextra -pedantic
EXE=app
SRCS_GLOB=src/*.cpp
SRCS=$(wildcard $(SRCS_GLOB))
OBJS=$(SRCS:.cpp=.o)
all: $(EXE)
$(EXE): $(OBJS)
@$(CXX) -o $@ $(OBJS)
depend: .depend
.depend: $(SRCS)
@-rm -f ./.depend
@$(CXX) $(CXXFLAGS) -MM $^>>./.depend
clean:
-rm -f $(EXE)
-rm $(OBJS)
-rm *~
-rm .depend
include .depend
再看一下标签。这个新的 Makefile 确保你只重新编译已更改的文件,从而最大限度地缩短编译时间。
文档
有关 make 的更多信息,请参阅自由软件基金会的官方文档 , stackoverflow 文档和 dmckee 关于 stackoverflow 的详细解答 。