【Linux】make/Makefile --- 自動化構建項目的工具

目錄

一、make/Makefile的簡單使用

二、Makefile 的語法規則

三、實現的原理

3.1 make/Makefile識別文件新舊

3.2?.PHONY修飾的偽目標總是被執行

3.3?make/Makefile是具有依賴性的推導能力的

四、語法技巧

五、注意事項


Linux中自動化構建項目最簡單的方式:make/Makefile
make:是一個命令
Makefile:是一個在當前目錄下存在的一個具有特定格式的文本文件。
(Makefile首字母可以小寫,但建議使用大寫)

makefile文件中,保存了編譯器和鏈接器的參數選項,并且描述了所有源文件之間的關系。make程序會讀取makefile文件中的數據,然后根據規則調用編譯器,匯編器,鏈接器產生最后的輸出。

一、make/Makefile的簡單使用

  • 創建Makefile
    touch Makefile
  • ?編寫Makefile:
    vim Makefile
  • 編寫要生成的可執行程序mybin和項目清理clean:
  • 使用make命令生成可執行程序
    make
  • 使用make命令進行項目清理
    make clean

二、Makefile 的語法規則

Makefile 中包括依賴關系(目標依賴)依賴方法(命令)
下面是 Makefile 中一些要素的基本語法規則:

目標:指定了要生成的文件或要執行的操作名。

例如:上面的mybin就是要生成的目標文件名

依賴:指定了目標所依賴的文件或其他目標。

例如:上面的test.c 是目標文件依賴的文件。一個目標文件可以有多個依賴文件,用空格分開。
目標和依賴構成了依賴關系

命令(依賴方法):包含了生成目標所需的具體操作步驟,通常是一條或多條 Shell 命令。

第二行必須以Tab開頭,不能是空格,緊接著是生成目標文件的命令。

例如:上面的gcc test.c -o mybin -std=c99
(gcc test.c -o mybin 與gcc -o mybin test.c 相同,-o后面跟目標文件名即可)

偽目標:偽目標是指在 Makefile 中.PHONY定義的不對應實際文件的目標,通常用于執行一些特定的操作,比如清理臨時文件。?
例如:上面的clean目標用于執行清理操作,刪除mybin文件。
注:make默認執行的是第一行的命令,一般把清理工作放在最后面。

注釋:使用 # 符號來添加注釋,注釋從 # 開始一直到該行的末尾。

變量:可以使用變量來存儲命令選項、編譯器名稱等信息,然后在規則中引用這些變量。
語法格式:VAR_NAME = value

條件判斷:可以使用條件判斷(ifeq、ifdef 等)來根據不同的條件執行不同的命令。

函數:Makefile 支持一些內置函數,可以用于字符串處理、文件查找等操作。

使用make和make clean,就可以方便地完成項目自動化構建和清理。

三、實現的原理

3.1 make/Makefile識別文件新舊

make命令不是每次都會重新編譯,只有更改過的文件才會重新編譯。(提高編譯效率)
若源代碼沒有更改也重新編譯,那么每次預處理編譯匯編鏈接的時間比較長,成本高。

make/Makefile是如何知道文件更改過的?
答:通過源文件的修改時間和形成的可執行程序(也是文件)的修改時間做對比

重新編譯的本質:重新寫入一個二進制的可執行文件(bin文件),文件的修改時間會跟著更改。

  • 第一次的時候,一定是先有源文件,才有bin文件。
    源文件的修改時間 < bin文件的修改時間
  • 第二/n次的時候,我們對源文件做任何修改的時候,
    源文件的修改時間 > bin文件的修改時間
    ?????
    重新編譯形成可執行

大部分情況下重新編譯都沒問題,問題的產生不僅僅是修改新文件就能解決的。有些歷史問題需要重新清理項目才可以解決。

文件 = 內容 + 屬性,所以文件的ACM時間肯定與內容或屬性有關。

Access(最近訪問時間):普通文本文件打開:cat、vim,或者對目錄進入、ls顯示等

Modify?(對內容修改):當文件內容發生變化時,修改時間(mtime)會被更新。

Change(對屬性修改):當文件的權限、所有者、鏈接數或文件名發生變化時,更改時間(ctime)會被更新。

