makefile 編寫規則

1.概念

1.1 什么是makefile

Makefile 是一種文本文件,用于描述軟件項目的構建規則和依賴關系,通常用于自動化軟件構建過程。它包含了一系列規則和指令,告訴構建系統如何編譯和鏈接源代碼文件以生成最終的可執行文件、庫文件或者其他目標文件。

1.2 使用makefile的優點

Makefile 主要用于管理大型項目的構建過程,它可以:

  1. 自動檢測源代碼文件的變化,只編譯發生變化的文件,以提高構建效率。
  2. 根據依賴關系自動構建所需的目標文件,無需手動管理編譯順序。
  3. 支持通過簡單的命令來進行構建、清理和其他任務,提高了項目的可維護性和可重復性。
  4. 可以輕松地添加自定義的構建規則和操作,滿足特定項目的需求。

Makefile 使用一種稱為 Make 的構建工具來解析和執行其中的規則。Make 工具會根據 Makefile 中定義的規則和依賴關系,確定需要重新構建的目標文件,并執行相應的命令來完成構建過程。

2.演變的過程

2.1 gcc編譯

在我們平常linux下編譯文件的時候通過gcc全部編譯鏈接生成可執行的文件

這樣編譯導致的后果是每次改動某一個代碼,其他文件都要跟著編譯,非常的繁瑣每次,那我們有什么更簡單的方法嗎,有

2.2 gcc單個文件編譯后鏈接

很明顯,大家已經看到了,雖然有一點優化,但不多。這也是不可取的。這時候在linux編譯鏈接的時候就出現了makefile文件。

2.3 Makefile的工作原理

Makefile 的工作原理主要涉及兩個部分:規則(rules)和依賴關系(dependencies)。Makefile 中包含了一系列規則,每個規則描述了如何生成一個或多個目標文件,并指定了生成目標文件所需的依賴文件和生成命令。Make 工具會根據這些規則來自動執行構建過程。
下面是 Makefile 的工作原理的詳細解釋:

1.目標和依賴關系定義:

  • Makefile 中的每個規則由一個或多個目標(targets)和其對應的依賴關系(dependencies)組成。目標通常是文件名,代表生成的目標文件或執行的操作。依賴關系是目標文件所依賴的文件列表,通常是源文件或其他目標文件。
  • 每個規則的格式通常為
