Linux基礎開發工具二(gcc/g++,自動化構建makefile)

3. 編譯器gcc/g++

3.1 背景知識


1. 預處理(進行宏替換/去注釋/條件編譯/頭文件展開等)

2. 編譯(生成匯編)

3. 匯編(生成機器可識別代碼)

4. 連接(生成可執行文件或庫文件)

3.2?gcc編譯選項

格式 : gcc 【選項】 要編譯的文件 【選項】【目標文件】

1.預處理(進行宏替換)

預處理功能主要包括宏定義,?件包含,條件編譯,去注釋等。

預處理指令是以#號開頭的代碼行。

實例: gcc –E hello.c –o hello.i

選項“-E”,該選項的作?是讓 gcc 在預處理結束后停?編譯過程。

選項“-o”是指?標?件,“.i”?件為已經過預處理的C原始程序。

2. 編譯(生成匯編)

在這個階段中,gcc ?先要檢查代碼的規范性、是否有語法錯誤等,以確定代碼的實際要做的?作,在檢查?誤后,gcc 把代碼翻譯成匯編語?。

用戶可以使?“-S”選項來進?查看,該選項只進?編譯?不進?匯編,?成匯編代碼。

實例: gcc –S hello.i –o hello.s
?

3. 匯編(生成機器可識別代碼)

匯編階段是把編譯階段?成的“.s”?件轉成?標?件

讀者在此可使?選項“-c”就可看到匯編代碼已轉化為“.o”的?進制?標代碼了

實例: gcc –c hello.s –o hello.o

4. 連接(生成可執行文件或庫文件)


3.3 動態鏈接和靜態鏈接

在我們的實際開發中,不可能將所有代碼放在?個源?件中,所以會出現多個源?件,?且多個源?件之間不是獨?的,?會存在多種依賴關系,如?個源?件可能要調?另?個源?件中定義的函數,但是每個源?件都是獨?編譯的,即每個*.c?件會形成?個*.o?件,為了滿?前?說的依賴關系,則需要將這些源?件產?的?標?件進?鏈接,從?形成?個可以執?的程序。這個鏈接的過程就是靜態鏈接。靜態鏈接的缺點很明顯:

  1. 浪費空間:因為每個可執?程序中對所有需要的?標?件都要有?份副本,所以如果多個程序對同?個?標?件都有依賴,如多個程序中都調?了printf()函數,則這多個程序中都含有

    printf.o,所以同?個?標?件都在內存存在多個副本;

  2. 更新?較困難:因為每當庫函數的代碼修改了,這個時候就需要重新進?編譯鏈接形成可執?程序。但是靜態鏈接的優點就是,在可執?程序中已經具備了所有執?程序所需要的任何東西,在執?的時候運?速度快

動態鏈接的出現解決了靜態鏈接中提到問題。動態鏈接的基本思想是把程序按照模塊拆分成各個相對獨?部分,在程序運?時才將它們鏈接在?起形成?個完整的程序,?不是像靜態鏈接?樣把所有程序模塊都鏈接成?個單獨的可執??件。

動態鏈接其實遠?靜態鏈接要常?得多。?如我們查看下 hello 這個可執?程序依賴的動態庫,會發現它就?到了?個c動態鏈接庫:

$ ldd hello
linux-vdso.so.1 => (0x00007fffeb1ab000)
libc.so.6 => /lib64/libc.so.6 (0x00007ff776af5000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff776ec3000)# ldd命令?于打印程序或者庫?件所依賴的共享庫列表。

在這里涉及到?個重要的概念: 庫!!!

我們的C程序中,并沒有定義“printf”的函數實現,且在預編譯中包含的“stdio.h”中也只有該函數的聲明,?沒有定義函數的實現,那么,是在哪?實“printf”函數的呢?

答案是:系統把這些函數實現都被做到名為 libc.so.6 的庫文件中去了,在沒有特別指定時,gcc 會到系統默認的搜索路徑“/usr/lib”下進行查找,也就是鏈接到 libc.so.6 庫函數中去,這樣就能實現函數“printf”了,而這也就是鏈接的作用。