注:

  • 三種時間會出現聯動,例如對內容修改,Access和Change時間也會更改。
  • Access時間不是每次訪問時都更改,讀取查看文件操作最頻繁,如果每次都改的話,比較浪費時間,因為文件一般都在磁盤存放,更改時間的本質就是訪問磁盤。但是訪問磁盤的速度比較慢(相對cpu而言),讀取查看文件操作又是很頻繁,如果每次都更改Access time的話,系統效率就會降低很多,所以就會隔一段時間更改一次。
    (具體間隔時間和是否間隔,由內核版本決定)
  • 使用touch命令可以修改ACM時間。
    -a 選項? 修改Access時間,但同時也修改了change時間,因為access時間也是屬性。
    -m 選項 修改Modify時間,但是Change時間也會跟著改。

綜上,make?是通過對比源文件和bin文件的Modify時間確定文件新舊的。

3.2?.PHONY修飾的偽目標總是被執行

通過時間對比,可以做到不讓有些代碼進行重新編譯(不讓某些操作進行)。

總是被執行就是:不考慮其他任何問題,總是執行依賴方法,不會被任何情況攔截
(make/makefile不再依靠時間對比了,直接執行對應的命令)

例如:mybin被.PHONY修飾,則多次make時,都會執行gcc命令,把可執行程序重新形成。

3.3?make/Makefile是具有依賴性的推導能力的

上一節講到gcc編譯生成一個可執行程序需要經過預處理、編譯、匯編和連接,中間會產生.i,.o,.s文件。但是在上面的操作中都沒有生成中間文件。
但是我們知道一件事:生成bin文件,就需要對應的.o文件。

以Makefile的推導過程如下:(類似一個棧結構)

生成了臨時文件 code.o code.s code.i

以上寫法只是為了了解編譯推導的過程,實際上不推薦使用。

建議直接用gcc形成可執行!


四、語法技巧

  1. Makefile里面的指令執行時會自動回顯出來,可以在前面加上?@?符號使其不回顯,不顯示指令信息。
  2. 可以使用?echo?添加一些輸出信息。
  3. 依賴方法可以不止一個,用回車隔開。
  4. makefile中用?#?注釋
  5. makefile中可以編寫變量,表達式之間不建議帶空格
    通過 $(變量名)?來引用變量的值。

    用途:之后如果想使用g++,只需要把gcc改成g++,mybin改成mybin.exe
  6. 可以用 #^ 符號代替依賴關系中的所有內容,#@?代替要形成的目標文件

?


五、注意事項

  • 首次make時,make掃描Makefile文件時,自頂向下。如果發現第一個目標文件,則嘗試根據該目標及其依賴關系構建目標文件。(默認一次形成一個最終的目標文件)
  • 偽目標文件沒有實際的依賴關系,每次都會執行其定義的命令,而不是構建文件。
  • Makefile里主要包含了五個東西:顯式規則、隱晦規則、變量定義、文件指示和注釋。
    顯式規則說明了,如何生成一個或多個目標文件。
  • make有自動推導的功能,所以隱晦的規則可以讓我們比較粗糙地簡略地書寫makefile,比如源文件與目標文件之間的時間關系判斷。
  • 在makefile中可以定義變量,當makefile被執行時,其中的變量都會被擴展到相應的引用位置上,通常使用 $(var) 表示引用變量。
  • 文件指示。在一個makefile中引用另一個makefile,類似C語言中的include;
    ".mk" 是用來表示 Makefile 文件的擴展名。
    include path/to/another_makefile.mktarget: dependencycommand
    
  • 注釋,makefile中可以使用 # 在行首表示行注釋
  • 默認的情況下,make命令會在當前目錄下按順序找尋文件名為"GNUmakefile"、"makefile"、"Makefile"的文件。

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

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

相關文章

python樂觀鎖和悲觀鎖

在并發編程中&#xff0c;鎖是一種常用的機制&#xff0c;用于保護共享資源的訪問。樂觀鎖和悲觀鎖是兩種不同的鎖機制。 樂觀鎖&#xff1a;不會一開始就加鎖&#xff0c;在更新的時候&#xff0c;判斷一下在此期間別人是否修改了數據&#xff0c;若修改了不執行此操作&#…

