| 前言什么是 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 官方網站]( glibc 是 gnu 發(fā)布的 libc 庫,即 c 運行庫。glibc 是 linux 系統(tǒng)中最底層的 api,幾乎其他任何的運行庫都會依賴 glibc. glibc 除了封裝 linux 操作系統(tǒng)所提供的系統(tǒng)服務外,它本身提供了許多其它一些必要服務的實現(xiàn),主要有: 
 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 版本
 /lib/x86_64-linux-gnu/libc.so.6為什么這個庫可以直接運行呢?原來是在 libc 的代碼中有一點小手腳: void__libc_main (void) {     __libc_print_version ();     _exit (0); }
 ldd 命令也是 glibc 提供的,所以也能查看 glibc 版本: ldd --version2、查看 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
 `ldd test_gcc.so` 
 `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、設置鏈接庫路徑
 先查看:`echo $LD_LIBRARY_PATH`,可通過該環(huán)境變量直接設置。 或者,`gcc --print-search-dirs` 
 `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. 再找內定目錄 
 這是當初 compile gcc 時寫在程序內的。 這里有兩個問題: 
 這時,使用`-Wl`,`--no-undefined`參數(shù),如果使用了 include 文件,鏈接器卻找不到相應的實現(xiàn),就會產生錯誤提示。 
 運行時動態(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
 ../sysdeps/x86_64/multiarch/strstr.c:47:30 
 | 
|  | 
來自: 菌心說 > 《編程+、計算機、信息技術》