如何理解庫?
為什么要有庫?讓程序員直接使用,提高開發效率,語言上的庫更多的時提供公共的方法集合(c語言提供的printf需要stdio.h, c++提供STL容器 需要iostream),printf(“hello world” )是打印到了顯示器硬件上,是c語言工程師把printf往顯示器上打印的功能寫好了把他放在庫里面你直接調用;使你不用外部的東西直接在語言當中就能編程使用語言提供的方法能在語言層面調用printf,STL容器之類)把搭建上層應用所需要的所有底層功能全部按技術角度提前寫好放入庫,讓程序員直接使用,提高開發效率。

動態庫/共享庫最終也是會加載到內存中的,只有一份,把公共的方法抽取出來,在系統中只有一份節省內存資源,磁盤里面不存速度慢一點。


?動態鏈接就是程序還沒加載到內存中時,就已經和動態庫建立了連接;

動態鏈接:

程序通過連接器獲取了連接信息,要進行鏈接!!

進行鏈接就是去動態庫獲取寫入方法的地址;

優點:節省資源;

缺點:動態庫一旦丟失所有程序無法直接運行、速度慢;


靜態鏈接:? 把你要的方法直接拷貝到可執行程序中

動態庫把方法直接給了連接器,連接器進行鏈接時,直接給程序,和動態庫取消聯系,不依賴任何庫

優點:不依賴任何庫,自己獨立就能運行;

缺點:體積大,占據資源多(占據磁盤空間,內存空間)無法充分利用資源,加載速度受影響

我們的系統中一般默認沒有安裝c/c++的靜態庫,我們可以用命令行安裝c/c++的靜態庫:

使用yum(適用于CentOS,RHEL,Fedora)centos:

sudo yum install glibc-static

sudo yum install libstdc++-static

如果需要完整的的開發工具鏈(如gcc、g++等),可以安裝一下包:

sudo yum install gcc gcc-c++ make

使用apt(適用于Ubuntu,Debian等):

sudo apt install libc6-dev

sudo apt?install libstdc++-static-dev

如果需要完整的的開發工具鏈(如gcc、g++等),可以安裝一下包:

sudo apt install build-essential

3.4 靜態庫和動態庫


靜態庫是指編譯鏈接時,把庫?件的代碼全部加?到可執??件中,因此?成的?件?較?,但在運?時也就不再需要庫?件了。其后綴名?般為".a"

動態庫與之相反,在編譯鏈接時并沒有把庫?件的代碼加?到可執??件中,?是在程序執?時由運?時鏈接?件加載庫,這樣可以節省系統的開銷。動態庫?般后綴名為“.so”,如前?所述的libc.so.6 就是動態庫。gcc 在編譯時默認使?動態庫。完成了鏈接之后,gcc 就可以?成可執??件,如下所?。 gcc hello.o –o hello

gcc默認生成的?進制程序,是動態鏈接的,這點可以通過 file 命令驗證。
?

Linux下,動態庫XXX.so, 靜態庫XXX.a

Windows下,動態庫XXX.dll, 靜態庫XXX.lib

如何查看是否已經安裝epel-release源:

EPEL 倉庫的配置文件通常位于 /etc/yum.repos.d/ 目錄下。你可以列出該目錄下的文件,看看是否有與 EPEL 相關的 repo 文件:

ls -l /etc/yum.repos.d/ | grep epel

也可以安裝一個廣泛使用的C++庫集合,提供了大量的功能,從智能指針到正則表達式支持等

# 安裝 Boost 靜態庫
sudo yum install boost-devel

二. 自動化構建 -make/Makefile

2.1 背景

會不會寫makefile,從?個側?說明了?個人是否具備完成?型工程的能力。

?個?程中的源?件不計數,其按類型、功能、模塊分別放在若?個?錄中,makefile定義了?系列的規則來指定,哪些?件需要先編譯,哪些?件需要后編譯,哪些?件需要重新編譯,甚?于進?更復雜的功能操作

makefile帶來的好處就是?“?動化編譯”,?旦寫好,只需要?個make命令,整個?程完全?動編譯,極?的提?了軟件開發的效率。

make是?個命令?具,是?個解釋makefile中指令的命令?具,?般來說,?多數的IDE都有這個命令,?如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可?,makefile都成為了?種在?程??的編譯?法。

make是?條命令,makefile是?個文件,兩個搭配使?,完成項目自動化構建

2.2 基本使用?

實例代碼
?

#include <stdio.h>
int main()
{
printf("hello Makefile!\n");
return 0;
}

Makefile文件

myproc:myproc.c
gcc -o myproc myproc.c
.PHONY:clean
clean:
rm -f myproc

