0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

Linux系統(tǒng)下C/C++的編譯流程與步驟

嵌入式學習站 ? 來源:嵌入式學習站 ? 作者:嵌入式學習站 ? 2022-11-08 16:11 ? 次閱讀

編譯流程分為四個階段:預處理、編譯、匯編、鏈接

Linux系統(tǒng)下g++編譯為例:

通過g++的選項可以查看過程中的每一步

預處理:處理一些#號定義的命令或語句(如#define、#include、#ifdef等),生成.i文件

編譯:進行詞法分析、語法分析和語義分析等,生成.s的匯編文件

匯編:將對應的匯編指令翻譯成機器指令,生成二進制.o目標文件

鏈接:鏈接分為兩種

靜態(tài)鏈接

在鏈接期,將靜態(tài)鏈接庫中的內(nèi)容直接裝填到可執(zhí)行程序中。

在程序執(zhí)行時,這些代碼都會被裝入該進程的虛擬地址空間中。

動態(tài)鏈接

在鏈接期,只在可執(zhí)行程序中記錄與動態(tài)鏈接庫中共享對象的映射信息。

在程序執(zhí)行時,動態(tài)鏈接庫的全部內(nèi)容被映射到該進程的虛擬地址空間。其本質(zhì)就是將鏈接的過程推遲到運行時處理

擴展:

01 為什么要有靜態(tài)鏈接?

在我們的實際開發(fā)中,不可能將所有代碼放在一個源文件中,所以會出現(xiàn)多個源文件,而且多個源文件之間不是獨立的,而會存在多種依賴關系,如一個源文件可能要調(diào)用另一個源文件中定義的函數(shù),但是每個源文件都是獨立編譯的,即每個.c文件會形成一個.o文件,為了滿足前面說的依賴關系,則需要將這些源文件產(chǎn)生的目標文件進行鏈接,從而形成一個可以執(zhí)行的程序。這個鏈接的過程就是靜態(tài)鏈接

由很多目標文件進行鏈接形成的是靜態(tài)庫,反之靜態(tài)庫也可以簡單地看成是一組目標文件的集合,即很多目標文件經(jīng)過壓縮打包后形成的一個文件

02 靜態(tài)鏈接的優(yōu)缺點缺點:

浪費空間,因為每個可執(zhí)行程序中對所有需要的目標文件都要有一份副本,如果運行多個程序并且這些程序都對同一個目標文件有依賴,那么目標文件在內(nèi)存中就會存在多個副本;

更新困難,因為每當一個依賴文件的代碼修改了,這個時候就需要全部重新編譯鏈接形成新的可執(zhí)行程序。

優(yōu)點:

運行速度快并且不依賴外部環(huán)境,因為在可執(zhí)行程序中已經(jīng)具備了所有執(zhí)行程序所需要的任何東西,在執(zhí)行的時候運行速度快。

注意:我們知道,鏈接器在鏈接靜態(tài)鏈接庫的時候是以目標文件為單位的。比如我們引用了靜態(tài)庫中的printf()函數(shù),那么鏈接器就會把庫中包含printf()函數(shù)的那個目標文件鏈接進來,如果很多函數(shù)都放在一個目標文件中,很可能很多沒用的函數(shù)都被一起鏈接進了輸出結果中。由于運行庫有成百上千個函數(shù),數(shù)量非常龐大,每個函數(shù)獨立地放在一個目標文件中可以盡量減少空間的浪費,那些沒有被用到的目標文件就不要鏈接到最終的輸出文件中。

03 為什么要有動態(tài)鏈接?

為了解決靜態(tài)鏈接中提到的兩個問題,一方面是空間浪費,另外一方面是更新困難。

流程簡介:

假設現(xiàn)在有兩個程序program1.o和program2.o,這兩者共用同一個庫lib.o,假設首先運行程序program1,系統(tǒng)首先加載program1.o,當系統(tǒng)發(fā)現(xiàn)program1.o中用到了lib.o,即program1.o依賴于lib.o,那么系統(tǒng)接著加載lib.o,如果program1.o和lib.o還依賴于其他目標文件,則依次全部加載到內(nèi)存中。當program2運行時,同樣的加載program2.o,然后發(fā)現(xiàn)program2.o依賴于lib.o,但是此時lib.o已經(jīng)存在于內(nèi)存中,這個時候就不再進行重新加載,而是將內(nèi)存中已經(jīng)存在的lib.o映射到program2的虛擬地址空間中,從而進行鏈接.

