linux gcc

一、常用編譯選項

  1. ?基本編譯
    gcc [input].c -o [output]
    ?示例

    gcc hello.c -o hello  # 將 hello.c 編譯為可執行文件 hello
    ./hello               # 運行程序
  2. ?分步編譯

    • 預處理:-E(生成?.i?文件)
      gcc -E hello.c -o hello.i
    • 編譯為匯編:-S(生成?.s?文件)
      gcc -S hello.i -o hello.s
    • 匯編為目標文件:-c(生成?.o?文件)
      gcc -c hello.s -o hello.o
    • 鏈接為可執行文件:
      gcc hello.o -o hello
  3. ?調試信息
    -g?選項生成帶調試信息的文件(供 GDB 使用):

    gcc -g test.c -o test_debug
  4. ?優化選項
    -O1,?-O2,?-O3?表示優化級別(-O2?最常用):

    gcc -O2 main.c -o optimized_program
  5. ?警告選項

    • -Wall?啟用所有常見警告
    • -Werror?將警告視為錯誤
    gcc -Wall -Werror strict_code.c -o strict_program
  6. ?鏈接庫文件

    • -l?指定庫名(如數學庫?-lm
    • -L?指定庫文件路徑
    gcc calc.c -lm -L/usr/local/lib -o calc

二、示例場景

1. 編譯多文件項目
# 編譯兩個文件并鏈接
gcc main.c utils.c -o app
2. 生成靜態庫
# 1. 編譯為 .o 文件
gcc -c mylib.c -o mylib.o
# 2. 打包為靜態庫
ar rcs libmylib.a mylib.o
# 3. 使用靜態庫
gcc main.c -L. -lmylib -o static_app
3. 生成動態庫(共享庫)
# 1. 編譯為位置無關代碼(-fPIC)
gcc -fPIC -c mylib.c -o mylib.o
# 2. 生成動態庫(-shared)
gcc -shared mylib.o -o libmylib.so
# 3. 使用動態庫(需設置庫路徑)
gcc main.c -L. -lmylib -o dynamic_app
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH  # 臨時添加庫路徑

三、C語言是如何編譯的

1. 預處理

類比:準備食材

想象你在做一道復雜的菜,首先你需要把所有的食材準備好,比如切菜、洗菜、調味等。預處理階段就像是這個準備食材的過程。

具體過程

預處理器(cpp)會處理源代碼文件中的預處理指令,比如?#include#define?和?#ifdef?等。它會將這些指令替換成實際的代碼或數據。

  • ??#include??:將指定的頭文件內容插入到當前文件中。
  • ??#define??:定義宏,替換代碼中的宏定義。
  • ??#ifdef?/?#ifndef??:條件編譯,根據條件決定是否包含某段代碼。

示例

#include <stdio.h>
#define PI 3.14159int main() {printf("The value of PI is %f", PI);return 0;
}

預處理后,#include <stdio.h>?會被替換成?stdio.h?文件的內容,PI?會被替換成?3.14159

2. 編譯

類比:編寫食譜

現在你已經準備好了食材,接下來你需要編寫一個詳細的食譜,告訴廚師每一步該怎么做。編譯階段就像是這個編寫食譜的過程。

具體過程

編譯器(gcc)會將預處理后的源代碼轉換成匯編代碼。這個過程會檢查語法錯誤、類型檢查等。

  • ??語法檢查??:確保代碼符合C語言的語法規則。
  • ??類型檢查??:確保變量和函數的類型使用正確。

示例

預處理后的代碼會被編譯成類似以下的匯編代碼(具體內容取決于編譯器和平臺):

main:push    rbpmov     rbp, rspsub     rsp, 16mov     edi, OFFSET FLAT:.LC0call    puts@PLTmov     eax, 0leaveret

3. 匯編

類比:將食譜翻譯成操作步驟

現在你已經有了詳細的食譜,接下來需要將這些食譜翻譯成具體的操作步驟,讓廚師可以一步步執行。匯編階段就像是這個翻譯過程。

具體過程

匯編器(as)會將匯編代碼轉換成機器碼,生成目標文件(.o?文件)。這個過程不會進行任何優化,只是簡單地將匯編指令轉換成機器碼。

示例

上面的匯編代碼會被轉換成機器碼,生成一個目標文件?main.o

4. 鏈接

