用 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 的詳細解答 。