?target: dependenciescommand
  • target?是目標文件或操作的名稱,dependencies?是生成?target?所需的依賴文件列表,command?是生成?target?的命令。
    ? 檢查文件時間戳
    • 在執行 Makefile 時,Make 工具會檢查每個目標文件和其依賴文件的時間戳,以確定哪些文件需要重新生成。
    • 如果目標文件不存在,或者其時間戳早于任何一個依賴文件的時間戳,那么 Make 工具會執行生成目標文件的命令。
    • 執行生成命令

      • 當確定需要重新生成目標文件時,Make 工具會執行該目標的生成命令。生成命令通常是編譯源文件、鏈接目標文件或執行其他操作的命令。
      • Make 工具會按照 Makefile 中規定的順序依次執行每個目標的生成命令,直到所有目標文件都被成功生成。
    • 遞歸處理依賴

      • 如果一個目標文件的依賴文件也是其他目標文件,則 Make 工具會遞歸處理這些依賴關系,確保所有依賴文件都被生成。
    • 增量構建

      • Make 工具會根據文件的時間戳判斷哪些文件需要重新生成,從而實現增量構建。只有發生了變化的文件及其依賴文件才會重新生成,提高了構建效率。
    • 通過這樣的方式,Makefile 提供了一種簡潔而有效的方法來管理項目的構建過程,自動化了源代碼的編譯、鏈接和其他構建操作,使得項目的開發和維護更加高效和可靠。

      2.4 初階Makefile文件

    • 這個版本的Makefile雖然有了一定的用途,但還是無法解決文件太多的問題。如何解決這一難題呢,我們接著向下看
    • 2.5 中階Makefile文件


    • 雖然這個看起來已經比較完善了,但是依舊在文件太多的時候,會出現很多編譯.c的文件,那有沒有什么辦法,讓其不用這么麻煩呢
    • 2.6 后階Makefile文件

    • CXX = gcc
      TARGET = aio
      OBJ = BintrayTree.o Queue.o test.oCXXFLAGS = -c -Wall$(TARGET) : $(OBJ)
      # $@ 表示目標文件
      # $^ 所依賴文件$(CXX) -o $@ $^
      # % 是一個通配符,用于匹配任意長度的字符序列
      %.o : %.c
      # $< 第一個依賴文件$(CXX) $(CXXFLAGS) $< -o $@# .PHONY防止出現于clear重名的文件而發生歧義
      .PHONY: clear
      # make clear 執行下面的命令(刪除后綴.o和編譯鏈接后的目標文件)
      clear:rm -r *.o $(TARGET)

    • 這樣我們,其實已經足夠優化了,但是我們任然有可優化的地方,比如,我們可不可不列出鏈接的依賴文件,當然可以的

    • 2.7 終極版本

    • 到這里,我們就可以很清楚的認識到Makefile的優化過程
      CXX = gcc
      TARGET = aio
      #將后綴為.c的文件放入windcard中
      SRC = $(wildcard *.c)
      #路徑替換,將SRC中的.c替換為.o
      OBJ = $(patsubst %.c, %.o, $(SRC))CXXFLAGS = -c -Wall$(TARGET) : $(OBJ)
      # $@ 表示目標文件
      # $^ 所依賴文件$(CXX) -o $@ $^
      # % 是一個通配符,用于匹配任意長度的字符序列
      %.o : %.c
      # $< 第一個依賴文件$(CXX) $(CXXFLAGS) $< -o $@# .PHONY防止出現于clear重名的文件而發生歧義
      .PHONY: clear
      # make clear 執行下面的命令(刪除后綴.o和編譯鏈接后的目標文件)
      clear:rm -r *.o $(TARGET)


      3,Makefile的編碼規則

    • 我們之前已經有所了解Makefile的編碼規則,但是在這里我還是覺得有必要總體講一下

      在編寫 Makefile 時,遵循一些編碼規則可以使其更加清晰、易于維護和跨平臺。下面是一些常見的 Makefile 編碼規則:

      1.縮進使用Tab鍵:
      Makefile 中命令行必須使用 Tab 鍵進行縮進,而不是空格。這是因為 Make 工具默認使用 Tab 鍵作為命令行的縮進標識,使用空格可能會導致 Make 解析錯誤。
      2.目標和依賴關系之間的冒號:
      目標(target)和依賴關系(dependencies)之間使用冒號(:)分隔。冒號前面是目標,后面是依賴關系。
      3.命令行前面的Tab鍵:
      在每個規則中,命令行必須以 Tab 鍵開頭,表示該命令是該規則的執行命令。除了注釋以外,任何其他以 Tab 鍵開頭的行都被視為命令。
      4.變量使用大寫字母:
      為了與命令和目標區分開,通常將變量使用大寫字母命名。例如:CC = gcc。
      5.使用變量代替硬編碼的命令和路徑:
      使用變量來代替硬編碼的命令和路徑,使得 Makefile 更加靈活和可移植。例如,將編譯器命令使用變量表示:CC = gcc,然后在規則中使用 $(CC) 來引用。

    • 6.使用偽目標:
      對于不產生實際文件的操作(如清理、安裝等),使用偽目標(.PHONY)來定義。這樣可以確保即使存在同名文件,也不會誤導 Make 工具。例如:.PHONY: clean。
      7.注釋使用 #:
      使用 # 符號來添加注釋,使得 Makefile 更具可讀性。注釋可以幫助理解 Makefile 中每個規則的作用。
      8.模塊化設計:
      將 Makefile 模塊化,分成多個小的 Makefile 文件,然后通過 include 指令引入。這樣可以提高 Makefile 的可維護性和可讀性,減少重復代碼。
      9.合理使用條件語句:
      可以使用條件語句(如 ifeq、ifdef 等)來根據不同的條件執行不同的規則或命令,以實現更靈活的構建過程。
      10.跨平臺兼容性:
      考慮到不同平臺下的路徑分隔符和命令格式的差異,編寫具有跨平臺兼容性的 Makefile。可以使用自動化工具或條件語句來處理不同平臺下的差異。

      遵循這些規則可以使 Makefile 更加規范、易讀和易于維護,有助于提高項目的構建效率和可靠性。

      4,每期一問

    • 4.1 上期答案

      // 計算樹的高度
      int getHeight(struct TreeNode* root) {if (root == NULL) {return 0;}int leftHeight = getHeight(root->left);int rightHeight = getHeight(root->right);return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
      }// 判斷是否是平衡二叉樹的輔助函數
      bool isBalancedHelper(struct TreeNode* root) {if (root == NULL) {return true;}int leftHeight = getHeight(root->left);int rightHeight = getHeight(root->right);if (abs(leftHeight - rightHeight) <= 1 && isBalancedHelper(root->left) && isBalancedHelper(root->right)) {return true;}return false;
      }// 判斷是否是平衡二叉樹
      bool isBalanced(struct TreeNode* root) {return isBalancedHelper(root);
      }

      4.2 本期問題. - 力扣(LeetCode)

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

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