依賴關系

上?的?件myproc,它依賴myproc.c

依賴方法

gcc -o myproc myproc.c ,就是與之對應的依賴關系

項?清理

?程是需要被清理的

像clean這種,沒有被第?個?標?件直接或間接關聯,那么它后?所定義的命令將不會被?動執?,不過,我們可以顯?要make執?。即命令?“make clean”,以此來清除所有的?標?件,以便重編譯。

但是?般我們這種clean的?標?件,我們將它設置為偽?標,? .PHONY 修飾,偽?標的特性是,總是被執?的。

這里就涉及到了總是被執行和不被執行兩個概念。

這里直接看圖詳解:

?

輸入make命令,make命令會自動在當前目錄下 找Makefile,然后用make去解釋Makefile里面的內容, 從上往下執行Makefile中的編譯方法,幫我們形成可執行程序。

有了.PHONY,make clean 就可以重復執行 rm -f code。? ? ?

.PHONY:讓make忽略源文件和可執行標文件的M時間對比
?

2.3 推導過程?

?

myproc:myproc.o
gcc myproc.o -o myprocmyproc.o:myproc.s
gcc -c myproc.s -o myproc.omyproc.s:myproc.i
gcc -S myproc.i -o myproc.smyproc.i:myproc.c
gcc -E myproc.c -o myproc.i.PHONY:clean
clean:
rm -f *.i *.s *.o myproc

編譯過程?

$ make
gcc -E myproc.c -o myproc.i
gcc -S myproc.i -o myproc.s
gcc -c myproc.s -o myproc.o
gcc myproc.o -o myproc

?

make是如何工作的,在默認的方式下,也就是我們只輸入make命令。那么:

  1. make會在當前?錄下找名字叫“Makefile”或“makefile”的?件。
  2. 如果找到,它會找?件中的第?個?標?件(target),在上?的例?中,他會找到 myproc 這個?件,并把這個?件作為最終的?標?件。
  3. 如果 myproc ?件不存在,或是 myproc 所依賴的后?的 myproc.o ?件的?件修改時間要? myproc 這個?件新(可以? touch 測試),那么,他就會執?后?所定義的命令來?成myproc 這個?件。
  4. 如果 myproc 所依賴的 myproc.o ?件不存在,那么 make 會在當前?件中找?標為myproc.o ?件的依賴性,如果找到則再根據那?個規則?成 myproc.o ?件。(這有點像?個堆棧的過程)
  5. ?當然,你的C?件和H?件是存在的啦,于是 make 會?成 myproc.o ?件,然后再? myproc.o ?件聲明 make 的終極任務,也就是執??件 hello 了。
  6. 這就是整個make的依賴性,make會?層??層地去找?件的依賴關系,直到最終編譯出第?個?標?件。
  7. ?在找尋的過程中,如果出現錯誤,?如最后被依賴的?件找不到,那么make就會直接退出,并報錯,?對于所定義的命令的錯誤,或是編譯不成功,make根本不理。
  8. make只管文件的依賴性,即,如果在我找了依賴關系之后,冒號后?的?件還是不存在,那么就停止工作


?

輸入make命令時,會讀取當前目錄下的Makefile文件,自頂向下對文件進行掃描,首先會發現code依賴的code.o不存在,因為code.o也有依賴關系,所以make進而找code.o的依賴關系,依次往下。到最后找到code.i依賴的code.c,依賴文件列表code.c本身在當前目錄下是已經存在的,所以code.c已經具備了能夠進行形成code.i的條件了,所以make就會執行code.i的依賴方法gcc -E code.c -o code.c這條命令,一旦code.i形成那么code.s,code.s所對應的依賴關系也有了,就會執行他的依賴方法。依次往上。---這就是make自動推導的過程。

當識別到code.o不存在會向下找,因為code.o也有依賴關系,所以make除了找code.o的依賴關系,還會把上一組code.o形成code的這組依賴方法入棧,然后依次往下,等到識別到code.c已經具備了能夠進行形成code.i的條件時,然后依次出棧執行依賴方法。

不想看這個命令執行的過程,只看結果,前面加@,關閉回顯

?

2.4 擴展語法

有了變量的定義,我們要定義的目標文件叫Bin,

源文件SRC

