Linux修煉:自動化構建make/Makefile

?????????Hello大家好!很高興我們又見面啦!給生活添點passion,開始今天的編程之路!

我的博客:<但凡.

我的專欄:《編程之路》、《數據結構與算法之美》、《C++修煉之路》、《Linux修煉:終端之內 洞悉真理》

感謝你打開這篇博客!希望這篇博客能為你帶來幫助,也歡迎一起交流探討,共同成長。

目錄

1、引入

2、基本概念

? ? ? 理解

?3、推導

4、Makefile語法拓展


1、引入

? ? ? ? 在上一期我們介紹了gcc來編譯源文件,可是大家在未來寫代碼的時候,有可能會有多個源文件需要我們去編譯,那么我們怎么樣才能像在vs那樣,自動化的編譯形成可執行程序呢?

? ? ? ? 我們可以通過這一期介紹的make/Makefile來實現自動化構建


2、基本概念

? ? ? ? make是Linux系統內置的命令,而Makefile是需要工程師自己建立的文件。

? ? ? ? 那么我們先來簡單看一下怎么操作:

? ? ? ? 現在我們的目錄中已經有了一個寫好的code.c文件。

? ? ? ? 第一步新建一個名為Makefile的文件(或者makefile);

? ? ? ? 第二步,在文件中寫入以下代碼:

????????

? ? ? ? 注意,第二行必須是table而不是空格!

? ? ? ? 第三步,輸入命令 make,我們發現我們當前目錄中生成了code文件:

? ? ? ? 第四步,我們直接執行這個可執行程序code:

? ? ? ? ?接下來,我們在Makefile中寫一下自動清理:

? ? ? ? ?現在,我們執行make clean命令,就能夠自動刪除我們剛才實現的可執行程序了。? ? ? ? ??


? ? ? 理解

????????現在我們來解釋一下我們剛才都寫了什么:

? ? ? ? 文件的第一行,code:code.c 是依賴關系;緊接著第二行叫依賴方法。依賴方法表明了依賴關系。注意第二行開頭必須是TAB鍵,對于縮進有嚴格要求。依賴關系和依賴方法缺一不可。依賴關系中,冒號前面的我們叫目標文件,也就是我們生成的文件。冒號后面的叫依賴文件列表。這個列表可以有多個文件。

? ? ? ? 第三行.PHONY?:clean聲明?clean是一個偽目標,即它不代表實際要生成的文件名。第四行clean:?定義了一個名為 clean?的目標。當在命令行運行make? clean時,Make 會執行該目標下的命令。偽目標總是被執行的。 什么叫總是被執行的呢?我們多次執行make,會發現他不讓你編譯了,因為他檢測到你的源代碼沒有變化。這就叫總是不被執行,本質上是為了提升效率。如果我們多次執行clean,發現他總是會被執行。因為他被.PHONY修飾了。

? ? ? ? 那么系統是怎么知道我們的源文件有沒有被更改呢?

? ? ? ? 我們看一下code.c的文件屬性:

? ? ? ? 當我們的修改文件內容時,第一二個時間屬性會更改,當訪問時,后兩個時間屬性不會更改,但是第一個可能會更改,根據系統而定。當我們修改屬性但是不修改內容時,只有第三個時間屬性會改變。?系統根據我們code和code.c的Modify時間的新舊來判斷是否需要重修編譯。

? ? ? ? 所以說,系統判斷的并不是你內容是否被更改了,只要你編輯了code.c,就算你去掉一個字母,又加上去了,內容沒有改變,在系統眼里,code.c的Modify時間比code的時間新,那么code.c就允許再次被執行。

? ? ? ? 我們在執行make時,他是從上往下掃描的,默認都是實現遇到的第一個目標。所以說對于這兩個目標的前后順序是不能調換的。


?3、推導

? ? ? ? 我們現在用一幅圖來理解makefile是怎么推導的:

