Linux 自動化構建工具 make/Makefile

来源:https://www.cnblogs.com/helong-123/archive/2022/06/20/16393401.html
-Advertisement-
Play Games

鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 VS中有一鍵編譯+自動運行,Linux也給我們提供了對應的編譯方式,雖然不及VS那麼便捷,但是相比於手動輸入 gcc -o add add.c ,我們一句make就可以搞定 Makefile是一個文件,能夠存放上述 gcc -o add add. ...


鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站

VS中有一鍵編譯+自動運行,Linux也給我們提供了對應的編譯方式,雖然不及VS那麼便捷,但是相比於手動輸入 gcc -o add add.c ,我們一句make就可以搞定

Makefile是一個文件,能夠存放上述 gcc -o add add.c 這種編譯指令

make是一個命令工具,能夠解釋Makefile中的指令

要如何編譯.c文件,關鍵就在於Makefile是怎麼寫的,下麵我們主要介紹這兩者的使用

一、 單個文件的編譯

假設我們要編譯這麼一個test.c文件,我們希望編譯生成一個名為test的可執行文件

file

我們在test.c所在目錄下創建一個Makefile文件,這裡有兩種編譯寫法

1、寫法一:逐個生成.i、.s、.o文件,最後再生成 test執行文件

先一步步向下分析,需要什麼依賴文件,然後再一步步生成

file

編寫好以後,我們只需要在命令行輸入make,系統就會幫我們自動編譯了,同時會生成每一步產生的文件按

file

2、 寫法二:一步到位,直接通過 test.c 生成 test 執行文件(推薦)

Makefile中要寫的內容如下

file

第一行:確定好依賴文件和目標文件。也就是要用依賴文件來生成目標文件

第二行:編譯指令。

            $@ 指向第一行的目標文件,表示目標文件test

            $^ 指向第一行的依賴文件,表示依賴文件test.c

            -std 表示採用的C++標準

接下來我們只需要在命令行輸入make,系統就會幫我們編譯了,編譯成功以後,當前目錄下就會多出一個test 執行文件

file

file

3、 Makefile自動清理

我們每次開始編譯之前,我們最好先清理一下之前生成的執行文件,手動輸入 rm test 有點太麻煩了,Makefile只要寫入下麵的內容,就會自動幫我們清理了

file

如果我們還希望移除生成的.o 、.s、.i文件,那麼第6行只要換成

rm -f test test.o test.s test.i

一般我們make的時候,系統會自動調用,當然也可以手動調用,如

file

file

我們會發現之前的test執行文件不見了

二、多個文件的編譯(同一目錄下)

現在我們有三個文件,分別是test.c、sub.c、sub.h,而且我們要在test.c中調用sub.h中的函數

file

Makefile中的內容如下:

file

test執行文件 要依賴 多個文件生成的 .o文件,現在沒有 .o文件,所以需要重新生成 .o文件

當前路徑下有多個.c文件,我們逐個去寫的話,就是

test.o:test.c
    gcc -c $@ $^
sub.o:sub.c
    gcc -c $@ $^

但是這樣寫太複雜了,我們可以選擇下麵這種寫法

%.o: %.c
    gcc -c $<
  • %.o:表示目標文件是 .o文件

  • %.c:表示依賴文件是當前路徑下的 .c文件,可以看作是一個集合中放著 test.c sub.c

  • $< : 展開%.c ,逐個生成對應的 .o文件,比如test.c就會生成對應的test.o、sub.c就會生成對應的

      sub.o
    

現在我們來運行一下

file

file

三、多個文件的編譯(不同目錄下)

現在我們有三個文件,test.c、sub.h、sub.c,但是其中sub.h、sub.c在其目錄func_dir 下

file

file

Makefile的內容如下:

file

現在我們來運行一下試試

file

file

四、一次生成多個運行文件

1、常規寫法嘗試及其不可行的原因

=常規寫法嘗試=

上面的都是一個main函數文件 + 一堆函數文件的編譯,但是有的時候,比如不同進程間通信時,我們可能需要一次生成兩個運行文件,如果我們按照常規的思路來寫,會怎麼樣?

file

file

測試結果如下,我們發現只生成了一個運行文件,很顯然無法按照常規的寫法來寫

file

=原因分析=

Makefile自動構建結束會生成運行文件,預設只生成最開始的一個,我們寫的時候,server的生成放在client的前面,server就是最開始的哪一個,所以Makefile就只生成了 server

2、改進

Makefile既然生成server以後,就不會繼續生成下一個運行文件,那麼我們就要在這之前就告訴Makefile,我希望生成兩個運行文件(因為Makefile是自頂向下運行的,不會上來就去執行gcc指令)

file

然後我們再來看一下測試結果,現在就能一次生成兩個運行文件了

file

本文轉自:https://blog.csdn.net/challenglistic/article/details/124249349


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

-Advertisement-
Play Games
更多相關文章
  • 大佬的理解->《Java IO(五) -- 字元流進階及BufferedWriter,BufferedReader》 1、BufferedReader BufferedReader高效字元流讀取文件基本用法,自帶緩衝區,讀取文件效率高,支持逐行讀取; 1.1 初始化 BufferedReader(R ...
  • 游戲的世界精彩紛呈,有動作類、策略類、角色扮演類等諸多類型,還有很多難以分類的小游戲,讓人玩起來往往愛不釋手 ...
  • 大佬的理解->《Java IO(四) -- 字元流》 FileReader字元流讀取文件,更適合用於讀取文件,可以讀取中文 1、FileReader 1.1 初始化 FileReader(File file) FileReader(String fileName) 1.2 讀取文件內容 read() ...
  • 項目全部代碼地址:https://github.com/Tom-shushu/work-study.git (mqtt-emqt 項目) 先看我們最後實現的一個效果 1.手機端向主題 topic111 發送消息,並接收。(手機測試工具名稱:MQTT調試器) 2.控制台列印 MQTT基本簡介 MQTT ...
  • 大佬的理解->《Java IO(三) -- 位元組流》 1、FileInputStream 1.1 初始化 FileInputStream(String name) FileInputStream(File file) //直接通過文件地址初始化 FileInputStream fis = new i ...
  • 第二回 巧習得元素分類 子不知懷璧其罪 雲溪父親見狀看了看雲溪,臉上滲出意思冷汗,但遲疑一下就立即退了出去,匆匆忙忙的往右邊廚房趕,只留下了雲溪和這位神秘的老爺子。 雲溪瞠目結舌的看著悠然自得的喝著老爹泡的茶的老爺子,下意識說了一句:“老先生你怎麼這麼快,還知道我要來這裡”。 “方向,你一直在繞巷子 ...
  • 一、Iproute2簡介 Iproute2是一個在Linux下的高級網路管理工具軟體。實際上,它是通過rtnetlink sockets方式動態配置內核的一些小工具組成的,從Linux2.2內核開始,Alexey Kuznetsov 實現了通過rtnetlink sockets用來配置網路協議棧,它 ...
  • 目錄 一、前景回顧 二、用C語言編寫內核 三、載入內核 四、運行測試 一、前景回顧 本回開始,我們要開始編寫內核代碼了,在此之前,先梳理一下已經完成的工作。 藍色部分是目前已經完成的部分,黃色部分是本節將要實現的。 二、用C語言編寫內核 為什麼要用C語言來編寫內核呢,其實用彙編語言也可以實現,只是對 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...