【Linux 學習計劃】-- gcc、g++、動靜態庫鏈接

目錄

什么是gcc、g++

gcc、g++ 相關操作詳解

預處理、編譯、匯編、鏈接來源

動靜態鏈接是什么

結語


什么是gcc、g++

gcc、g++其實就是編譯器,是幫助我們從.c或者.cc,.cpp文件編譯成可執行程序的

其中,我們如果要編譯c語言文件的話,上面兩個我們都可以使用,雖然g++是用來編譯cpp的,但是cpp本身就包含了c語言

但是我們并不能使用gcc來編譯cpp文件,會報錯的,

接著我們來快速見一下gcc、g++的用法(其實這兩個用法是差不多的,所以接下來主包就只展示gcc的用法):

這上面我們用到了一個 -o 的選項,這其實就是在給生成出來的可執行程序進行一個命名

如果我們不加上 -o 選項的話,那么他會默認將名字改成a.out

gcc、g++ 相關操作詳解

這里要聲明一下,由于gcc、g++底層用的是同樣的東西,只不過默認處理的語言不同,僅此而已,所以我們gcc進行的操作,g++同樣也有,也可以進行

所以,下面主包也同樣是用gcc進行演示

首先,我們的程序要從.c文件變成可執行程序,一共需要經歷四步:

預處理、編譯、匯編、鏈接

對應在gcc中的操作是:

預處理:gcc -E test.c -o test.i

編譯:gcc -S?test.i?-o test.s

匯編:gcc -c?test.s?-o test.o

鏈接:gcc test.o -o test

其實挺好記的,選項就是ESc,其實就看向鍵盤最左上角,有一個Esc退出鍵

而對應后綴就是iso,記著就好了

接著我們來詳細談一談這四個步驟,以及為什么是四個步驟而不是一步到位

預處理

其實這個步驟就干幾件事情:宏替換,去注釋,頭文件展開,條件編譯等等

我們可以簡單來看一看:

我們可以看到,左邊是test.c,右邊是.i,而我們左邊就12行,到了右邊就變成了800多行了,其實在預處理這一步,就是將上面的頭文件展開,注釋去掉等等而已

但還有一個,什么是條件編譯?

其實就和名字一樣,根據不同的條件,編譯不同的代碼:

就是這樣的

編譯

編譯其實就干一件事情,將C語言轉變成匯編代碼

而我們上面預處理那一步,其實還是c語言,只不過變得非常干凈而已

但是這一步,卻是將c變成匯編,如下圖:

我們用vim打開來看看這個.s文件

匯編

這一步傳自上一步編譯,這一步就是將匯編翻譯成二進制

這里就不用vim打開來看了,因為二進制要看的話只會看到亂碼

鏈接

到了最后一步鏈接這里,其實就是將.o文件(在Windows下可能叫做.obj)變成可執行程序

預處理、編譯、匯編、鏈接來源

可能有人會疑惑,你說預處理我能理解,這樣看起來還是比較整潔,替換一下我覺得沒有問題

但是剩下三步是為什么?為什么不能一步到位直接形成可執行程序?

這里我們就需要講一講歷史淵源了

在最開始的時候,電腦剛出來的時候,我們是用二進制進行編程的

就是像這樣的

但是由于這樣子太麻煩了,所以就出現了匯編語言

但是我們匯編的底層還是二進制

接著就是c語言的出現

我們當然可以直接從c變成可執行,但是這樣太麻煩,因為最底層還是二進制,但是如果我們只是將出c變成匯編的話,匯編到二進制那一步我們就不需要做了,因為歷史幫我們完成了,所以效率就很高

所以有四步一方面是歷史原因,另一方面就是效率高了

另外還有一個有意思可以拓展一下的就是:編譯器的自舉

問一個問題,是有匯編語言,還是先有匯編語言的編譯器?

答案當然是現有匯編語言,不然的話匯編對應的編譯器的語法檢查等等東西怎么寫?

但是在最開始的時候,我們只有語言,沒有對應的編譯器,所以我們就會先用二進制寫一個匹配匯編的編譯器,接著就是,我們再用這個二進制寫成的匯編編譯器再寫一個用匯編語言寫出來的匯編編譯器

這時,我們的編譯器就出來了,c語言同樣如此,這就叫做編譯器的自舉

動靜態鏈接是什么

首先是操作,動態鏈接的話是默認的,你用gcc默認就是動態鏈接

如果你要靜態鏈接的話,需要在gcc指令的最后面加上-static

但是可能會遇到如下這種情況:

這代表靜態庫沒有安裝,因為可能有些默認就是沒有靜態庫的,用yum安裝即可

