編譯指定glibc
1. linux 的rpm包有 glibc和linux 兩種,有什麼區別呀!
linux的rpm發行包,一般會在rpm文件名中說明編譯這個rpm的環境,安裝rpm的時候也要找到對應自己操作系統環境的包來安裝。
1:如果rpm包名裡面有linux並且指定了linux版本,說明這個rpm包就是在這個linux版本下編譯的,如果你的linux版本匹配,就可以安裝。
2:如果rpm包名裡面有glibc並且指定了glibc版本,說明這個rpm包需要在指定的glibc版本環境中安裝,glibc是linux下的基礎庫。
3:這2種包不一定是互斥的,只要符合環境要求,都可以安裝。
2. make install glibc,卸載glibc
你沒定義安裝路納鋒徑,應該是按默認安裝到/usr/local下面的了,刪除相畝橡應文件夾就可以的了.make clean 只是清除編譯目錄下的已編譯文件.make install後會將編譯好的文件迅茄旁安裝到一個或多個指定或默認的目錄里的.
3. linux編譯安裝glibc-2.17
這個其實應該找一個舊版本的ntfs-3g,版本太新
另外,不要隨便編譯安裝glibc,如果你新編譯的glibc覆蓋了系統中的,不能保證你的系統還能正常使用
4. 高版本gcc編譯出的程序在低版本glibc機器上運行
比如我們用gcc 9.3.0編譯程序,但需要發布的機器gcc版本是4.8.5,怎麼辦?祥孫
你可能想到如下方法
將libc和libstdc++靜態編譯,編譯時帶上如下參數。
glibc並不推薦靜態鏈接,你依賴的其他庫可能依賴的了glibc,並且往往是動態鏈接的,可以通過 nm <bin> | grep GLIBC_ 確定你的程序是否依賴了glibc。
使用攜帶gcc9.3.0環境的容器發布程序,是可以的。但是在一些沒有容器且沒有sudo許可權的場合,依然不太友好。
這個方法雖然聽起來不是很優雅,但其實如果你對elf文件有一些了解,是不錯的方式。下面說下具體的方法。
當你有條件獲得程序源碼,並能夠重新編譯時,可以直接在編譯時指定相關參數來解決。
先說編譯時要增加的參數:
gcc參數
ld參數
這兩個參數分別設置的elf文件中的rpath和interpreter欄位。
rpath
全名 run-time search path ,是elf文件中一個欄位,它指定了可執行文件執行時搜索so文件的第一優先位置,一般編譯器默認將該欄位設為空。elf文件中還有一個類似的欄位runpath,其作用與rpath類似,但搜索優先順序稍低。搜索優先順序:
如果你需要使用相對路徑指定lib文件夾,可以使用 ORIGIN 變數,ld會將ORIGIN理解成可執行文件所在的路徑。
interpreter
動態庫載入器,程序啟動時,操作系統會先把控制權轉交給ld-linux-x86-64.so.2,該so負責載入所有程序依賴的so。。這個欄位在鏈接時會幫你自動設置,64bit程序一般為 /lib64/ld-linux-x86-64.so.2 。修改rpath或者LD_LIBRARY_PATH指向本地lib目錄,但通過ldd程序,發現/lib64/ld-linux-x86-64.so.2這個so仍然指向系統so。原因就是這個字並寬段是寫謹蔽鏈死在elf文件中的,並不受LD_LIBRARY_PATH影響。
編譯時帶上這兩個參數,下面只需要將你程序依賴的so打包一份,隨程序進行發布即可。
當你無法編譯程序時,也可以通過其他方式修改rpath和interpreter。這種情況需要使用到一個工具 patchelf ,通過 dnf install patchelf 即可安裝。你可以通過它修改elf文件的rpath和interpreter:
除了絕對路徑,一種比較常見的方式是在部署前,使用 pwd 獲取當前路徑,使用相對路徑指向本地lib。