Linux應用開發基礎知識——Makefile初級教程(九)

目錄

一、Makefile是啥?

1.1、了解幾種文件(.o 文件和.c文件 )

1.2、關于Makefile的寫法

1.3、簡單使用Makefile基本指令

1.4、引入偽目標

1.5、Makefile的優點

1.6、Makefile的使用

二、Makefile創建和使用變量

2.1、創建變量的目的

2.2、自動變量的使用

2.3、Makefile即時變量、延時變量

2.3、Makefile通配符

2.4、Makefile的常用函數


一、Makefile是啥?

在 Linux 中使用?make?命令來編譯程序,特別是大程序;而 make 命令所執行的動作依賴于?Makefile?文件。最簡單的?Makefile?文件如下:
在這里插入圖片描述

1.1、了解幾種文件(.o 文件和.c文件 )

.o文件是由.c文件編譯得到的,一個可執行程序里面不可能只含有一個.c文件,里面肯定包含著很多其他子文件,所以我們編譯得到的程序就是將很多個.c文件編譯得到.o文件,然后再將很多個.o文件聯合起來變成一個可執行程序!所以Makefile就是一個很好的工具!
那怎么將一個.c文件編譯成一個.o文件呢?

gcc -c f1.c -o f1.o
f1.c:想要編譯的.c文件
f1.o:想要編譯成的.o文件

那怎么將一堆.o文件聯合編譯成一個可執行程序呢?

gcc f1.o f2.o main.o -o test
將f1.o,f2.o,main.o編譯成一個可執行文件test

1.2、關于Makefile的寫法

一個文件里面想要使用make指令來編譯程序,那么里面就一定要含有一個文件(命名為Makefile或者makefile),M大小寫都可以,我個人喜歡大寫,看起來更好看,后面提到的關于這個名詞,都會用Makefile來講。
Makefile里面的內容格式:
在這里插入圖片描述
注意:這里的TAB鍵不可以用四個空格來代替!!!
例:

f2.o:f2.cgcc -c f2.c -o f2.o

1.3、簡單使用Makefile基本指令

我們來實現一個簡單的程序,關于程序內容:
f1.c:實現簡單printf1打印函數
在這里插入圖片描述
f2.c:實現簡單printf2打印函數
在這里插入圖片描述
head.h:聲明printf1和printf2函數
在這里插入圖片描述
main.c:添加head頭文件,使用printf1和printf2函數
在這里插入圖片描述
做完以上的準備工作后,我們就來編寫一個簡單的Makefile:
根據格式:
在這里插入圖片描述
我們的Makefile:

test:f1.o f2.o main.ogcc f1.o f2.o main.o -o test
f1.o:f1.cgcc -c f1.c -o f1.o
f2.o:f2.cgcc -c f2.c -o f2.o
main.o:main.cgcc -c main.c -o main.o

然后使用make就可以編譯得到我們的可執行程序test了
然后我們就可以運行:./test
在這里插入圖片描述
假如我們不使用make指令,我們可以更有目的性的去編譯:
例:只想要編譯出f1.o文件
在這里插入圖片描述

1.4、引入偽目標

繼續在上面的測驗來實現:
我們完善一下我們的Makefile,修改為:

test:f1.o f2.o main.ogcc f1.o f2.o main.o -o test
f1.o:f1.cgcc -c f1.c -o f1.o
f2.o:f2.cgcc -c f2.c -o f2.o
main.o:main.cgcc -c main.c -o main.oclean:rm *.o test

有前面可以知道:
make f1.o就是:
在這里插入圖片描述
那么我們make clean不就是輸入了rm *.o test指令嗎?
事實確實是這樣的!在這里插入圖片描述
我們看規律來看,都是make一個目標文件,假如我們的程序里面真的有一個clean文件呢?那會怎么樣呢?
在這里插入圖片描述
我們不就用不了這個簡單的一次性刪除所有.o文件和可執行程序(或者其他便捷指令)了嗎?所以我們要引入偽目標:
在這里插入圖片描述
這樣就不會互相干擾了!
在這里插入圖片描述