BIN=proc.exe         # 定義變量
CC=gcc
#SRC=$(shell ls *.c) # 采?shell命令??式,獲取當前所有.c?件名
SRC=$(wildcard *.c)  # 或者使? wildcard 函數,獲取當前所有.c?件名
OBJ=$(SRC:.c=.o)     # 將SRC的所有同名.c 替換 成為.o 形成?標?件列表
LFLAGS=-o            # 鏈接選項
FLAGS=-c             # 編譯選項
RM=rm -f             # 引?命令

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

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

相關文章

PostGIS實現柵格數據入庫-raster2pgsql

raster2pgsql使用與最佳實踐 一、工具概述 raster2pgsql是PostGIS提供的命令行工具,用于將GDAL支持的柵格格式(如GeoTIFF、JPEG、PNG等)導入PostgreSQL數據庫,支持批量加載、分塊切片、創建空間索引及金字塔概覽,是柵格數據入庫的核心工具。 二、核心功能與典型用法 1…

精益數據分析(64/126):移情階段的用戶觸達策略——從社交平臺到精準訪談

精益數據分析&#xff08;64/126&#xff09;&#xff1a;移情階段的用戶觸達策略——從社交平臺到精準訪談 在創業的移情階段&#xff0c;精準找到目標用戶并開展深度訪談是驗證需求的關鍵。今天&#xff0c;我們結合《精益數據分析》中的方法論&#xff0c;探討如何利用Twit…

ORACLE RAC環境REDO日志量突然增加的分析

服務概述 CRM系統在7/11日出現REDO日志產生量突增&#xff0c;達到平時產生量的20倍以上&#xff0c;對數據同步已經造成了較大的影響。工程師接到故障申報后&#xff0c;及時進行響應&#xff0c;通過對相關日志等信息的深入分析&#xff0c;整理匯總此文檔。 二、數據庫REDO…

注冊表設置windows背景護眼色

方法一&#xff1a; CtrlR&#xff0c;輸入regedit打開注冊表 HKEY_CURRENT_USER\Control Panel\Colors 右側窗口Windows鍵值由255 255 255改為202 234 206。 方法二&#xff1a; 還是注冊表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\DefaultColo…

回溯法理論基礎 LeetCode 77. 組合 LeetCode 216.組合總和III LeetCode 17.電話號碼的字母組合

目錄 回溯法理論基礎 回溯法 回溯法的效率 用回溯法解決的問題 如何理解回溯法 回溯法模板 LeetCode 77. 組合 回溯算法的剪枝操作 LeetCode 216.組合總和III LeetCode 17.電話號碼的字母組合 回溯法理論基礎 回溯法 回溯法也可以叫做回溯搜索法&#xff0c;它是一…

自己手寫tomcat項目

一&#xff1a;Servlet的原理 在Servlet(接口中)有&#xff1a; 1.init():初始化servlet 2.getServletConfig()&#xff1a;獲取當前servlet的配置信息 3.service():服務器&#xff08;在HttpServlet中實現&#xff0c;目的是為了更好的匹配http的請求方式&#xff09; 4.g…

蘭亭妙微:用系統化思維重構智能座艙 UI 體驗

蘭亭妙微設計專注于以產品邏輯驅動的界面體驗優化&#xff0c;服務領域覆蓋AI交互、智能穿戴、IoT設備、智慧出行等多個技術密集型產業。我們倡導以“系統性設計”為方法論&#xff0c;在用戶需求與技術邊界之間找到最優解。 此次智能駕駛項目&#xff0c;我們為某車載平臺提供…

ubuntu安裝google chrome

更新系統 sudo apt update安裝依賴 sudo apt install curl software-properties-common apt-transport-https ca-certificates -y導入 GPG key curl -fSsL https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor | sudo tee /usr/share/keyrings/google-chrom…

技術測評:小型單文件加密工具的功能解析

最近在測試一款名為OEMexe的文件加密工具&#xff0c;發現它確實有一些獨特之處值得分享。這款軟件體積非常小巧&#xff0c;僅209KB&#xff0c;屬于綠色單文件版程序&#xff0c;無需安裝即可直接運行。 主要特點 多格式支持&#xff1a;能夠處理多種常見文件格式&#xff0…

Java-Objects類高效應用的全面指南

Java_Objects類高效應用的全面指南 前言一、Objects 類概述二、Objects 類的核心方法解析2.1 requireNonNull系列方法&#xff1a;空指針檢查的利器2.2 equals方法&#xff1a;安全的對象比較2.3 hashCode方法&#xff1a;統一的哈希值生成2.4 toString方法&#xff1a;靈活的對…

