初始Mkaefile

来源:https://www.cnblogs.com/XLX-0327/archive/2019/03/16/10541466.html
-Advertisement-
Play Games

初識MakefIle 在學習Linux過程中,我越發的覺得Linux系統給了使用者更大的自由,同時也就增加了學習的成本。在gcc下去調試代碼,沒有了熟悉的VS,沒有的人性話的錯誤提示(當然Makefile是有錯誤提示和警告的),也沒有一鍵編譯。全得自己來,但是在這個過程中,你將會熟悉系統的整個編譯過 ...


初識MakefIle

在學習Linux過程中,我越發的覺得Linux系統給了使用者更大的自由,同時也就增加了學習的成本。在gcc下去調試代碼,沒有了熟悉的VS,沒有的人性話的錯誤提示(當然Makefile是有錯誤提示和警告的),也沒有一鍵編譯。全得自己來,但是在這個過程中,你將會熟悉系統的整個編譯過程,以及自己去寫編譯文件的那種快感。今天我將不去重點介紹編譯的過程,重點在GNU的Makefile怎樣寫,算是自己的一個總結。

在此我先說一下,我的Makefile是在https://blog.csdn.net/haoel/article/details/2886陳皓《跟我一起寫Makefile》學到的,裡面講的很是全面有興趣的話可以認真的去讀一遍(內容比較多)。

從認為,Makefile是為生成,編譯好的、可執行的文件(make只是一個根據指定的Shell命令進行構建的工具),可以用來調試,也可以直接運行。有人可能要說用gcc自己寫命令編譯不是更好嗎?但是如果一個項目有成百上千個.c .h文件怎麼整。

從最簡單的說起,一般情況下我們執行Makefile文件直接make就可以了(有些人會進行一些騷操作這就不說了),會生成許多 .o文件最終會有一個或多個可執行文件。

咱們還是直接從例子中去體會吧!

SRC = $(wildcard *.c)
OBJ = $(patsubst %.c,%.o,$(SRC))
target = SendMsg
mode = -g
CC   := gcc
$(target):$(OBJ)
$(CC) $(CFLAGS) $^ -o $(target)

.PHONY:
clean:
rm -rf *.o $(target)

上面的代碼塊就是一個簡單的Makefile,我們一句一句的分析他的語法,等到末尾基本上簡單的Makefile也就會寫了,再去系統的學習Makefile也比較容易(請保持耐心):

整體的看最多的就是賦值符號,細心點會發現有兩種複製方式 “=”和“:=”,這兩個都是賦值符號,符號左邊是變數,右面是所要賦值的內容;

"="是最基本的賦值,如同我們c/c++語言中的賦值一樣;

":="表示覆蓋賦值,也就是同一個變數在如果用":="賦值,則會覆蓋掉之前的內容。

開始看第一句:

SRC = $(wildcard *.c)

之前說過“=”左邊是變數,則"SRC"就是變數,想來我不用解釋變數是什麼意思吧。“=”右邊是所要賦值的內容。

$(wildcard *.c)

在這內容裡面"$"是函數的調用符,也是變數的調用符。就是說你調用一個變數或一個函數時前面要加上"$"來作為標誌,表示這是個函數,或者這是個變數,並且裡面的內容需要用括弧括起來,括弧可以用"{}"也可以用"()"但是最好統一一下不要混用,顯得雜亂。(如果對指針比較熟悉的話很快就應該想到“$”跟指針中的“*”用法很類似,為了提取出對方的內容所要加的標誌符,如果對指針不熟悉可以忽略這句話)。

因此上面那句話也可以這樣寫 ${wildcard *.c};

我們分析一下 $(wildcard *.c) 括弧裡面的內容“*”是通配符的一種,這裡表示所有的以".c"結尾的文件,如果是"*.o"那就是所有的以“.o”結尾的文。“wildcard”是Makefile中的函數,Makefile中是有自己內置函數就像我們c/c++中的庫函數一樣。在這裡“wildcard”函數的作用是來獲取工作目錄下的所有的 “*.c” 文件列表。Makefile中不止這一個函數,還有很多可以自己去看去實踐。

現在整體看“SRC = $(wildcard *.c)”這句話的意思就是,取出當前目錄下所有的".c"文件並且將此賦給 SRC,那麼 SRC 將會代表此目錄下的所有 “.c”文件。

第二句

OBJ = $(patsubst %.c,%.o,$(SRC))

同樣定義“OBJ”變數,調用“patsubst”函數,函數參數為“%.c”,“%.o”,“$(SRC)”;(函數中有多個參數時,以逗號隔開)

“%”也是一中通配符:非空長度任意的非空字元串。(“%”與“*”是有區別的)

“patsubst”函數的作用是將變數“SRC”中所用“.c”文件用“.o”替代。因此OBJ就是很多將尾碼為".c"變成“.o”的文件集合;

第三、四、五句(同類型)

target = SendMsg
mode = -g
CC   := gcc

定義target變數名字角SendMsg;

定義“mode”變數且賦值為“-g”;