1.5、Makefile的優點

按照這樣的編譯,我們就可以寫一個Makefile然后使用make指令即可編譯,不用我們一條條去編譯,假如我們編寫了一個程序,里面有著非常復雜的代碼和繁多的文件,就算用Makefile這么牛的工具也要編譯個一個半個小時,編譯成功之后,突然想起來一個Bug,但是只需要修改一個底層文件即可,那么修改后又得重新編譯,還是要這么多時間嗎?
這就要說到Makefile的優點了,Makefile會根據文件的時間戳來發現更新過的文件,減少編譯工具量!
例:
第一次編譯時:(會把全部文件指令都執行一遍)
在這里插入圖片描述
假如我們的f1.c文件需要修改一下Bug,我們后來修改了一下f1.c文件(其實沒有修改,這里使用了touch指令更新了一下f1.c的時間戳代替f1.c被修改):
在這里插入圖片描述
這里只執行有關于f1.c更新的Makefile指令,可見Makefile的強大!

1.6、Makefile的使用

在這里插入圖片描述

二、Makefile創建和使用變量

2.1、創建變量的目的

創建變量的目的就是用來代替一個文本字符串。
比如:
1、用于代替系列文件的名字
2、代替傳遞個編譯器的參數
3、需要運行的程序。。。。。。。等等等等
這里就簡單來使用一下變量。(還是基于上面的Makefile來修改)
定義一個變量,以及使用變量:|

變量定義:OBJS=man.o out.o
變量使用:$(OBJS)

test:f1.o f2.o main.ogcc f1.o f2.o main.o -o test
f1.o:f1.cgcc -c f1.c -o f1.o
f2.o:f2.cgcc -c f2.c -o f2.o
main.o:main.cgcc -c main.c -o main.o.PHONY:clean
clean:rm *.o test

簡單使用變量優化Makefile:(這樣修改工具鏈的時候就很方便了!)

OBJS=f1.o f2.o main.o
CC=gcctest:$(OBJS)$(CC) f1.o f2.o main.o -o test
f1.o:f1.c$(CC)-c f1.c -o f1.o
f2.o:f2.c$(CC)-c f2.c -o f2.o
main.o:main.c$(CC)-c main.c -o main.o.PHONY:clean
clean:rm *.o test

2.2、自動變量的使用

$@:表示規則中的目標文件名。
$<:表示規則中的第一個依賴文件名。
$^:表示規則中的所有依賴文件名,以空格分隔。
$?:表示比目標文件更新的所有依賴文件名,以空格分隔。
$(@D):表示目標文件所在的目錄名。
$(@F):表示目標文件的文件名(不包含路徑)。
$+:表示規則中的所有依賴文件名,以空格分隔,并以出現的先后順序為序。
例:(依然是在上面的Makefile修改優化)

OBJS=f1.o f2.o main.o
CC=gcctest:$(OBJS)$(CC) $^ -o $@
f1.o:f1.cgcc -c $< -o $@
f2.o:f2.cgcc -c $^ -o $@
main.o:main.cgcc -c $^ -o $@.PHONY:clean
clean:rm *.o test

2.3、Makefile即時變量、延時變量

語法如下:

A = xxx // 延時變量
B ?= xxx // 延時變量,只有第一次定義時賦值才成功;如果曾定義過,此賦值無效
C := xxx // 立即變量
D += yyy // 如果 D 在前面是延時變量,那么現在它還是延時變量;

一個例子理解即時變量、延時變量:

A = $@
test:@echo $A

上述 Makefile 中,變量 A 的值在執行時才確定,它等于 test,是延時變量。如
果使用“A :=?@”,這是立即變量,這時@”,這是立即變量,這時@為空,所以 A 的值就是空。

OBJS=f1.o f2.o
OBJS+=main.o

此時OBJS=f1.o f2.o main.o

2.3、Makefile通配符

