小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

關于 gcc 中遇到的問題,這里有你想要的全部答案

 菌心說 2022-01-14

前言

什么是 gcc

[gcc 官方網站](https://gcc./)

GCC(GNU Compiler Collection,GNU編譯器套件),是由 GNU 開發(fā)的編程語言編譯器。它是以 GPL(General Public License)許可證所發(fā)行的自由軟件,也是 GNU 計劃的關鍵部分(GPU 是一個軟件工程項目,是 GNU's Not Unix 的縮寫)。

GCC 原本作為 GNU 操作系統(tǒng)的官方編譯器,現(xiàn)已被大多數(shù)類 Unix 操作系統(tǒng)(如Linux、BSD、Mac OS X等)采納為標準的編譯器,GCC 同樣適用于微軟的Windows。GCC 是自由軟件過程發(fā)展中的著名例子,由自由軟件基金會以 GPL 協(xié)議發(fā)布。

什么是 glibc

[glibc 官方網站](
https://www./software/libc/)

glibc 是 gnu 發(fā)布的 libc 庫,即 c 運行庫。glibc 是 linux 系統(tǒng)中最底層的 api,幾乎其他任何的運行庫都會依賴 glibc. glibc 除了封裝 linux 操作系統(tǒng)所提供的系統(tǒng)服務外,它本身提供了許多其它一些必要服務的實現(xiàn),主要有:

  • string:字符串處理

  • signal:信號處理

  • dlfcn:管理共享庫的動態(tài)加載

  • direct:文件目錄操作

  • elf:共享庫的動態(tài)加載器,即 interpreter

  • iconv:不同字符集的編碼轉換

  • inet:socket 接口的實現(xiàn)

  • intl:gettext 的實現(xiàn)

  • io

  • linuxthreads

  • locale:本地化

  • login:虛擬終端設備的管理,及系統(tǒng)的安全訪問

  • malloc:動態(tài)內存管理的分配與管理

  • nis

  • stdlib

  • math

gcc 和 glibc 的關系

首先,gcc 是編譯器,基本上 linux 下所有程序(包括內核)都是 gcc 編譯的,libc 也是。但 gcc 和 libc 又是相互依賴的,什么意思呢?就是在編譯 c/cpp 代碼時,既需要 gcc,也需要 libc.

gcc 發(fā)行版本

截止2021年8月,最新版本已經到 gcc11.2 了。

glibc 發(fā)行版本

截止2021年8月,最新版本已經到 glibc2.34 了,歷史版本有 glibc2.29、2.30、2.31、2.32、2.33 等。

查看命令

1、查看當前系統(tǒng)的 glibc 版本

  • 方法1:

/lib/x86_64-linux-gnu/libc.so.6

為什么這個庫可以直接運行呢?原來是在 libc 的代碼中有一點小手腳:

void__libc_main (void) {     __libc_print_version ();     _exit (0); }
  • 方法2:

ldd 命令也是 glibc 提供的,所以也能查看 glibc 版本:

ldd --version

2、查看 glibc 的 api 版本

strings /lib/x86_64-linux-gnu/libc.so.6 | grep GLIBC

3、查看 so 信息

`objdump -p test_gcc.so`,其他類似命令還有 `nm` 和 `readelf`

4、查看當前so依賴哪些so

  • 方法1:

`ldd test_gcc.so`
  • 方法2:

`objdump -x test_gcc.so | grep NEEDED`

5、獲取 gcc 依賴的某個 so 文件位置

`gcc --print-file-name=libz.so.1`

6、查看當前使用的 gcc 版本和引用的頭文件路徑

`echo | gcc -v -x c -E -`

7、查看當前so使用了GLIBC_2.23中哪些函數(shù)

`objdump -T test_gcc.so | grep GLIBC_2.23`

8、查看當前so使用的memcpy版本

`nm test_gcc.so | grep memcpy -w``objdump -T /lib/x86_64-linux-gnu/libc.so.6 | grep memcpy`

9、設置 c、c++ 頭文件路徑

`export CPLUS_INCLUDE_PATH=/opt/compiler/gcc-8.2/x86_64-custom-linux-gnu/include/c++/8.2.0:/usr/include/x86_64-linux-gnu/``export C_INCLUDE_PATH=......`

10、編譯時如何設置鏈接器版本

指定正確的 ldd 路徑,也就是對應具體的 glibc 版本(非常重要)。

11、設置鏈接庫路徑

  • 方法1:

先查看:`echo $LD_LIBRARY_PATH`,可通過該環(huán)境變量直接設置。

或者,`gcc --print-search-dirs`

  • 方法2:使用動態(tài)庫管理命令 ldconfig

`ldconfig -v`: 查看所有動態(tài)鏈接庫

`vim /etc/ld.so.conf`,顯示 `include /etc/ld.so.conf.d/*.conf`,然后`cd /etc/ld.so.conf.d`

修改完之后,要重新運行下 `ldconfig`

解釋

linux 下的共享庫機制采用了類似于高速緩存的機制,將庫信息保存在`/etc/ld.so.cache`里邊。

程序連接的時候首先從這個文件里邊查找,然后再到`ld.so.conf`的路徑里邊去詳細找。

這就是為什么修改了`ld.so.conf`要重新運行一下`ldconfig`的原因

12、c++ 標準庫: stdlibc++ 和 libc 的版本號是不一樣的

`objdump -T /usr/lib/gcc/x86_64-linux-gnu/5/libstdc++.so | grep GLIBCXX`

13、gcc 頭文件的搜索路徑順序

1. 優(yōu)先搜索`-I`指定的路徑2. 查找GCC的環(huán)境變量`C_INCLUDE_PATH`/`CPLUS_INCLUDE_PATH`/`OBJC_INCLUDE_PATH`指定的路徑3. 查找默認的搜索路徑`/usr/include`、`/usr/local/include`

14、gcc搜索鏈接庫(編譯期 + 運行期)的順序

gcc在編譯時按照如下順序尋找所需要的庫文件:

1. gcc會去找`-L`指定的目錄

2. 再找gcc的環(huán)境變量`LIBRARY_PATH`

3. 再找內定目錄

  • /lib和/lib64

  • /usr/lib 和/usr/lib64

  • /usr/local/lib和/usr/local/lib64

這是當初 compile gcc 時寫在程序內的。

這里有兩個問題:

  • 默認情況下,gcc編譯時只會查找相應的頭文件,而不會連接具體的lib。也就是說只要include設置完全,就可以編譯通過。它沒有進一步檢查include中的類和函數(shù)有沒有實現(xiàn),而是在運行時才開始查找。所以就會經常發(fā)生編譯可以通過,但運行時卻無法運行,因為在運行時它找不到相關類或者函數(shù)的實現(xiàn)。

這時,使用`-Wl`,`--no-undefined`參數(shù),如果使用了 include 文件,鏈接器卻找不到相應的實現(xiàn),就會產生錯誤提示。

  • 編譯時默認不查找當前目錄,需要使用`-L ./`指定,例如

運行時動態(tài)庫的搜索路徑的先后順序是:

1. 編譯目標代碼時指定的動態(tài)庫搜索路徑;這是通過gcc的參數(shù)`-Wl,-rpath=`指定。當指定多個動態(tài)庫搜索路徑時,路徑之間用冒號 :分隔

2. 環(huán)境變量`LD_LIBRARY_PATH`指定的動態(tài)庫搜索路徑

3. 配置文件`/etc/ld.so.conf`中指定的動態(tài)庫搜索路徑

4. 默認的動態(tài)庫搜索路徑,如:`/lib`, `/usr/lib`

注意:

1. 動態(tài)庫搜尋路徑并不包括當前目錄,所以當即使可執(zhí)行文件和其所需的so文件在同一文件夾,也會出現(xiàn)找不到問題

2. 一般不推薦直接修改環(huán)境變量,而是修改`/etc/ld.so.conf`,將相應的路徑添加上,然后`ldconfig`一下就好

3. ldconfig做的這些東西都與運行程序時有關,跟編譯時一點關系都沒有,編譯的時候還是該加`-L`就得加,不要混淆了

4. 往`/lib`和`/usr/lib`里面加 `lib`,是不用修改`/etc/ld.so.conf`的,但是完了之后要調一下`ldconfig`(很重要),不然這個`lib`會找不到。而往其他目錄加`lib`,需要修改`/etc/ld.so.conf`,并且要`ldconfig`一下。

15、如何安裝指定版本glibc

  • 從官網下載,解壓,如 ./glibc-2.21

  • cd glibc-2.21

  • mkdir build

  • mkdir /opt/glibc-2.21

  • cd build

  • ../configure --prefix=/opt/glibc-2.21

  • apt-get install gawk

  • make

  • 需要解決一些編譯告警或錯誤問題

  • 報錯(解決):./stdlib/setenv.c +270

  • 報錯(未解決):

../sysdeps/x86_64/multiarch/strstr.c:47:30

  • 未完待續(xù)。。。

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多