定義“CC”變數且賦值為"gcc"

第六、七句

 

$(target):$(OBJ)
$(CC) $(CFLAGS) $^ -o $(target)

這段代碼是核心,它符合Makefile 的編譯規則如下:

target ... : prerequisites ...
          command
          ...
          ...

target是目標文件(可以不止一個),prerequisites是目標的依賴文件(可以不止一個),(command)生成目標文件所需要執行的命令。

“目標文件”:即最終生成的可執行的文件;

“目標依賴文件”:即生成目標文件所需要的文件;

“命令”:即處依賴文件到目標文件的過程。註意命令需要以開頭必須是table,這是命令的標識。

現在回過頭去看我們的程式,五六句:

$(target),表示所要生成的目標文件;

$(OBJ),表示生成目標文件所需的依賴文件;

$(CC) $(mode) $^ -o $(target),處理生成目標的命令;

{命令中"$^"是自動化變數終端的一種,表示所有依賴文件的集合,如果有重覆的依賴文件,則去掉重覆的依賴文件(自動化變數:會將模式變數一次取出的一種機制變數,自動化變數有好幾個,可以去詳細解讀)};

重點:在Makefile中是以時間戳為參考標準去更新文件的,假若依賴文件中任意一個文件比目標文件的時間戳新,則再次編譯目標文件,直到目標文件的時間戳為最新為止。

則五六句代碼的理解就是:

以OBJ為依賴文件生成target文件,命令規則是“gcc -g $^ -o target”(假設懂 gcc 的基本語法)。

八、九、十句

.PHONY:
clean:
rm -rf *.o $(target)

這個小模塊的目的是為了,清除所有的已經編譯後的目標文件;在調試時改變更改程式後需要重新編譯,那麼將會生成新的編譯文件;為了比避免出錯,一般先會清除先前的編譯文件,在重新生成編譯文件。

在這個模塊中“clean”時一條偽命令,為什麼這樣說,是因為它不會再編譯的過程中執行,只有使用語句 “make clean”時才會執行此命令。其中“.PHONY”是偽命令的標識,可以選擇不寫。

最後“rm -rf *.o $(target)”,想來應該也都清楚了,清除所有以“.o”和“target”文件。

至此整個Makefile結束。此段程式雖然簡短但是五臟俱全,其中涉及很多Makefile的知識點,可以由此去逐點擊破,對Makefile做個詳細的瞭解。

如有問題請指出,我修改……一起進步!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.上次介紹了一些常用的系統命令,這次又總結了一些小命令,故分享一下: 網卡地址查詢的命令: 2.查看系統的內核以及架構內容: 先查詢它的文檔幫助: -a參數表示print all 查看系統的負載數,說句笑話,如果這個數超過5,就會睡不著覺了...,肯定是系統過載了,得想方法解決,否則嚴重會導致系統 ...
  • 一、網路會話 使用 con-name 參數指定公司所使用的網路會話名稱company,然後依次用ifname 參 數指定本機的網卡名稱,用autoconnect no 參數設置該網路會話預設不被自動激活,以及用ip4 及gw4 參數手動指定網路的IP 地址: nmcli connection add ...
  • 1 執行查看幫助命令 man:獲取幫助信息 空格鍵:向下翻一頁 PgGe down:向下翻一頁 PaGe up:向上翻一頁 home:直接前往首頁 end:直接前往尾頁 /:從上至下搜索關鍵詞 ?:從下至上搜索關鍵詞 n:定位搜索到的關鍵詞 q:退出幫助文檔 2 常用系統工作命令 echo [字元串 ...
  • 今天在進行項目聯繫的時候,啟動在待機的虛擬機,發現虛擬機的網路設置又出現了問題。 我以為像往常一樣重啟網卡服務就能成功,但是它卻報了Job for iptables.service failed because the control process exited with error code。 ...
  • Node Exporter 1. Node Exporter Scrape Time type: GraphUnit: secondsLabel: Seconds{{collector}} - 各個收集器持續時間metrics: node_scrape_collector_duration_seco ...
  • "Learn Tmux in Ten Minutes" "Layouts 佈局" "Window 視窗" "Pane 窗格" "CONFIGURATION" Learn Tmux in Ten Minutes Layouts 佈局 1. Server 服務 2. Session 會話 3. Wind ...
  • 本節內容主要介紹Linux操作系統的主要特性,包括Linux與Windows操作系統的主要區別;Linux系統的分類;開發環境的推薦;Linux操作系統的安裝;Linux系統下開發環境的安裝和配置。 1、Linux和Windows的主要不同點: 1)開放性的不同。Linux系統自從1991年10月5 ...
  • 人工智慧下智能家居解決方案 今天先到這兒,希望對您技術領導力, 企業管理,物聯網, 系統架構設計與評估,團隊管理, 項目管理, 產品管理,團隊建設 有參考作用 , 您可能感興趣的文章: 2017-2018年Scrum狀態調查報告2016年測試狀態調查2017年IT行業測試調查報告項目管理-習慣發生範... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...