在 Makefile 中,通配符用于匹配文件名或文件路徑中的多個字符,以便在規則中批量處理文件。通配符常見的有以下幾種:
*:匹配零個或多個字符。
?:匹配一個任意字符。
[…]:匹配方括號內的任意一個字符。
[!..]:匹配除了方括號內的字符之外的任意一個字符。
%:%,o&%,c表示任意的.o和.c文件
在?Makefile?中,通配符通常與模式規則結合使用,以便自動化地處理一類文件。
例:

常用通配符使用:
program: *.cgcc $^ -o $@%.o:%.cgcc -c $^ -o $@

在這個?Makefile?中,==*.c ==通配符匹配當前目錄下所有以 .c 結尾的文件。$ ^表示所有匹配到的文件,$@ 表示目標文件。因此,program: *.c 規則會將所有的 .c 文件編譯鏈接成一個名為 program 的可執行文件。

2.4、Makefile的常用函數

函數調用的格式如下:
$(function arguments)

1、$(foreach var, list, text)
對 list 中的每一個元素,取出來賦給 var,然后把 var 改為 text 所描述的形式。
例:

objs := a.o b.o
dep_files := $(foreach f,?(𝑜𝑏𝑗𝑠),.(objs),.(f).d) // 最終 dep_files := .a.o.d .b.o.d

objs := a.o b.o
dep_files := $(foreach f, $(objs), $(f).s) // 最終 dep_files := a.o.s b.o.s

2、$(wildcard pattern)
pattern 所列出的文件是否存在,把存在的文件都列出來。

src_files := $( wildcard *.c) // 最終 src_files 中列出了當前目錄下的所有.c 文件

3、$(subst from,to,text)

在文本text’中使用to’替換每一處`from’。
比如:$(subst ee, EE, feet on the street)
結果為‘fEEt on the strEEt’。

4、$(patsubst pattern,replacement,text)

尋找text’中符合格式pattern’的字,用replacement’替換它們。?pattern’和`replacement’中可以使用通配符。

比如:$(patsubst %.c,%.o,x.c.c bar.c)
結果為:`x.c.o bar.o’。

5、$(strip string)
去掉前導和結尾空格,并將中間的多個空格壓縮為單個空格。

比如:$(strip a b c )
結果為`a b c’。

6、$(findstring find,in)
在字符串in’中搜尋find’,如果找到,則返回值是`find’,否則返回值為空。
在這里插入圖片描述

將分別產生值a’和’(空字符串)。

7、$(filter pattern…,text)
返回在text’中由空格隔開且匹配格式pattern…’的字,去除不符合格式`pattern…’的字。

比如:$(filter %.c %.s,foo.c bar.c baz.s ugh.h)
結果為`foo.c bar.c baz.s’。

8、$(filter-out pattern…,text)
返回在text’中由空格隔開且不匹配格式pattern…’的字,去除符合格式`pattern…’的字。它是函數 filter 的反函數。

