Linux下gcc編譯,動態庫和靜態庫,makefile,gdb調試

来源:https://www.cnblogs.com/stux/archive/2023/10/24/17785144.html
-Advertisement-
Play Games

1.編譯過程 1.1 預處理(Pre-Processing) 展開頭文件, 巨集替換(變數巨集、函數巨集)、替換空格等 gcc -E hello.c -o hello.i // -E 預處理選項, -o 重命名 1.2 編譯(Compilation) 逐行檢查程式中出現的語法錯誤,簡單的邏輯錯誤 gcc ...


1.編譯過程

1.1 預處理(Pre-Processing)

  展開頭文件, 巨集替換(變數巨集、函數巨集)、替換空格等

gcc -E hello.c  -o hello.i     // -E 預處理選項, -o 重命名

1.2 編譯(Compilation)

  逐行檢查程式中出現的語法錯誤,簡單的邏輯錯誤

gcc -S hello.i -o hello.s

1.3 彙編(Assemble)

  將 .s 彙編文件中所有的彙編指令翻譯成二進位機器碼(下麵就是來了個截圖,二進位顯示了亂碼)

gcc -c hello.s -o hello.o

1.4 鏈接(Linking)

  將 .o 的目標文件,鏈接庫文件、數據段合併,地址回填(把彙編里相對地址替換成程式運行後真正可以運行的地址)。生成可執行文件 hello

gcc hello.o -o hello

1.5 gcc常用參數

-E // 展開頭文件
-s // 生成彙編文件
-c // 編譯生成2進位文件
-I // 指定頭文件路徑 大i
-L // 指定庫文件路徑
-l // 指定庫名 小L
-g // 包含調試信息 
-On // n取 0-3, n 越大優化級別越高
-Wall //warning all 顯示所有警告
-D // 編譯時動態註入一個巨集, 編譯的時候控制#define的具體數值

2.動態庫和靜態庫

2.1 函數庫

  本質:把具有相同功能的一組函數放到同一份文件中(源碼或二進位的形式)

2.2 靜態庫

  對執行速度有要求

  • 機制:把引入的庫文件通過編譯直接複製到 .out 文件中
  • 優點:將函數庫中的函數本地化,定址方便,速度快(函數庫執行效率 = 自定義函數的執行效率)
  • 缺點:每個程式都需要複製一份,會浪費記憶體

  製作靜態庫: 

gcc -c add.c sub.c mul.c    // 製作 .o 文件
ar rs libmymath.a add.o sub.o mul.o    // 製作靜態庫
gcc hello.c -L ./ -lmymath -o app    // 指定頭文件路徑, 指定庫名, 設置文件輸出名app

2.3 動態庫

  對執行速度不敏感,對系統資源敏感;更新比較頻繁(可以避免完全重新編譯)

  • 機制:代碼共用
  • 優點:節省記憶體(共用)、易於更新(動態鏈接)
  • 缺點:相較於靜態庫函數調用速度慢,函數地址是延時綁定機制
gcc -c -fPIC add.c sub.c mul.c    // -fPIC生成與位置無關的目標文件
gcc -shared -o libmymath.so sub.o mul.o add.o    // 生成一個動態庫
gcc hello.c -o app -L ./lib -l mymath -I ./inc    // 生成文件

 啟動 ./app 報錯,錯誤原因:”動態鏈接器“ ld-linux-x86-64.so.2 搜索動態庫的路徑沒有指定

  鏈接器:工作於 gcc 編譯過程中的鏈接階段。工作結束後生成可執行文件

  動態鏈接器:工作於可執行程式運行之後,輔助載入器負責將動態庫載入到記憶體

 解決辦法

  環境變數法:export LD_LIBRARY_PATH=./lib 將當前動態庫所在的目錄加入到環境變數,終端退出後環境變數就會失效

  配置文件法:vi .bashrc 加入一行 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./lib,重啟終端,每次啟動終端自動生效

  拷貝法:把自己的動態庫直接拷貝到 /lib 或 /usr/lib 中

  緩存文件法(推薦):修改配置文件,修改緩存文件,生成動態鏈接器需要搜索的新目錄位置

sudo vim /etc/ld.so.conf    // 修改動態鏈接庫的路徑
// 將絕對路徑增加到文件中
sudo ldconfig -v    // 更新 ld.so.cache 該文件影響動態鏈接庫搜索的位置

3.makefile

3.1 語法

 目標:依賴條件

 tab縮進,指令

hello:hello.o add.o sub.o mul.o
    gcc hello.o add.o sub.o mul.o -o hello
hello.o:hello.c
    gcc -c hello.c -o hello.o
sub.o:sub.c
    gcc -c sub.c -o sub.o
add.o:add.c
    gcc -c add.c -o add.o
mul.o:mul.c
    gcc -c mul.c -o mul.o

 模式規則:在makefile中,具有有嚴格統一的規則,使用模式規則代替,模式規則中只能使用 $< 符號

%.o:%.c
    gcc -c $< -o $@

 靜態模式規則:將模式規則指定給某一個變數使用

