您好,登錄后才能下訂單哦!
這篇“C++的Makefile怎么用”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“C++的Makefile怎么用”文章吧。
為什么要使用 Makefile?
Makefile 文件描述了整個工程的編譯、鏈接的規則。
為工程編寫 Makefile 的好處是能夠使用一行命令來完成“自動化編譯”。只需提供一個(通常對于一個工程來說會是多個)正確的 Makefile,接下來每次的編譯都只需要在終端輸入“make”命令,整個工程便會完全自動編譯,極大提高了效率。尤其是在編譯一個僅有一小部分文件被改動過的大項目的情況下。
絕大多數的 IDE 開發環境都會為用戶自動編寫 Makefile。
Make 是怎么工作的?
Make 工作的原則就是:
一個目標文件當且僅當在其依賴文件(dependencies)的更改時間戳比該目標文件的創建時間戳新時,這個目標文件才需要被重新編譯。
Make 工具會遍歷所有的依賴文件,并且把它們對應的目標文件進行更新。編譯的命令和這些目標文件及它們對應的依賴文件的關系則全部儲存在 Makefile 中。
Makefile 中也指定了應該如何創建,創建出怎么樣的目標文件和可執行文件等信息。
除此之外,你甚至還可以在 Makefile 中儲存一些你想調用的系統終端的命令,像一個 Shell 腳本一樣使用它。
作用:
Makefile 文件告訴 Make 怎樣編譯和連接成一個程序
可用命令 dnf install make 安裝make功能
格式:
按如下格式編寫 Makefile
目標(target): 依賴(prerequiries)...
命令(command)
注意:每個命令行前面必須是一個Tab字符,即命令行第一個字符是Tab
實驗:
vim Makefile 編輯文件:
simpletest:simple.o simpletest.o g++ simple.o simpletest.o -o simpletest simple.o:simple.cpp g++ -c simple.cpp -o simple.o simpletest.o:simpletest.cpp g++ -c simpletest.cpp -o simpletest.o
結果為:
[root@foundation1 shishi]# make
g++ -c simple.cpp -o simple.o
g++ -c simpletest.cpp -o simpletest.o
g++ simple.o simpletest.o -o simpletest
命令上下是有順序的,上一行對下一行具有依賴關系
如果文件夾中已經有.o文件,make后會提示已經生成,需要刪除.o文件后再make
clean的作用: 被指定時會刪除對應.o文件,避免上述情況
simpletest:simple.o simpletest.o g++ simple.o simpletest.o -o simpletest simple.o:simple.cpp g++ -c simple.cpp -o simple.o simpletest.o:simpletest.cpp g++ -c simpletest.cpp -o simpletest.o clean: rm simpletest simple.o simpletest.o
結果為:
[root@foundation1 shishi]# make clean
rm simpletest simple.o simpletest.o
[root@foundation1 shishi]# make
g++ -c simple.cpp -o simple.o
g++ -c simpletest.cpp -o simpletest.o
g++ simple.o simpletest.o -o simpletest
使用變量: 如果調用某個文件用的次數較多,可以使用變量代替,變量可以直接替換
變量定義: 變量 = 字符串
變量使用: $(變量名)
makefile 文件可改為:
TARGET = simpletest OBJS = simple.o simpletest.o $(TARGET):$(OBJS) g++ $(OBJS) -o $(TARGET) simple.o:simple.cpp g++ -c simple.cpp -o simple.o simpletest.o:simpletest.cpp g++ -c simpletest.cpp -o simpletest.o clean: rm $(TARGET) $(OBJS)
命令自動推導: 我們可以發現,由于 .cpp 文件都是生成對應的 .o 文件,所以 makefile 文件是可以自動識別的
makefile 文件可改為:
TARGET = simpletest OBJS = simple.o simpletest.o $(TARGET):$(OBJS) g++ $(OBJS) -o $(TARGET) simple.o:simple.cpp simpletest.o:simpletest.cpp clean: rm $(TARGET) $(OBJS)
預定義變量: 系統中自己也定義了一些變量
變量 | 程序 | 默認值 |
---|---|---|
CC | C語言編譯程序 | cc |
CXX | C++編譯程序 | g++ |
AR | C++打包程序 | ar |
CPP | 帶有標準輸出的C語言預處理程序 | $(CC) -E |
RM | 刪除命令 | rm |
makefile 文件可改為:
TARGET = simpletest OBJS = simple.o simpletest.o $(TARGET):$(OBJS) $(CXX) $(OBJS) -o $(TARGET) simple.o:simple.cpp simpletest.o:simpletest.cpp clean: $(RM) $(TARGET) $(OBJS)
假想目標: 如果文件夾中有clean文件,那么make clean就不能使用,需要使用假想目標,可以在執行命令時不查看文件夾里面的文件,直接生效
makefile 文件可改為:
TARGET = simpletest OBJS = simple.o simpletest.o .PHONY: clean $(TARGET):$(OBJS) $(CXX) $(OBJS) -o $(TARGET) simple.o:simple.cpp simpletest.o:simpletest.cpp clean: $(RM) $(TARGET) $(OBJS)
建議不生成目標文件的命令都設為假想目標
vim Makefile 編輯文件:
TARGET = simpletest OBJS = simple.o LIB = libsimple.so CXXFLAGS = -c -fPIC .PHONY: clean $(TARGET):$(LIB) simpletest.o $(CXX) simpletest.o -o $(TARGET) -L. -lsimple $(LIB):$(OBJS) $(CXX) -shared $(OBJS) -o $(LIB) simple.o:simple.cpp $(CXX) $(CXXFLAGS) simple.cpp -o $(OBJS) simpletest.o:simpletest.cpp $(CXX) $(CXXFLAGS) simpletest.cpp -o simpletest.o clean: $(RM) $(TARGET) $(OBJS) $(LIB)
結果為:
[root@foundation1 shishi]# make clean
rm -f simpletest simple.o libsimple.so
[root@foundation1 shishi]# make
g++ -c -fPIC simple.cpp -o simple.o
g++ -shared simple.o -o libsimple.so
g++ -c -fPIC simpletest.cpp -o simpletest.o
g++ simpletest.o -o simpletest -L. -lsimple
預定義變量:
還是需要在前面定義
變量 | 程序參數 |
---|---|
CFLAGS | 用于C編譯器的額外標志 |
CXXFLAGS | 用于C++編譯器的額外標志 |
ARFLAGS | 用于C/C++打包器的額外標志 |
LDFLAGS | 鏈接庫路徑-L |
LDLIBS | 鏈接庫-l |
makefile 文件可改為:
TARGET = simpletest OBJS = simple.o LIB = libsimple.so CXXFLAGS = -c -fPIC LDFLAGS = -L. LDLIBS = -lsimple .PHONY: clean $(TARGET):$(LIB) simpletest.o $(CXX) simpletest.o -o $(TARGET) $(LDFLAGS) $(LDLIBS) $(LIB):$(OBJS) $(CXX) -shared $(OBJS) -o $(LIB) simple.o:simple.cpp $(CXX) $(CXXFLAGS) simple.cpp -o $(OBJS) simpletest.o:simpletest.cpp $(CXX) $(CXXFLAGS) simpletest.cpp -o simpletest.o clean: $(RM) $(TARGET) $(OBJS) $(LIB)
自動變量:
自動變量是在規則每次執行時都基于目標和依賴產生新值的變量
自動變量 | 含義 |
---|---|
$< | 表示第一個匹配的依賴 |
$@ | 表示目標 |
$^ | 所有依賴 |
$? | 所有依賴中更新的文件 |
$+ | 所有依賴文件不去重 |
$(@D) | 目標文件路徑 |
$(@F) | 目標文件名稱 |
makefile 文件可改為:
TARGET = simpletest OBJS = simple.o LIB = libsimple.so CXXFLAGS = -c -fPIC LDFLAGS = -L. LDLIBS = -lsimple .PHONY: clean $(TARGET):simpletest.o $(LIB) $(CXX) $< -o $@ $(LDFLAGS) $(LDLIBS) $(LIB):$(OBJS) $(CXX) -shared $^ -o $@ simple.o:simple.cpp $(CXX) $(CXXFLAGS) $< -o $@ simpletest.o:simpletest.cpp $(CXX) $(CXXFLAGS) $< -o $@ clean: $(RM) $(TARGET) $(OBJS) $(LIB)
自動匹配:
通配符主要用于匹配文件名,makefile中使用%作為通配符。從匹配目標格式的目標名中依據通配符抽取部分字符串,再按照抽取字符串分配到每一個依賴格式中產生依賴名。例如,使用%.o:%.cpp
可以讓重復的語句合為一句
makefile 文件可改為:
TARGET = simpletest OBJS = simple.o LIB = libsimple.so CXXFLAGS = -c -fPIC LDFLAGS = -L. LDLIBS = -lsimple TESTOBJ = simpletest.o .PHONY: clean $(TARGET):$(TESTOBJ) $(LIB) $(CXX) $< -o $@ $(LDFLAGS) $(LDLIBS) $(LIB):$(OBJS) $(CXX) -shared $^ -o $@ $(TESTOBJ) $(OBJS):%.o:%.cpp $(CXX) $(CXXFLAGS) $< -o $@ clean: $(RM) $(TARGET) $(OBJS) $(LIB) $(TESTOBJ)
TARGET = simpletest2 OBJS = simple.o LIB = libsimple.so CXXFLAGS = -c -fPIC LDLIBS = -ldl TESTOBJ = simpletest2.o .PHONY: clean # 生成可執行文件 $(TARGET):$(TESTOBJ) $(LIB) $(CXX) $< -o $@ $(LDFLAGS) $(LDLIBS) # 生成庫 $(LIB):$(OBJS) $(CXX) -shared $^ -o $@ # 生成目標文件 $(TESTOBJ) $(OBJS):%.o:%.cpp $(CXX) $(CXXFLAGS) $< -o $@ clean: $(RM) $(TARGET) $(OBJS) $(LIB) $(TESTOBJ)
結果為:
[root@foundation1 C++7.4]# make clean
rm -f simpletest2 simple.o libsimple.so simpletest2.o
[root@foundation1 C++7.4]# make
g++ -c -fPIC simpletest2.cpp -o simpletest2.o
g++ -c -fPIC simple.cpp -o simple.o
g++ -shared simple.o -o libsimple.so
g++ simpletest2.o -o simpletest2 -ldl
[root@foundation1 C++7.4]# ./simpletest2
Simple()
Test()
~Simple()
以上就是關于“C++的Makefile怎么用”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。