類比:將多個菜譜合并成一本完整的烹飪書

現在你已經有了每道菜的具體操作步驟,接下來需要將這些步驟合并成一本完整的烹飪書,確保所有的步驟和食材都能協調工作。鏈接階段就像是這個合并過程。

具體過程

鏈接器(ld)會將多個目標文件和庫文件合并成一個可執行文件。這個過程會解析所有的符號引用,確保每個函數和變量的調用都能找到正確的定義。

  • ??符號解析??:確保每個函數和變量的調用都能找到正確的定義。
  • ??重定位??:將符號的地址修正為最終的內存地址。

假設你有兩個源文件?main.c?和?utils.c,編譯后會生成?main.o?和?utils.o。鏈接器會將這兩個目標文件合并成一個可執行文件?program

總結

  1. ??預處理??:準備食材,處理?#include#define?等指令。
  2. ??編譯??:編寫食譜,將預處理后的代碼轉換成匯編代碼。
  3. ??匯編??:將食譜翻譯成操作步驟,生成目標文件。
  4. ??鏈接??:合并多個菜譜,生成最終的可執行文件。

5.函數庫

靜態庫

定義??:靜態庫是將一系列的目標文件(.o?文件)打包成一個單獨的文件,在編譯鏈接時,鏈接器會把靜態庫中被程序使用的代碼直接復制到最終的可執行文件中。靜態庫的文件擴展名通常是?.a

靜態連接在靜態連接中,編譯器和鏈接器在編譯階段就把程序所需要使用的庫代碼(靜態庫)直接合并到最終生成的可執行文件中。

  • ??創建靜態庫??:首先要有多個目標文件。假設我們有兩個源文件?add.c?和?sub.c,分別實現加法和減法功能。
// add.c
int add(int a, int b) {return a + b;
}// sub.c
int sub(int a, int b) {return a - b;
}

使用 `gcc` 編譯這兩個源文件生成目標文件:

gcc -c add.c sub.c

然后使用 `ar` 工具創建靜態庫:

ar rcs libmath.a add.o sub.o

這里?ar?是歸檔工具,r?表示將目標文件插入到歸檔文件中,c?表示如果歸檔文件不存在則創建它,s?表示寫入一個目標文件索引。

?這樣來使用靜態庫

gcc main.c -L. -lmath -o main

-L.?表示在當前目錄下查找庫文件,-lmath?表示鏈接名為?libmath.a?的靜態庫(注意,-l?后面跟的是庫名去掉?lib?前綴和?.a?后綴)。?

優點
  • ??獨立性??:可執行文件包含了靜態庫的所有代碼,不依賴外部的庫文件,移植方便。
  • ??性能??:由于代碼已經直接嵌入到可執行文件中,運行時不需要額外的加載時間,執行效率較高。
缺點
  • ??文件體積大??:每個使用靜態庫的可執行文件都會包含一份庫代碼的副本,會導致可執行文件體積變大。
  • ??更新困難??:如果靜態庫有更新,所有使用該庫的可執行文件都需要重新編譯鏈接。
動態庫

定義??:動態庫是在程序運行時才被加載到內存中供程序使用的庫。多個程序可以共享同一個動態庫的內存副本。是C/C++或者其他第三方軟件提供的所有方法的集合,被所有程序以鏈接的方式關聯起來。動態庫的文件擴展名通常是?.so

動態鏈接在動態連接中,編譯階段只是記錄程序需要使用哪些動態庫(.so?文件),然后再需要時加載,并不會把庫代碼復制到可執行文件中。

  • 創建動態庫??:同樣使用之前的?add.c?和?sub.c?源文件,先編譯成目標文件:
gcc -c -fPIC add.c sub.c

-fPIC?表示生成位置無關代碼,這是創建動態庫所必需的。
使用?gcc?創建動態庫:

gcc -shared -o libmath.so add.o sub.o

-shared?表示生成共享庫。

??使用動態庫??:

gcc main.c -L. -lmath -o main

編譯命令和靜態庫類似,但在運行可執行文件時,需要確保系統能找到動態庫。可以通過設置?LD_LIBRARY_PATH?環境變量來指定動態庫的搜索路徑:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./main
優點
  • ??節省內存??:多個程序可以共享同一個動態庫的內存副本,減少了內存的使用。
  • ??更新方便??:如果動態庫有更新,只需要替換動態庫文件,不需要重新編譯使用該庫的所有程序。