$(obj):%.o:%.c
    gcc -c $< -o $@

 偽目標:針對殘缺的規則,使之生成目標(比如有一個clean.o文件已經是最新的,就不會執行clean清除命令

.PHONY:clean ALL

3.2 函數介紹

3.2.1 wildcard 函數

// 匹配當前工作目錄下的所有 .c 文件,將文件名組成列表,賦值給 src 變數
// src = add.c sub.c mul.c hello.o
src = $(wildcard ./*.c)

3.2.2 patsubst 函數

// 用來替換參數, 將 參數3 中包含 參數1 的部分替換為 參數2
// obj = add.o sub.o mul.o hello.o
obj = $(patsubst %.c, %.o, $(src))

3.3 普通變數和自動變數

 普通變數

  • 定義變數語法:變數名 = 變數值     (foo = abc)
  • 取變數值語法:$(變數)           (bar = $abc ---> bar = abc)

 自動變數

  • $@: 在規則的命令中,表示規則中的目標
  • $^ : 在規則的命令中,表示所有依賴條件
  • $< : 在規則的命令中,表示第一個依賴條件。如果該變數應用在”模式規則“中,它可以將依賴條件列表中的每一個依賴,依次取出,套用模式規則

3.4 關鍵字

  ALL: 預設情況下第一組生成文件的目標就是終極目標,或者顯示的寫ALL:hello表示終極目標,完成後結束makefile

  clean: 藉助makefile清除項目中的指定文件,例如(clean: -rm -rf $(obj) hello

  指令 make -n 模擬執行命令,不真正執行,可以先看一次避免出問題

3.5 修改後的 makefile

src = $(wildcard *.c)
obj = $(patsubst %.c, %.o, $(src))

CC = gcc
target = app

ALL:$(target)

$(target):$(obj)
    $(CC) $^ -o $@

$(obj):%.o %.c
    $(CC) -c $< -o $@

clean:
    -rm -rf $(obj) $(target)

.PHONY:clean ALL

4. gdb調試

4.1 基礎指令

 基礎的斷點設置和繼續運行等指令

  • -g:使用該指令編譯可執行文件,否則沒有調試表
  • gdb ./a.out
  • list:list 1 列出源碼,根據源碼指定行號設置斷點,1表示從第一行開始顯示源碼
  • b:b 55 在第55行添加斷點
  • run/r:運行程式,啟動調試(可以直接找到停止位置就是出錯位置)
  • next/n:下一條指令(越過函數)
  • step/s:下一條執行(進入函數內部)
  • print/p:列印變數值,如p var 查看 var 變數的值
  • continue:執行到下一個斷點
  • finish:結束當前函數調用
  • quit:退出調試
  • start:不使用斷點,直接開始單步調試

 設置一些條件和查看棧幀及變數

  • set args:啟動gdb調試後,通過該指令可以設置main函數的參數,需要在start和run指令之前設置
  • info b:查看當前斷點信息表
  • b 23 if i=5:設置斷點在23行,如果 i=5 時斷點才生效
  • ptybe:查看變數類型
  • display:設置跟蹤變數,display i,跟蹤變數 i
  • undisplay:取消跟蹤變數
  • bt:列出當前程式存活的棧幀
  • frame:如果有多層調用,在內層想查看外層棧幀里的參數,使用 frame n (n 是棧幀編號)切換棧幀,再使用 p var 列印變數

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

-Advertisement-
Play Games
更多相關文章
  • 作者: 大飛飛魚 來源: blog.csdn.net/ababab12345/article/details/80490621 Part1前言 最近由於筆者所在的研發集團產品需要,需要支持高性能的大文件(大都數是4GB以上)的http上傳,並且要求支持http斷點續傳。筆者在以前的博客如何實現支持大 ...
  • rustlings是學習rust的一個很優秀的題庫。2023年6月19日決定對rust做一個重新的梳理,整理今年4月份做完的rustlings,根據自己的理解來寫一份題解,記錄在此。 ...
  • 記錄EF 排序配上自定義的比較器 前言 要求頁面文件顯示的時候能夠按照序號去排序要求如下: 資料庫有一個列存放文件名,如: 1.1文件 1.2文件 1.1.1文件 1.1.11文件1.0.txt 1.1.2(文件).pdf 現在需要實現查詢的時候按照這個列排序,並且是按照序號排序。 查詢的時候是按層 ...
  • WPF應用端是我們《SqlSugar開發框架》多端界面中的一部分,和Winform前端框架、Vue3+ElementPlus前端、UniApp+Thorn移動端,組成一個完整的整體框架,後端服務是基於SqlSugar的基礎ORM的.netcore框架,提供Web API服務供各個前端使用,底層支持多... ...
  • 一:背景 1. 講故事 在分析旅程中,總會有幾例控制台的意外卡死導致的生產事故,有經驗的朋友都知道,控制台卡死一般是動了 快速編輯視窗 的緣故,截圖如下: 雖然知道緣由,但一直沒有時間探究底層原理,市面上也沒有對這塊的底層原理介紹,昨天花了點時間簡單探究了下,算是記錄分享吧。 二:幾個疑問解答 1. ...
  • 在經過基於SqlSugar框架的WPF應用端系統界面及模塊的不斷優化和重構後,視圖界面及視圖模型等代碼已趨穩定,因此完成前面的介紹後,現在開始統一基於代碼生成工具Database2Sharp進行WPF應用端界面代碼的快速生成了,代碼除了和WPF應用端的基類保持一致處理外,並添加一些註釋代碼,整合使用... ...
  • aspnetcore微服務之間通信grpc,一般服務對外介面用restful架構,HTTP請求,服務之間的通信grpc多走內網。 以前寫過一篇grpc和web前端之間的通訊,代碼如下: exercisebook/grpc/grpc-web at main · liuzhixin405/exercis ...
  • 文件類型和擴展名 文件種類 常規文件 純文本文件(ASCII) 二進位文件(binary) 數據文件(data) 在ls -al顯示屬性為[-] 目錄 在ls -al顯示屬性為[d] 鏈接文件 區塊設備文件:[b] 字元設備文件:[c] 數據介面文件:[s] 數據輸送文件FIFO:[p] 擴展名 L ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...