然后要安裝哪一個庫就搜一下對應指令即可,因為一般用不到這個,所以其實不太需要安裝

接著我們需要知道,我們的項目中會包含很多頭文件,但是我們在編譯的時候,會先通過預處理找到庫然后將庫展開代替到項目中的

這就說明,我們的云服務器中,系統中,是一定有對應的庫的,這樣我們才能說去找到他

而在Linux中,我們可以用 ldd 命令來查看

我們可以看到,這里面用到的就是c語言的標準庫

同時我們還可以用file指令看看,具體的鏈接方式:

這里可以看到,就是動態鏈接

但是我們還需要知道,什么是動靜態鏈接?

舉個例子,學校外面有一個網吧,當到了周末的時候,同學們都會去到網吧里面用電腦,因為學校沒有(假設),這時候,我們的網吧就是動態庫,而同學們去網吧的這個過程,就叫做動態鏈接

而靜態鏈接就是,沒有網吧,但是在學生宿舍里面每一個人都有一臺電腦,這時候不管外面有沒有網吧,同學們都不會出去了,因為電腦直接就有了,這就是靜態鏈接

而在我們的Linux中,最主要的就是動態鏈接,因為動態鏈接的優點就是,我們的庫(網吧)只需要有一個就夠了,會省空間,提高效率,但是缺點就是,當我們的這個對應的庫被誤刪的時候,可能會有幾百上千個文件(同學)同時用不了(上不了網)

而靜態庫的優缺點則是相對的,因為這是直接將庫給每個人配一個了

這是動靜態庫大小的對比

我們可以看到的是,這里面都是用到的動態庫,因為本身靜態庫的效率就不高,從這里我們就可以看到Linux對于動靜態庫的態度了

結語

這篇文章到這里就結束啦!!~( ̄▽ ̄)~*

如果覺得對你有幫助的,可以多多關注一下喔

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

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

相關文章

前端讀取本地項目中 public/a.xlsx 文件中的數據 vue3

前端讀取本地項目中 public/a.xlsx 文件中的數據 vue3 項目中需要在 Vue3 項目中讀取 public/a.xlsx 文件,可以使用 fetch API 來獲取文件內容 一、安裝 xlsx 首先,你需要安裝 xlsx 庫: npm install xlsx二、在需要用的頁面里引入xlsx im…

MySQL:to many connections連接數過多

當你遇到 MySQL: Too many connections 錯誤時,意味著當前連接數已達到 MySQL 配置的最大限制。這通常是由于并發連接過多或連接未正確關閉導致的。 一、查看當前連接數 查看 MySQL 當前允許的最大連接數 SHOW VARIABLES LIKE max_connections;查看當前使用的最大…

2024年熱門AI趨勢及回顧

人工智能的崛起 2024 年可能會被銘記為人工智能不再是一種技術新奇事物,而是成為現實的一年。微軟、Salesforce 和 Intuit 等巨頭將人工智能融入主流企業解決方案;從文案寫作到數據分析,專門的人工智能應用程序和服務如雨后春筍般涌現&#…

LangFlow技術深度解析:可視化編排LangChain應用的新范式 -(2)流編輯器系統

Flow Editor System | langflow-ai/langflow | DeepWiki 流編輯器系統 相關源文件 流編輯器系統是 Langflow 的核心交互式組件,允許用戶直觀地創建、編輯和管理 LLM 驅動的應用程序。它提供了一個直觀的畫布,用戶可以在其中添加節點、將其與邊緣連接并…

驅動-定時-秒-字符設備

文章目錄 目的相關資料參考實驗驅動程序-timer_dev.c編譯文件-Makefile測試程序-timer.c分析 加載驅動-運行測試程序總結 目的 通過定時器timer_list、字符設備、規避競爭關系-原子操作,綜合運用 實現一個程序,加深之前知識的理解。 實現字符設備驅動框…

[Java實戰]Spring Boot整合Kafka:高吞吐量消息系統實戰(二十七)

[Java實戰]Spring Boot整合Kafka:高吞吐量消息系統實戰(二十七) 一、引言 Apache Kafka作為一款高吞吐量、低延遲的分布式消息隊列系統,廣泛應用于實時數據處理、日志收集和事件驅動架構。結合Spring Boot的自動化配置能力&…

Kotlin Multiplatform--04:經驗總結(持續更新)