缺點
  • ??依賴問題??:可執行文件依賴于外部的動態庫文件,如果動態庫文件丟失或版本不兼容,程序可能無法正常運行。
  • ??加載時間??:程序運行時需要加載動態庫,會有一定的加載時間開銷。

?

注意:linux系統中認為后綴無意義,但不是代表gcc認為后綴無意義,也就是說我們后綴不對的話gcc編譯會出錯的。

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

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

相關文章

若依框架二次開發——RuoYi-AI 集成本地大模型

文章目錄 前提條件1. RuoYi-AI 已成功部署并運行2. Ollama 本地大模型已安裝1. 配置本地大模型2. 切換至本地模型3. 開始對話總結本文將詳細介紹如何在 RuoYi-AI 中集成本地 Ollama 大模型,使系統能夠在 離線環境 下提供智能對話能力。 前提條件 在開始集成本地大模型之前,…

Flask學習筆記 - 模板渲染

Flask 模板渲染 模板是包含占位符的 HTML 文件 Flask 使用 Jinja2 模板引擎來處理模板渲染。模板渲染允許你將動態內容插入到 HTML 頁面中&#xff0c;使得應用能夠生成動態的網頁內容。 創建模板&#xff1a;將 HTML 文件放在 templates 文件夾中&#xff0c;使用 Jinja2 占…

解碼 from XXX import * - 導入的真相

文章目錄 前言一、 什么是 from XXX import *?二、基本用法:導入的實際效果三、默認行為:無 __all__ 的情況四、與直接運行 XXX.py 的對比示例模塊使用 from XXX import *直接運行 python example.py關鍵差異五、為什么需要注意 from XXX import *?最佳實踐六、實際應用場景…

JavaScript 中常見的鼠標事件及應用

JavaScript 中常見的鼠標事件及應用 在 JavaScript 中&#xff0c;鼠標事件是用戶與網頁進行交互的重要方式&#xff0c;通過監聽這些事件&#xff0c;開發者可以實現各種交互效果&#xff0c;如點擊、懸停、拖動等。 在 JavaScript 中&#xff0c;鼠標事件類型多樣&#xff0…

Nacos注冊中心AP模式核心源碼分析(單機模式)

文章目錄 概述一、客戶端啟動主線流程源碼分析1.1、客戶端與Spring Boot整合1.2、注冊實例&#xff08;服務注冊&#xff09;1.3、發送心跳1.4、拉取服務端實例列表&#xff08;服務發現&#xff09; 二、服務端接收請求主線流程源碼分析2.1、接收注冊請求2.1.1、初始化注冊表2…

prism WPF 模塊

模塊 DLL ModuleA 和 ModuleB 都要安裝 Prism.Unity 引用方式1 項目引用 直接 在引用中添加項目引用 App.xaml.cs 添加模塊 ConfigureModuleCatalog using ModuleA; using ModuleB; using Prism.Ioc; using Prism.Modularity; using Prism.Unity; using PrismWpfApp.ViewMo…

CSS:換行與不換行

一、CSS 不允許換行 在 CSS 中&#xff0c;有幾種方法可以控制文本不換行&#xff1a; 1. 使用 white-space 屬性 .no-wrap {white-space: nowrap; } white-space: nowrap; 會強制文本在一行顯示&#xff0c;不換行。 2. 使用 overflow 和 text-overflow 通常與 white-sp…

JavaScript BOM、事件循環

目錄 BOM&#xff08;瀏覽器對象模型&#xff09; 一、window 對象 1. 窗口控制 2. 定時器 二、location 對象 三、navigator 對象 四、history 對象 五、screen 對象 六、本地存儲 1. localStorage 2. sessionStorage 七、BOM 應用場景 八、總結 JavaScript 執行…

k8s運維面試總結(持續更新)

一、你使用的promethues監控pod的哪些指標&#xff1f; CPU使用率 內存使用率 網絡吞吐量 磁盤I/O 資源限制和配額&#xff1a;Prometheus可以監控Pod的資源請求和限制&#xff0c;確保它們符合預設的配額&#xff0c;防止資源過度使用。具體指標如container_spec_cpu_quota用于…

ubuntu20.04升級成ubuntu22.04