04 動態(tài)鏈接的優(yōu)缺點優(yōu)點:

節(jié)約內(nèi)存:即使需要每個程序都依賴同一個庫,但是該庫不會像靜態(tài)鏈接那樣在內(nèi)存中存在多分,副本,而是這多個程序在執(zhí)行時共享同一份副本;

更新方便:更新時只需要替換原來的目標文件,而無需將所有的程序再重新鏈接一遍。當程序下一次運行時,新版本的目標文件會被自動加載到內(nèi)存并且鏈接起來,程序就完成了升級的目標。

缺點:

性能略差:因為把鏈接推遲到了程序運行時,所以每次執(zhí)行程序都需要進行鏈接,所以性能會有一定損失。

依賴外部環(huán)境:因為把鏈接推遲到了程序運行時,所以要保證程序運行時外部的庫存在且內(nèi)容正確無誤。

審核編輯:郭婷

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11123

    瀏覽量

    207921
  • C++
    C++
    +關注

    關注

    21

    文章

    2085

    瀏覽量

    73304

原文標題:C/C++的編譯流程?

文章出處:【微信號:嵌入式學習站,微信公眾號:嵌入式學習站】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    OpenHarmony標準系統(tǒng)C++公共基礎類庫案例:HelloWorld

    1、程序簡介該程序是基于凌蒙派OpenHarmony-v3.2.1標準系統(tǒng)C++公共基礎類庫的簡單案例:HelloWorld。主要講解C++公共基礎類庫案例如何搭建和編譯。2、程序解析
    的頭像 發(fā)表于 08-13 08:23 ?246次閱讀
    OpenHarmony標準<b class='flag-5'>系統(tǒng)</b><b class='flag-5'>C++</b>公共基礎類庫案例:HelloWorld

    C++中實現(xiàn)類似instanceof的方法

    并執(zhí)行特定于類型的操作。無論是在編譯時檢查類型,還是在運行時動態(tài)標識對象類型,C++ 都提供了強大的機制來獲取類型信息
    的頭像 發(fā)表于 07-18 10:16 ?357次閱讀
    <b class='flag-5'>C++</b>中實現(xiàn)類似instanceof的方法

    SEGGER編譯器優(yōu)化和安全技術介紹 支持最新CC++語言

    SEGGER編譯器是專門為ARM和RISC-V微控制器設計的優(yōu)化C/C++編譯器。它建立在強大的Clang前端上,支持最新的C
    的頭像 發(fā)表于 06-04 15:31 ?1168次閱讀
    SEGGER<b class='flag-5'>編譯</b>器優(yōu)化和安全技術介紹 支持最新<b class='flag-5'>C</b>和<b class='flag-5'>C++</b>語言

    c語言,c++,java,python區(qū)別

    操作系統(tǒng)、嵌入式系統(tǒng)等對性能要求較高的場景。C語言的語法相對簡單,學習曲線較平緩,也是學習其他高級語言的入門語言。 C++C++是在
    的頭像 發(fā)表于 02-05 14:11 ?1384次閱讀

    C++Linux內(nèi)核開發(fā)中從爭議到成熟

    Linux 內(nèi)核郵件列表中一篇已有六年歷史的老帖近日再次引發(fā)激烈討論 —— 主題是建議將 Linux 內(nèi)核的開發(fā)語言從 C 轉換為更現(xiàn)代的 C++。
    的頭像 發(fā)表于 01-31 14:11 ?493次閱讀
    <b class='flag-5'>C++</b>在<b class='flag-5'>Linux</b>內(nèi)核開發(fā)中從爭議到成熟

    RX系列V3.06.00的C/C++編譯器包數(shù)據(jù)手冊

    電子發(fā)燒友網(wǎng)站提供《RX系列V3.06.00的C/C++編譯器包數(shù)據(jù)手冊.pdf》資料免費下載
    發(fā)表于 01-26 15:57 ?1次下載
    RX系列V3.06.00的<b class='flag-5'>C</b>/<b class='flag-5'>C++</b><b class='flag-5'>編譯</b>器包數(shù)據(jù)手冊

    賽昉系列:OK7110-C_Qt5.15.2+Linux5.15.0_編譯手冊_V1.0

    OK7110-C_Qt5.15.2+Linux5.15.0_編譯手冊_V1.0_20230820
    發(fā)表于 01-23 16:23 ?0次下載

    C++簡史:C++是如何開始的

    MISRA C++:2023,MISRA? C++ 標準的下一個版本,來了!為了幫助您做好準備,我們介紹了 Perforce 首席技術支持工程師 Frank van den Beuken 博士撰寫
    的頭像 發(fā)表于 01-11 09:00 ?429次閱讀
    <b class='flag-5'>C++</b>簡史:<b class='flag-5'>C++</b>是如何開始的

    C語言和C++中那些不同的地方

    ++11標準。根據(jù)不同的標準,它們的功能也會有所不同,但是越新的版本支持的編譯器越少,所以本文在討論的時候使用的C語言標準是C89,C++標準是C
    的頭像 發(fā)表于 12-07 14:29 ?774次閱讀
    <b class='flag-5'>C</b>語言和<b class='flag-5'>C++</b>中那些不同的地方

    運行c程序的基本步驟

    運行C程序的基本步驟可以分為以下四個主要步驟:編寫程序、編譯程序、鏈接程序和運行程序。本文將詳細介紹這些步驟,以及它們的背后原理和細節(jié)。 第
    的頭像 發(fā)表于 11-27 16:21 ?4423次閱讀

    如何選擇創(chuàng)建c語言和c++

    的詳盡、詳實、細致的討論。 C 語言的特點和優(yōu)勢: C 語言是一種過程性的編程語言,它注重的是簡潔、高效、直接的編碼方式。以下是一些 C 語言的主要特點和優(yōu)勢: 1.1 跨平臺:C
    的頭像 發(fā)表于 11-27 15:58 ?458次閱讀

    c++怎么開始編程

    應用程序、嵌入式系統(tǒng)和網(wǎng)絡應用程序等各種領域。 在開始編程之前,你需要安裝C++的編程環(huán)境。首先,你需要下載并安裝一個編譯器,比如微軟的Visual Studio、GNU的GCC或者Clang。這些
    的頭像 發(fā)表于 11-27 15:56 ?739次閱讀

    高性能C++編程的核心要點

    也有助于降低能耗、減少散熱問題,延長硬件使用壽命。 Linux環(huán)境C++程序的特點 Linux操作系統(tǒng)具有開源、穩(wěn)定、高效的特點,成為
    的頭像 發(fā)表于 11-09 11:29 ?565次閱讀

    C++之父新作帶你勾勒現(xiàn)代C++地圖

    為了幫助大家解決這些痛點問題,讓大家領略現(xiàn)代C++之美,掌握其中的精髓,更好地使用C++,C++之父Bjarne Stroustrup坐不住了,他親自操刀寫就了這本《C++之旅》!
    的頭像 發(fā)表于 10-30 16:35 ?699次閱讀
    <b class='flag-5'>C++</b>之父新作帶你勾勒現(xiàn)代<b class='flag-5'>C++</b>地圖

    Ubuntu系統(tǒng)編譯OpenCV4.8源碼記錄

    很多人經(jīng)常會問我是否有在Ubuntu系統(tǒng)開發(fā)OpenCV C++應用的教程,其實我一直沒有,然后我有幾塊開發(fā)板都是基于Linux的,有Jetson系列的開發(fā)板,所以我以前寫過一篇文
    的頭像 發(fā)表于 10-27 16:07 ?1366次閱讀
    Ubuntu<b class='flag-5'>系統(tǒng)</b><b class='flag-5'>下</b><b class='flag-5'>編譯</b>OpenCV4.8源碼記錄