Kotlin Multiplatform--04:經驗總結(持續更新) 引言 引言 本章用來記載筆者開發過程中的一些經驗總結 一、Ktor設置Header 在官方文檔中,想要設置Header的示例代碼如下: client.get("https://ktor.io&qu…

在 Ubuntu 系統中,將 JAR 包安裝為服務

在 Ubuntu 系統中,將 JAR 包安裝為服務可以通過 systemd 來實現。以下是詳細的操作步驟: 準備工作 確保 JAR 文件路徑和 Java 運行時環境已準備好。驗證 Java 是否可用: java -version創建 systemd 服務文件 systemd 的服務文件通常位于 …

電商項目-商品微服務-品牌管理微服務開發

一、功能分析 品牌管理微服務包括: (1)查詢全部列表數據 (2)根據ID查詢實體數據 (3)增加 (4)修改 (5)刪除 (6)分頁…

Spring Boot開發—— 整合Lucene構建輕量級毫秒級響應的全文檢索引擎

文章目錄 一、為什么選擇 Lucene?輕量級搜索的底層密碼二、核心原理:Lucene 的倒排索引2.1 倒排索引:速度之源2.2 段合并優化策略三、Spring Boot集成Lucene實戰3.1 依賴配置3.2 實體與索引設計3.3 核心索引服務(含異常處理)3.4 使用示例(測試類)四、高級優化技巧4.1 索…

SpringBootDay1|面試題

目錄 一、springboot框架 1、什么是springboot 2、Spring Boot的主要優點 3、springboot核心注解 4、定義banner(springboot的logo) 5、springboot配置文件 6、springboot 整合 jdbc 二、面試題 1)springmvc的作用 ?編輯 2&#x…

jQuery Ajax中dataType 和 content-type 參數的作用詳解

jQuery Ajax中dataType與contentType參數解析 一、核心概念對比 參數作用對象數據類型默認值dataType響應數據預期接收的數據格式jQuery自動判斷(根據響應頭MIME類型)contentType請求數據發送數據的編碼格式application/x-www-form-urlencoded 二、da…

幾款常用的虛擬串口模擬器

幾款常用的虛擬串口模擬器(Virtual Serial Port Emulator),適用于 Windows 系統,可用于開發和調試串口通信應用: 1. com0com (開源免費) 特點: 完全開源免費,無功能限制。 可創建多個虛擬串口…

LLM筆記(六)線性代數

公式速查表 1. 向量與矩陣:表示、轉換與知識存儲的基礎 向量表示 (Vectors): 語義的載體 在LLM中,向量 x ∈ R d \mathbf{x}\in\mathbb{R}^d x∈Rd 是信息的基本單元,承載著豐富的語義信息: 詞嵌入向量 (Word Embeddings)&am…

[特殊字符] Word2Vec:將詞映射到高維空間,它到底能解決什么問題?

一、在 Word2Vec 之前,我們怎么處理語言? 在 Word2Vec 出現之前,自然語言處理更多是“工程方法”,例如字符串匹配、關鍵詞提取、正則規則...。但這些表示通常缺乏語義,詞與詞之間看不出任何聯系以及非常淺顯。當然,技術沒有好壞,只有適合的場景。例如: 關鍵詞匹配非常…

棧和隊列的模擬實現

棧和隊列的模擬實現 容器適配器priority_queue(優先級隊列)priority_queue的使用priority_queue的模擬實現: 仿函數什么叫仿函數?需要自己實現仿函數的情況: 棧的模擬實現隊列的模擬實現deque(vector和list的縫合怪&am…

idea本地debug斷點小技巧

idea本地debug斷點小技巧 簡單的設置斷點條件 斷點后,右鍵這個斷點,可以在 condition 中填寫能得出布爾的表達式 a 1 你如果寫如下,表示先給他賦值,然后斷住 a 2; true 斷點后設置某個變量的值 在 debug 區域可以設置變量…

Oracle中如何解決FREE BUFFER WAITS

基于性能上的考慮,服務器進程在掃描LRU主列的同時,會將臟塊移至LRU-W列,如果發現沒有足夠可用(可替換)的BUFFER CACHE,進程并不會無止盡地掃描整條LRU主列,而是在掃描到某個閥值(該閥…

Git命令使用全攻略:從創建分支到合并的完整流程

Git命令使用全攻略:從創建分支到合并的完整流程 引言一、初始化項目與基礎配置1.1 克隆遠程倉庫1.2 查看當前分支狀態 二、創建與管理分支2.1 從main分支創建新功能分支2.2 查看分支列表2.3 提交代碼到新分支2.4 推送分支到GitHub 三、版本發布與標簽管理3.1 創建輕…

MATLAB跳動的愛心

520,一個會動的心~~~ function particleHeart2 % author : slandarer% 所需匿名函數 col1Func(n) repmat([255,158,196]./255,[n,1])repmat([-39,-81,-56]./255,[n,1]).*rand([n,1]); col2Func(n) repmat([118,156,216]./255,[n,1])repmat([137,99,39].*.1./255,[n,…