? ? ? ? 我們想要生成code就需要code.o,想生成code.o就需要code.s。以此類推。直到我們想生成code.i需要code.c,我們是有code.c的,所以就能生成了code.i,接著反向執行剛才的每個命令。其實系統在檢測到我們某一個指令沒有前置文件時,先把他入棧。只要沒法生成就入棧,知道可以執行了,就依次出棧執行指令。

?????????但是我們實際上不會這樣寫。往往我們習慣這樣寫:

code:code.o                                                                       gcc code.o -o code 
code.o:code.cgcc -c code.c -o code.o.PHONY:clean
#clean:rm -f code

4、Makefile語法拓展

????????接下來我們適度拓展一下makefile的語法:

? ? ? ? 在寫makefile文件的時候,我們可以不直接把各種命令都寫出來,而是以變量的形式來寫。

BIN=code.exe
CC=gcc 
SRC=code.c
OBJ=code.o
CFLAGS=-c
LFLAGS=-o
RM=rm -f$(BIN):$(OBJ)$(CC) $(LFLAGS) $(BIN) $(OBJ)   #或者寫成$(CC) $(LFLAGS) $@ $^                                                                                                                      
$(BOJ):$(SRC)$(CC) $(CFLAGS) $(SRC) #默認生成.o結尾的同名文件.PHONY:clean 
clean:$(RM) $(BIN).PHONY:print 
print:#打印并關閉回顯#使用@關閉回顯@echo $(BIN)@echo $(CC)@echo $(SRC)@echo $(FLAGS)@echo $(RM)

? ? ? ? 我們定義了一堆變量,我們的命令直接用變量代替就可以了,這類似于C語言中的宏或者全局變量,如果我們想換一些命令,比如把gcc換成g++,就直接切換這個變量就可以了。其中,$@代表上一行中冒號左邊的內容,$^代表冒號右邊所有內容。

? ? ? ? 我們可以把代碼繼續"升級":

BIN=code.exe
CC=gcc 
SRC=$(whildcard *.c)
OBJ=$(SRC:.c=.o)
CFLAGS=-c
LFLAGS=-o
RM=rm -f$(BIN):$(OBJ)$(CC) $(LFLAGS) $(BIN) $(OBJ)   #或者寫成$(CC) $(LFLAGS) $@ $^                                                                                                                      
%.o:%.c$(CC) $(CFLAGS) $<.PHONY:clean 
clean:$(RM) $(BIN).PHONY:print 
print:#打印并關閉回顯#使用@關閉回顯@echo $(BIN)@echo $(CC)@echo $(SRC)@echo $(FLAGS)@echo $(RM)

? ? ? ? whilecard是makefile內置的函數,可以實現查找當前目錄下以.c為結尾的文件。當然我們也可以把.c改成.o或者其他的。第二行代碼就是把SRC的所有文件中都換成同名的.o文件。%.o:%.c代表,冒號左側有一百個文件,分別是code1.o,code2.o......,冒號右側也有一百個文件,分別是code1.c,code2.c......,而$<代表著把以上的文件對應著,一個一個的交給.o文件。而&^代表把冒號右邊的統一交給冒號左邊的。因為最后我們只形成一個可執行程序。

? ? ? ? 當然了我們日常練習也沒必要寫的這么復雜。

? ? ? ? 好了,今天的內容就分享到這,我們下期再見!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/91138.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/91138.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/91138.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GaussDB 分布式部署下創建表方法

1、問題現象 分布式集群采用水平分表的方式,將業務數據表的元組/行打散存儲到各個節點內。 2、技術背景 通過全并行數據處理技術和快速定位到數據存儲位置等手段可極大提升數據庫性能,GaussDB分布式部署下可以創建倆種類型表,在做實際業務系統開發時根據業務場景創建不同表。…

Padavan路由器設置DNSmasq的DHCP Option