計網| 網際控制報文協議(ICMP)

目錄 網際控制報文協議&#xff08;ICMP&#xff09; 一、ICMP 基礎特性 二、ICMP 報文分類及作用 差錯報告報文 詢問報文 網際控制報文協議&#xff08;ICMP&#xff09; ICMP&#xff08;Internet Control Message Protocol&#xff0c;網際控制報文協議&#xff09;是 …

微服務初步學習

系統架構演變過程 一、單體架構 前后端都在一個項目中&#xff0c;包括我們現在的前后端分離開發&#xff0c;都可以看作是一個單體項目。 二、集群架構 把一個服務部署多次&#xff0c;可以解決服務不夠的問題&#xff0c;但是有些不必要的功能也跟著部署多次。 三、垂直架…

Web安全基礎:深度解析與實戰指南

一、Web安全體系架構的全面剖析 1.1 分層防御模型(Defense in Depth) 1.1.1 網絡層防護 ??防火墻技術??: 狀態檢測防火墻(SPI):基于連接狀態跟蹤,阻斷非法會話(如SYN Flood攻擊)下一代防火墻(NGFW):集成IPS、AV、URL過濾(如Palo Alto PA-5400系列)配置示例…

使用大語言模型從零構建知識圖譜(上)

從零到一&#xff1a;大語言模型在知識圖譜構建中的實操指南 ©作者|Ninja Geek 來源|神州問學 將你的 Pandas data frame 利用大語言模型轉換為知識圖譜。從零開始構建自己的基于大語言模型的圖譜構建器&#xff0c;實際使用 Langchain 的 LLMGraphTransformer &#xff…

18.自動化生成知識圖譜的多維度質量評估方法論

文章目錄 一、結構維度評估1.1 拓撲結構評估1.1.1 基礎圖論指標1.1.2 層級結構指標 1.2 邏輯一致性評估1.2.1 形式邏輯驗證1.2.2 約束滿足度 二、語義維度評估2.1 語義一致性評估2.1.1 標簽語義分析2.1.2 關系語義評估 2.2 語義表示質量2.2.1 嵌入質量2.2.2 上下文語義評估 三、…

go 集成base64Captcha 支持多種驗證碼

base64Captcha 是一個基于 Go 語言開發的驗證碼生成庫&#xff0c;主要用于在 Web 應用中集成驗證碼功能&#xff0c;以增強系統的安全性。以下是其主要特點和簡介&#xff1a; base64Captcha主要功能 驗證碼類型豐富&#xff1a;支持生成多種類型的驗證碼&#xff0c;包括純…

制作大風車動畫

這個案例的風車旋轉應用了圖形變換來實現&#xff0c;速度和縮放比例應用slider來實現&#xff0c;其中圖片的速度&#xff0c;圖片大小的信息通過State來定義變量管理&#xff0c;速度和和縮放比例的即時的值通過Prop來管理。 1. 案例效果截圖 2. 案例運用到的知識點 2.1. 核…

代碼隨想錄算法訓練營第四十二四十三天

LeetCode/卡碼網題目: 42. 接雨水84. 柱狀圖中最大的矩形98. 所有可達路徑 其他: 今日總結 往期打卡 42. 接雨水 跳轉: 42. 接雨水 學習: 代碼隨想錄公開講解 問題: 給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖&#xff0c;計算按此排列的柱子&#xff0c;下雨之后能…

SEO 優化實戰:ZKmall模板商城的 B2C商城的 URL 重構與結構化數據

在搜索引擎算法日益復雜的今天&#xff0c;B2C商城想要在海量信息中脫穎而出&#xff0c;僅靠優質商品和營銷活動遠遠不夠。ZKmall模板商城以實戰為導向&#xff0c;通過URL 重構與結構化數據優化兩大核心策略&#xff0c;幫助 B2C 商城實現從底層架構到搜索展示的全面升級&…

Linux自有服務

自有服務概述 概述 自有服務&#xff0c;即不需要用戶獨立去安裝的軟件的服務&#xff0c;而是當系統安裝好之后就可以直接使用的服務&#xff08;內置&#xff09; 顯示服務 顯示服務 命令&#xff1a;systemctl \[選項] 選項參數 list-units --type service --all&#x…