軟件質量:建立信心的十大指標

. Bug 數量——可能按優先級或嚴重性排列 一般來說&#xff0c;錯誤的數量會在項目生命周期的中期開始增加。在截止日期之前的幾天或幾周&#xff08;取決于項目的規模&#xff09;&#xff0c;團隊將集中精力減少 bug 的數量&#xff0c;直到 bug 的數量達到某種漸近線。這個漸…

Nginx基礎篇:Nginx搭建、Nginx反向代理、文件服務器部署配置。

Nginx Linux系統安裝以及反向代理的配置 簡介優點nginx 環境安裝常用Nginx 命令nginx 文件服務器搭建 簡介 Nginx (engine x) 是一個高性能的HTTP和反向代理web服務器&#xff0c;同時也提供了IMAP/POP3/SMTP服務。Nginx是由伊戈爾賽索耶夫為俄羅斯訪問量第二的Rambler.ru站點…

如何把kubernetes pod中的文件拷貝到宿主機上或者把宿主機上文件拷貝到kubernetes pod中

1. 創建一個 Kubernetes Pod 首先&#xff0c;下面是一個示例Pod的定義文件&#xff08;pod.yaml&#xff09;&#xff1a; cat > nginx.yaml << EOF apiVersion: v1 kind: Pod metadata:name: my-nginx spec:containers:- name: nginximage: nginx EOF kubectl app…

LabelImg的使用及注意事項

LabelImg是一款開源的圖像標注工具&#xff0c;它主要用于標注目標檢測、語義分割和圖像分類等深度學習中需要的數據集。通過使用LabelImg&#xff0c;用戶可以快速、準確地為圖片中的目標添加標注信息&#xff0c;從而建立數據集。 使用步驟&#xff1a; 下載LabelImg&#x…

java測試rtsp地址連接狀態,測試RTSP連接狀態是否成功,java如何測試rtsp地址連接是否成功