是下文的拓展&#xff1a;由于更換路由器為Padavan&#xff0c;需要配置DHCP option才能使得AC能夠納管AP 愛快路由器下水星&#xff08;Mercury&#xff09;無線管理器AC跨三層發現AP_愛快管理第三方ap-CSDN博客 DNSmasq全部配置請參考&#xff1a;Man page of DNSMASQ dhcp-…

Ubuntu 22.04 Server 虛擬機初始化配置與優化指南

? Ubuntu 22.04 本地/通用服務器初始化配置清單 1. 設置時區 sudo timedatectl set-timezone Asia/Shanghai2. 防火墻配置&#xff08;UFW&#xff09; sudo ufw enable sudo ufw default deny # 可選放通SSH或其他端口 sudo ufw allow 22/tcp # 查看狀態 sudo ufw status # 禁…

如何在服務器上運行一個github項目

一、事情的緣起 今天一個朋友向我推薦了小紅書上的一個視頻&#xff0c;我看了一下這是一個在演示TypeWords項目的視頻。這個項目是Github上采用vue來編寫的一個開源項目。我進入該項目后看到了給出的樣例網址2study.top&#xff0c;然后到上面看了一下。我發現這是一個通過打…

7.14 Java基礎|String 和StringBuilder

補充注意&#xff1a;1、StringBuilder 的 append 方法可以接收整數類型的參數&#xff0c;并將其自動轉換為字符串后添加到 StringBuilder 中2、該方法適用于所有基本數據類型&#xff08;如 long、double 等&#xff09;和對象&#xff08;通過調用其 toString() 方法&#x…

React 第六十九節 Router中renderMatches的使用詳解及注意事項

前言 renderMatches 是 React Router 的一個高級實用函數&#xff0c;用于根據路由匹配結果渲染對應的組件樹。它提供了對路由渲染過程的底層控制能力&#xff0c;特別適用于自定義路由渲染邏輯的場景。 一、基本概念和功能 renderMatches 函數的作用是將路由匹配結果轉換為 Re…

esp8266-01S實現PPM波形

esp8266-01雖然小眾&#xff0c;但是功能可不能少。因航模需要讓ESP8266-01生成PPM波形。#include <ESP8266WiFi.h> #include <Ticker.h> // 僅用于延時函數替代#define PPM_PIN 2 // 使用 GPIO2 (需斷開串口上傳時的連接) #define CHANNELS 4 // PPM通道數量…

使用 pytest 測試框架構建自動化測試套件之一

pytest 是一個非常靈活且強大的測試框架&#xff0c;它支持簡單的單元測試到復雜的功能測試。顯著特點是其簡潔的語法&#xff0c;可以無需繼承 TestCase 類直接使用函數來編寫測試用例&#xff0c;并通過 assert語句 進行斷言。還支持參數化測試、豐富的插件系統。 pytest自動…

nacos docker 配置

docker.io/nacos 項目中國可用鏡像列表 | 高速可靠的 Docker 鏡像資源 1、Docker 拉取鏡像 docker pull nacos/nacos-server:v2.1.0 2、創建宿主機掛載目錄 mkdir -p /mydata/nacos/logs/ mkdir -p /mydata/nacos/conf/ AI寫代碼 3、啟動nacos并復制文件到宿主機&#xff0…

Django 模板(Template)

1. 模板簡介 作為 Web 開發框架,Django 提供了模板,可以很便利的動態生成 HTML。模版系統致力于表達外觀,而不是程序邏輯。 模板的設計實現了業務邏輯(view)與顯示內容(template)的分離,一個視圖可以使用任意一個模板,一個模板可以供多個視圖使用。 模板包含: HTM…

Word 文字編輯狀態下按回車換行后是非正文格式

在Word里編輯時&#xff0c;按回車后新段落突然變成標題1、標題2這類格式&#xff0c;不再是正文樣式&#xff0c;這通常是因為「正文」的樣式設置出了問題——可能被默認設置成“后續段落自動應用標題1/標題2格式”了。 修改方法很簡單&#xff1a; 找到并打開「正文」樣式的修…