相關文章

Node.js知識點以及案例總結

思考&#xff1a;為什么JavaScript可以在瀏覽器中被執行 每個瀏覽器都有JS解析引擎&#xff0c;不同的瀏覽器使用不同的JavaScript解析引擎&#xff0c;待執行的js代碼會在js解析引擎下執行 為什么JavaScript可以操作DOM和BOM 每個瀏覽器都內置了DOM、BOM這樣的API函數&#xf…

開源模型應用落地-食用指南-以最小成本博最大收獲

一、背景 時間飛逝&#xff0c;我首次撰寫的“開源大語言模型-實際應用落地”專欄已經完成了一半以上的內容。由衷感謝各位朋友的支持,希望這些內容能給正在學習的朋友們帶來一些幫助。 在這里&#xff0c;我想分享一下創作這個專欄的初心以及如何有效的&#xff0c;循序漸進的…

STM32F103C8T6 HC-SR04超聲波模塊——超聲波障礙物測距(HAl庫)

超聲波障礙物測距 一、HC-SR04超聲波模塊&#xff08;一&#xff09;什么是HC-SR04&#xff1f;&#xff08;二&#xff09;HC-SR04工作原理&#xff08;三&#xff09;如何使用HC-SR04&#xff08;四&#xff09;注意事項 二、程序編寫&#xff08;一&#xff09;CubeMX配置1.…

2024全新Langchain大模型AI應用與多智能體實戰開發

2024全新Langchain大模型AI應用與多智能體實戰開發 LangChain 就是一個 LLM 編程框架&#xff0c;你想開發一個基于 LLM 應用&#xff0c;需要什么組件它都有&#xff0c;直接使用就行&#xff1b;甚至針對常規的應用流程&#xff0c;它利用鏈(LangChain中Chain的由來)這個概念…

Facebook之魅:數字社交的體驗

在當今數字化時代&#xff0c;Facebook作為全球最大的社交平臺之一&#xff0c;承載著數十億用戶的社交需求和期待。它不僅僅是一個簡單的網站或應用程序&#xff0c;更是一個將世界各地的人們連接在一起的社交網絡&#xff0c;為用戶提供了豐富多彩、無與倫比的數字社交體驗。…

C++實現基礎二叉搜索樹(并不是AVL和紅黑樹)

本次實現的二叉搜索樹并不是AVL數和紅黑樹&#xff0c;只是了解流程和細節。 目錄 二叉搜索樹的概念K模型二叉搜索樹的實現二叉搜索樹的架構insert插入find 查找中序遍歷Inorder刪除earse替換法的思路情況一 &#xff1a;假如要刪除節點左邊是空的。在左邊時在右邊時 情況二&a…

文心智能體,零代碼構建情感表達大師智能體

前言 隨著智能體技術的突飛猛進&#xff0c;各行各業正迎來前所未有的變革與機遇。智能體&#xff0c;作為人工智能領域的重要分支&#xff0c;以其自主性、智能性和適應性&#xff0c;正逐步滲透到我們生活的每一個角落&#xff0c;成為推動社會進步和科技發展的新動力。 為了…

軟考 系統架構設計師系列知識點之雜項集萃(20)

接前一篇文章&#xff1a;軟考 系統架構設計師系列知識點之雜項集萃&#xff08;19&#xff09; 第28題 在單元測試中&#xff0c;&#xff08; &#xff09;。 A. 驅動模塊用來調用被測模塊&#xff0c;自頂向下的單元測試中不需要另外需要編寫驅動模塊 B. 樁模塊用來模擬被…

visual studio 2022 ssh 主機密鑰算法失敗問題解決

 Solution - aengusjiang 問題&#xff1a; I follow the document, then check sshd_config, uncomment“HostKey /etc/ssh/ssh_host_ecdsa_key” maybe need add the key algorithms: #HostKeyAlgorithms ssh-ed25519[Redacted][Redacted]rsa-sha2-256,rsa-sha2-512 Ho…

Redis常用命令——String篇