命令行 sudo do-release-upgrade 我是按提示輸入y確認操作&#xff0c;也可以遇到配置文件沖突時建議選擇N保留當前配置

Cortex-M? 函數調用的入棧與出棧操作

在 ARM Cortex-M 系列單片機中,普通C函數調用的入棧(壓棧)和出棧操作通常由編譯器編譯后生成的代碼管理,而硬件僅負責部分關鍵操作。以下是詳細分析: 1. 函數調用與返回的核心機制 (1) 硬件自動完成的部分 返回地址的保存: 當通過 BL(Branch with Link)或 BLX 指令調用…

DeepSeek能否用于對話系統(Chatbot)?技術解析與應用實例!

引言&#xff1a;Chatbot 的進化與挑戰 你有沒有發現&#xff0c;現在的AI聊天機器人越來越聰明了&#xff1f;無論是客服助手、智能語音設備&#xff0c;還是社交媒體上的自動回復&#xff0c;Chatbot&#xff08;對話系統&#xff09;已經滲透到我們生活的方方面面。但問題是…

多表查詢的多與一

1.查尋表需要的條件 1.1.首先我們要了解查詢表有哪些 1.1.1.多對一 多對一就是一個年表擁有例外一個表的多條數據 一個表對應立一個表的多條數據&#xff0c;另一個表對應這個表的多條數據 這個點被稱為多對一 1.1.2.多對多 多對多簡單來說就是需要一個中間商 中間商就…

配置文件、Spring日志

SpringBoot配置?件 SpringBoot?持并定義了配置?件的格式, 也在另?個層?達到了規范其他框架集成到SpringBoot的 ?的. 很多項?或者框架的配置信息也放在配置?件 中, ?如: 項?的啟動端? 數據庫的連接信息(包含??名和密碼的設置) 第三?系統的調?密鑰等信息 ?…

嵌入式——Linux系統的使用以及編程練習

目錄 一、Linux的進程、線程概念 &#xff08;一&#xff09;命令控制進程 1、命令查看各進程的編號pid 2、命令終止一個進程pid 二、初識Linux系統的虛擬機內存管理 &#xff08;一&#xff09;虛擬機內存管理 &#xff08;二&#xff09;與STM32內存管理對比 三、Lin…

Springcache+xxljob實現定時刷新緩存

目錄 SpringCache詳解 SpringCache概述 核心原理 接口抽象與多態 AOP動態代理 核心注解以及使用 公共屬性 cacheNames KeyGenerator&#xff1a;key生成器 key condition&#xff1a;緩存的條件&#xff0c;對入參進行判斷 注解 xxl-job詳解 SpringcacheRedis實現…

前端Uniapp接入UviewPlus詳細教程!!!

相信大家在引入UviewPlusUI時遇到很頭疼的問題&#xff0c;那就是明明自己是按照官網教程一步一步的走&#xff0c;為什么到處都是bug呢&#xff1f;今天我一定要把這個讓人頭疼的問題解決了&#xff01; 1.查看插件市場 重點&#xff1a; 我們打開Dcloud插件市場搜素uviewPl…

vector的介紹與代碼演示

由于以后我們寫OJ題時會經常使用到vector&#xff0c;所以我們必不可缺的是熟悉它的各個接口。來為我們未來作鋪墊。 首先&#xff0c;我們了解一下&#xff1a; https://cplusplus.com/reference/vector/ vector的概念&#xff1a; 1. vector是表示可變大小數組的序列容器…

ZLMediaKit 源碼分析——[5] ZLToolKit 中EventPoller之延時任務處理

系列文章目錄 第一篇 基于SRS 的 WebRTC 環境搭建 第二篇 基于SRS 實現RTSP接入與WebRTC播放 第三篇 centos下基于ZLMediaKit 的WebRTC 環境搭建 第四篇 WebRTC學習一&#xff1a;獲取音頻和視頻設備 第五篇 WebRTC學習二&#xff1a;WebRTC音視頻數據采集 第六篇 WebRTC學習三…

【零基礎入門unity游戲開發——2D篇】SortingGroup(排序分組)組件

考慮到每個人基礎可能不一樣&#xff0c;且并不是所有人都有同時做2D、3D開發的需求&#xff0c;所以我把 【零基礎入門unity游戲開發】 分為成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】&#xff1a;主要講解C#的基礎語法&#xff0c;包括變量、數據類型、運算符、…