PySide6 UI 靈活性:QToolBar 的浮動與停靠及 QSplitter 的可調整面板

PySide6 UI 靈活性&#xff1a;QToolBar 的浮動與停靠及 QSplitter 的可調整面板 在現代桌面應用程序開發中&#xff0c;提供靈活且用戶友好的界面至關重要。PySide6&#xff08;Qt for Python&#xff09;提供了強大的工具來構建這樣的界面。本文將深入探討兩個關鍵的 PySide6…

B4016 樹的直徑

B4016 樹的直徑 - 洛谷 題目描述 給定一棵 n 個結點的樹&#xff0c;樹沒有邊權。請求出樹的直徑是多少&#xff0c;即樹上最長的不重復經過一個點的路徑長度是多少。 輸入格式 第一行輸入一個正整數 n&#xff0c;表示結點個數。 第二行開始&#xff0c;往下一共 n - 1 行…

【一維 前綴和+差分】

一、一維前綴和 1.1 定義 給定一個數組 a[1..n]&#xff0c;其前綴和數組 pre[1..n] 定義為&#xff1a; pre[i]a[1]a[2]?a[i] pre[i] a[1] a[2] \dots a[i] pre[i]a[1]a[2]?a[i] 即 pre[i] 表示原數組從第 1 項到第 i 項的和。 1.2 構建 int a[N], pre[N]; for (int i …

Spring Boot 雙數據源配置

文章目錄什么是雙數據源&#xff1f;為什么需要雙數據源&#xff1f;核心實現原理完整示例注意什么是雙數據源&#xff1f; 雙數據源是指在一個應用程序中同時配置和使用兩個不同的數據庫連接。比如&#xff1a; 一個連接訂單數據庫&#xff0c;處理業務數據一個連接用戶中心…

【Java】【力扣】102.二叉樹層序遍歷

思路一個輔助隊列&#xff08;初始化隊列&#xff1a;根節點入隊&#xff09;一個節點 出隊&#xff0c;他的左右孩子入隊循環 直到隊列為空舉例代碼public List<List<Integer>> levelOrder(TreeNode root) {if (rootnull){return new ArrayList<List<Intege…

為什么有些PDF無法復制文字?原理分析與解決方案

在日常辦公和學習中&#xff0c;我們經常會從PDF文件中復制文字&#xff0c;用于編輯、引用、整理筆記。但你是否也遇到過這樣的情況&#xff1a;有些PDF中的文字根本無法選中&#xff0c;更無法復制粘貼&#xff1f; 看起來像是“文字”&#xff0c;但操作上卻完全無效——這…

LabVIEW瀏覽器ActiveX事件交互

?程序圍繞 WebBrowser ActiveX 控件&#xff0c;借 “Reg Event Callback” 注冊標題變更回調&#xff0c;“Callback - Title Change.vi” 處理標題數據&#xff0c;“Monitor...” 響應 URL 變更&#xff0c;“Unregister...” 清理資源&#xff0c;實現瀏覽器事件交互與管控…

C++后端面試八股文

一、C 語言基礎與底層原理請解釋 new / delete 和 malloc / free 的區別和聯系&#xff0c;以及使用它們時需要注意什么new 和 delete 是C的??運算符&#xff08;Operator&#xff09;??。這意味著它們可以被類&#xff08;通過 operator new 和 operator delete&#xff0…

基礎分類模型及回歸簡介(一)

一、先搞懂兩個核心任務&#xff1a;分類和回歸咱們生活中總遇到要 “判斷” 或 “預測” 的事&#xff1a;比如看到一個水果&#xff0c;判斷是蘋果還是橘子 —— 這就是分類&#xff08;結果是 “類別”&#xff09;&#xff1b;比如根據西瓜的大小、顏色&#xff0c;猜它能賣…