前面我們講解了一些 Redis 的全局命令&#xff08;Redis常用基本全局命令&#xff09;。所謂全局命令&#xff0c;就是可以匹配任意一個數據結構進行使用。但是不同的數據結構&#xff0c;也有自己的操作命令。本篇文章主要講解的是 String 的操作命令&#xff0c;希望會對你有…

ClickHouse課件

列式存儲數據庫&#xff1a;hbase clickhouse 簡介 ClickHouse入門 ClickHouse是俄羅斯的Yandex于2016年開源的列式存儲數據庫&#xff08;DBMS&#xff09;&#xff0c;使用C語言編寫&#xff0c;主要用于在線分析處理查詢&#xff08;OLAP&#xff09;&#xff0c;能夠使用…

2024年電工杯B題論文首發+問題一論文代碼分享

問題一論文代碼鏈接&#xff1a;https://pan.baidu.com/s/1kDV0DgSK3E4dv8Y6x7LExA 提取碼&#xff1a;sxjm --來自百度網盤超級會員V5的分享 基于數據分析的大學生平衡膳食食譜的優化設計及評價 摘要 大學時期不僅是學術學習和身體成長的關鍵階段&#xff0c;更是青年學生…

supermind讀寫自選股的功能來了

python custom_sector() # 返回所有板塊的dataframecustom_sector(板塊1) # 返回 板塊1 的屬性和股票custom_sector(板塊1, append, [000001.SZ]) # 增加板塊1的股票列表custom_sector(板塊1, pop, [000001.SZ]) # 移除板塊1的股票custom_sector(板塊1, remove) # 刪除板塊1zxg…

Hsql每日一題 | day03

前言 就一直向前走吧&#xff0c;沿途的花終將綻放~ 題目&#xff1a;打折日期交叉問題 如下為平臺商品促銷數據&#xff1a;字段為品牌&#xff0c;打折開始日期&#xff0c;打折結束日期 brand stt edt oppo,2021-06-05,2021-06-09 oppo,2021-06-11,2021-06-21 vivo,…

Java中流的概念細分

按流的方向分類&#xff1a; 輸入流&#xff1a;數據流向是數據源到程序&#xff08;以InputStream、Reader結尾的流&#xff09;。 輸出流&#xff1a;數據流向是程序到目的地&#xff08;以OutputStream、Writer結尾的流&#xff09;。 按處理的數據單元分類&#xff1a; 字…

PVE 虛擬機環境下刪除 local-lvm分區

1、刪除邏輯卷 lvremote pve/data 2、擴展邏輯卷 lvextend -l 100%FREE -r pve/root 3、 修改存儲目錄內容 點擊 Datacenter - Storage &#xff08;1&#xff09;刪除local-lvm分區 &#xff08;2&#xff09;編輯local分區&#xff0c;在內容一項中勾選所有可選項。

mysql 兩個不同字段的表導入數據

下面這個場景就是A表的字段和B表的字段不一樣&#xff0c;但是現在我想把b表中的數據導入到A表里面&#xff0c;下面是導入公式如下&#xff1a; 語法&#xff1a; 將SYS_ORG表中的數據導入到sys_depart&#xff0c;但是這兩個表的字段不一樣&#xff0c;在()里面填寫要新增數據…

Spring Boot 3.3 正式發布,王炸級更新,應用啟動速度直接起飛!

最新消息&#xff0c;Spring Boot 一次性發布了 3 個版本&#xff1a; 3.3.0 3.2.6 3.1.13 Spring Boot 3.3 正式發布了&#xff0c;3.1.x 在前幾天也停止維護了。 最新的支持版本如下&#xff1a; 從路線圖可以看到每個版本的終止時間&#xff0c;每個版本的生命周期只有…

安徽大學數學科學學院教授陳昌昊

男&#xff0c;本&#xff08;2005-2009&#xff09;、碩&#xff08;2009-2012&#xff09;學位都在湖北大學獲得&#xff0c;博士學位在芬蘭獲得&#xff08;2012-2016&#xff09;&#xff0c;博士后分別在澳大利亞&#xff08;2016-2019&#xff09;、香港&#xff08;2020…

vue3中el-form表單校驗,再點擊提交按鈕的時候通過校驗才進行提交

vue3中el-form表單校驗&#xff0c;再點擊提交按鈕的時候通過校驗才進行提交 一、前言1、案例 一、前言 在 Vue 3 中&#xff0c;可以使用 Element UI 的 <el-form> 組件配合 <el-form-item> 來實現表單的必填項校驗&#xff0c;并在提交時根據校驗結果來決定是否…