比如:$(filter %.c %.s,foo.c bar.c baz.s ugh.h)
結果為`ugh.h’。

9、$(sort list)
將‘list’中的字按字母順序排序,并去掉重復的字。輸出由單個空格隔開的字的列表。

比如:$(sort foo bar lose)
返回值是‘bar foo lose’。

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

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

相關文章

面試問題收集——卷積神經網絡

博主會經常分享自己在人工智能階段的學習筆記&#xff0c;歡迎大家訪問我滴個人博客&#xff01;&#xff08;養成系Blog&#xff01;&#xff09; 小牛壯士滴Blog~ - 低頭趕路 敬事如儀https://kukudelin.top/ 01-卷積基礎知識 問&#xff1a;簡述卷積基本操作&#xff0c;…

Kubernetes 全面解析:從基礎設施變革到核心架構詳解

引言在容器化技術席卷全球的今天&#xff0c;Kubernetes&#xff08;簡稱 K8s&#xff09;已成為容器編排領域的事實標準。無論是互聯網企業還是傳統行業&#xff0c;都在通過 Kubernetes 實現應用的高效部署、彈性擴展和自動化運維。但對于初學者而言&#xff0c;Kubernetes 的…

哈希相關的模擬實現

哈希相關的模擬實現哈希表的模擬實現閉散列除留取余法查找、插入和刪除閉散列參考程序開散列除留取余法&#xff08;數組鏈表&#xff09;迭代器查找和刪除插入開散列參考程序unordered_map和unordered_set的模擬實現unordered_mapunordered_set建議先看 哈希的概念及其應用-CS…

Vue3+Vite項目如何簡單使用tsx

安裝必要的依賴npm install vitejs/plugin-vue-jsx -D在 vite.config.ts 中添加以下內容import vueJsx from vitejs/plugin-vue-jsx export default {plugins: [vueJsx()] }在Vue頁面使用<script lang"ts"> import { defineComponent } from vue export defaul…

05百融云策略引擎項目交付-laravel實戰完整交付定義常量分文件配置-獨立建立lib類處理-成功導出pdf-優雅草卓伊凡

05百融云策略引擎項目交付-laravel實戰完整交付定義常量分文件配置-獨立建立lib類處理-成功導出pdf-優雅草卓伊凡引言此前只是把關于如何把查詢內容導出pdf庫的代碼實現了&#xff0c;但是我們并沒有完成整個項目&#xff0c;這最后一個步驟就是安裝composer再安裝tcpdf庫&…

模型訓練速度慢排查

一、nvidia-smi 查看 GPU 的利用率與顯存。若 GPU 利用率低或波動&#xff0c;說明 CPU 處理數據的速度跟不上 GPU 計算的速度&#xff0c;需要檢查數據傳輸并調整 num_workers&#xff1b;若 GPU 顯存充足&#xff0c;可以逐步增加 batch_size_per_card 直至顯存占滿&#xff…

STM32學習記錄--Day4

今天了解了一下SPI總線&#xff1a;1.SPI內部結構??&#x1f50c; SPI 四大核心引腳功能詳解??1. ??MOSI (Master Output Slave Input)????功能??&#xff1a;??主機輸出數據線????工作流程??&#xff1a;主機內部發送數據寄存器 (TxDR) 的數據 → 移位寄存…

【網絡安全】等級保護2.0解決方案

等保2.0&#xff08;網絡安全等級保護2.0&#xff09;是我國網絡安全領域的基礎性制度&#xff0c;在1.0版本基礎上擴展了云計算、大數據、物聯網等新興領域&#xff0c;形成覆蓋全場景的安全防護框架。其核心是按信息系統重要程度劃分等級&#xff08;1-5級&#xff09;&#…

TypeScript 基礎介紹(二)

引言&#xff1a;從基礎到結構化類型 在《TypeScript 基礎介紹&#xff08;一&#xff09;》TypeScript基礎介紹&#xff08;一&#xff09;-CSDN博客中&#xff0c;我們探討了 TypeScript 的類型系統基礎、聯合類型、類型斷言和類型守衛等核心特性。這些內容解決了 JavaScript…

【科研繪圖系列】R語言繪制線性相關性

文章目錄 介紹 加載R包 數據下載 導入數據 數據預處理 畫圖 系統信息 參考 介紹 【科研繪圖系列】R語言繪制線性相關性 加載R包 library(tidyverse) library(ggplot2) library(ggsignif) library(RColorBrewer) library(dplyr) library(reshape2

FastAPI的請求-響應周期為何需要后臺任務分離?

url: /posts/c7b54d6b3b6b5041654e69e5610bf3b9/ title: FastAPI的請求-響應周期為何需要后臺任務分離? date: 2025-07-31T06:11:25+08:00 lastmod: 2025-07-31T06:11:25+08:00 author: cmdragon summary: FastAPI 的請求-響應周期遵循 ASGI 協議,類似于餐廳點餐流程。同步處…

多種錄音筆錄音芯片方案推薦

多種錄音筆錄音芯片方案推薦一、引言隨著信息技術的飛速發展&#xff0c;錄音筆作為一種重要的音頻記錄設備&#xff0c;在會議記錄、采訪、學習等眾多場景中得到廣泛應用。其核心的錄音芯片方案直接影響錄音質量、功能特性以及產品成本。唯創知音作為音頻芯片領域的知名廠商&a…

Linux系統編程Day2-- Linux常用操作

一、Linux 基本命令概覽以下是一些常用的Linux命令操作&#xff0c;后續我們會對其每個單獨如何使用進行講解。操作類型常用命令示例文件/目錄操作ls, cd, cp, mv, rm, mkdir, rmdir查看文件內容cat, less, more, head, tail查找操作find, grep, locate, which權限管理chmod, c…

cs336 assignment1 作業環境配置

代碼結構 所有的代碼寫到cs336_basics/* 下面&#xff0c;在adapters.py里調用自己的.py&#xff0c;通過所有的test。 作業資料參考 karpathy視頻倉庫&#xff1a; 視頻 github倉庫 測試項目運行環境 下載uv uv官網倉庫 使用命令&#xff1a; powershell -ExecutionPoli…

YOLOv11來了,使用YOLOv11訓練自己的數據集和推理(附YOLOv11網絡結構圖)

文章目錄前言一、YOLOv11代碼下載地址1.YOLOv11模型結構圖二、數據集準備1.數據集標注軟件2.voc數據集格式轉換3.數據集劃分4.修改yolo的訓練配置文件三、YOLO環境配置教程1.pytorch環境安裝2.其他依賴安裝四、YOLOv11訓練五、YOLOv11推理六、解決訓練過程中斷怎么繼續上次訓練…

20250731在榮品的PRO-RK3566開發板的Android13下跑通敦泰的FT8206觸控芯片

20250731在榮品的PRO-RK3566開發板的Android13下跑通敦泰的FT8206觸控芯片 2025/7/31 17:48緣起&#xff1a;本文前置條件&#xff1a;已經解決FT8206和PRO-RK3566的硬件連接。 通過i2cdect可以掃描到i2c從機地址&#xff1a;0x38。【8位地址為0x70】緣起&#xff1a;本文只分析…

異常檢測:算法分類及經典模型概覽

第一部分&#xff1a;異常檢測的核心概念 在深入算法細節之前&#xff0c;理解異常檢測的“語境”至關重要。 1. 什么是異常檢測&#xff1f; 異常檢測&#xff08;Anomaly Detection 或 Outlier Detection&#xff09;旨在通過數據挖掘技術&#xff0c;識別出數據集中與大多數…

技術干貨 | 矢網DTF測量技術:透視線纜、天線與波導內部缺陷的“射頻X光”(二)

無線通信、雷達等領域中&#xff0c;射頻組件與傳輸系統的性能至關重要&#xff0c;其內部微小損傷易導致信號問題甚至系統失效。傳統測試無法精確定位故障點&#xff0c;排查困難。DTF測量&#xff0c;矢網賦予的“透視眼”&#xff01;它能穿透“黑箱”&#xff0c;精確定位線…

【[CSP-J 2022] 上升點列】

題目 [CSP-J 2022] 上升點列 題目描述 在一個二維平面內&#xff0c;給定 n 個整數點 (x i ,y i? )&#xff0c;此外你還可以自由添加 k 個整數點。 你在自由添加 k 個點后&#xff0c;還需要從 nk 個點中選出若干個整數點并組成一個序列&#xff0c;使得序列中任意相鄰兩點間…

Kong API Gateway的十年進化史

一、技術基因的誕生&#xff08;2007-2015&#xff09; 2007年&#xff0c;三位意大利開發者Augusto Marietti、Marco Palladino和Michele Orru在博洛尼亞的一個小車庫中創立了Mashape公司。 最初他們開發了一個名為Mashup的API聚合平臺&#xff0c;試圖通過整合第三方API為開發…