import java.net.Socket; import java.net.URI; import java.net.URISyntaxException;/*** ClassName: RTSPUtils* Description: 測試RTSP連接狀態* Author: zhanghui* Date: 2023-12-08* Version: 1.0**/ public class RTSPUtils {private static final int TIMEOUT_MS 10000…

我的創作紀念日(2周年)

機緣 在進入大學之前&#xff0c;完全沒有聽說過CSDN&#xff0c;第一次使用CSDN應該是搜C語言如何學&#xff0c;或者是和C語言相關的其他內容 因為我本人是學計算機專業的&#xff0c;大一剛開學因為疫情延遲了開學時間&#xff0c;老師線上教課&#xff0c;但是我之前是完…

永磁同步電機反電動勢系數怎么算?磁鏈強度怎么算?轉矩系數怎么算?

在進行永磁同步電機simulink仿真時&#xff0c;一個關鍵參數就是永磁體磁鏈強度&#xff0c; 實際上在simulink中&#xff0c;永磁體磁鏈強度/反電動勢系數/轉矩系數這三個是放一起的&#xff0c;這是因為他們都可互相算出來。 Torque constat (Nm/A) 轉矩系數 1.5 * Np *…

在瀏覽器中存儲token的最佳實踐

在瀏覽器中存儲token的最佳實踐 Web 應用程序不是靜態站點&#xff0c;而是靜態和動態內容的精心組合。更常見的是&#xff0c;Web 應用程序邏輯在瀏覽器中運行。該應用程序不是從服務器獲取所有內容&#xff0c;而是在瀏覽器中運行 JavaScript&#xff0c;從后端 API 獲取數據…

Tomcat部署開源站點JPress

前言 JPress使用Java開發&#xff0c;是我們常見的開源博客系統。JPress是一個開源的WordPress插件&#xff0c;它提供了一個簡單而強大的方式來創建企業級站點。該插件包括許多特性&#xff0c;例如主題定制、頁面構建器、性能優化、SEO、安全、電子商務和社交媒體整合等。使用…

Linux卸載MySql(簡潔版)

安裝MySql https://blog.csdn.net/tongxin_tongmeng/article/details/128263398 停止服務 service mysql stop 刪除服務 chkconfig --del mysql 刪除目錄 rm -rf /opt/mysql 刪除配置 rm -f /etc/my.cnf 刪除啟動腳本 rm -f /etc/init.d/mysql 刪除用戶和組 userdel mysql &am…

C_1練習題答案

1.在一個C程序中() A. main函數必須出現在所有函數之前 B. main函數可以出現在任何地方 C. main函數必須出現在所有函數之后 D. main 函數必須出現在固定位置 B 2.下列不合法的用戶標識符是() A. j2_KEY B. Double C. 4d_a D.8 C 3,在“文件包含”預處理語句的使用過程…

thinkphp6入門(12)-- 一對一關聯模型

定義一對一關聯&#xff0c;例如&#xff0c;一個用戶都有一個個人資料。 一、兩表 1.用戶表:user 2.工作經驗表&#xff1a;work_experience user表的id關聯work_experience表的user_id。 注意看&#xff0c;user_id1的有2條工作經驗 二、數據模型 主表模型&#xff1a;…

Linux 定時任務備份MySQL數據庫

Linux 定時任務基本知識 crontab yum install crontabs &#xff08;安裝 crontabs&#xff09; systemctl enable crond &#xff08;設為開機啟動&#xff09; systemctl start crond&#xff08;啟動crond服務&#xff09; systemctl status crond &#xff08;查看狀態&a…

STM32F407-14.3.9-02輸出比較模式

輸出比較模式 輸出比較模式生成波形時 當采用上升沿或下降沿計數時&#xff0c;更改ARR的值可改變周期&#xff1b; 更改CCRx的值會影響到生成波形的相位。波形的占空比永遠50% 當采用中心對齊模式時&#xff0c; 更改ARR的值可以改變周期&#xff0c;更改CCRx的值可以改…

操作系統考研筆記(王道408)

文章目錄 前言計算機系統概述OS的基本概念OS的發展歷程OS的運行機制OS體系結構OS引導虛擬機 進程和線程進程和線程基礎進程進程狀態進程控制進程通信線程線程實現 CPU調度調度的層次進程調度細節調度算法評價指標批處理調度算法交互式調度方法 同步與互斥基本概念互斥互斥軟件實…

Plantuml之類圖語法介紹(十六)

簡介&#xff1a; CSDN博客專家&#xff0c;專注Android/Linux系統&#xff0c;分享多mic語音方案、音視頻、編解碼等技術&#xff0c;與大家一起成長&#xff01; 優質專欄&#xff1a;Audio工程師進階系列【原創干貨持續更新中……】&#x1f680; 優質專欄&#xff1a;多媒…

STM32基于USB串口通信應用開發

?作者簡介&#xff1a;熱愛科研的嵌入式開發者&#xff0c;修心和技術同步精進&#xff0c; 代碼獲取、問題探討及文章轉載可私信。 ? 愿你的生命中有夠多的云翳,來造就一個美麗的黃昏。 &#x1f34e;獲取更多嵌入式資料可點擊鏈接進群領取&#xff0c;謝謝支持&#xff01;…

人工智能:走向智能化未來的探索

前言 人工智能&#xff08;Artificial Intelligence&#xff0c;簡稱AI&#xff09;是當今科技領域最引人注目的發展方向之一。從虛構作品中的機器人到現實生活中的智能助手&#xff0c;AI正深刻地改變著我們的生活方式、工作方式以及與技術互動的方式。本文將深入探討人工智能…

對無向圖進行鄰接矩陣的轉化,并且利用DFS(深度優先)和BFS(廣度優先)算法進行遍歷輸出, 在鄰接矩陣存儲結構上,完成最小生成樹的操作。

一 實驗目的 1&#xff0e;掌握圖的相關概念。 2&#xff0e;掌握用鄰接矩陣和鄰接表的方法描述圖的存儲結構。 3&#xff0e;掌握圖的深度優先搜索和廣度優先搜索遍歷的方法及其計算機的實現。 4&#xff0e;理解最小生成樹的有關算法 二 實驗內容及要求 實驗內容&#…