Linux編譯時如何減小so庫檔案的大小

2021-10-11 18:11:54 字數 2711 閱讀 7450

今天問了我這個問題,我就順便記錄一下。客戶問為什麼libc.so檔案再編譯前和編譯後的size不一樣啊,staging 和 compile 兩個dir下的 libc.so大小不一樣,具體有什麼區別嗎?

這是是因為編譯的時候還會用strip工具來處理庫檔案,把二進位制檔案中的包含的符號表和除錯資訊刪除掉,所以庫檔案編譯打包後會變小。

在linux下有個工具叫做strip,這是乙個可以將linux下的可執行檔案的符號表去除,減少每個可執行檔案的大小,這對於嵌入式方面很有必要。但是沒有了符號表也就意味著沒有辦法採用gdb進行除錯,因為gdb除錯是讀取elf檔案頭來獲取符號表,方便除錯,但strip之後,可執行檔案的elf檔案頭就沒有.symtab這個符號表,有的僅是動態符號表。在strip之後nm lib***.so是看不到符號表的,nm -d lib***.so可以看到動態符號表,但用處不大,但strip有個引數選項叫做--only-keep-debug,這個選項可以在strip的時候保留debug除錯資訊。

strip命令如何使用,可以自行搜尋一下。

那我們再把問題拓展下:linux編譯時如何減小so動態庫檔案的大小

在一些嵌入式系統開發中,由於成本和資源的限制需要對動態庫的大小進行限制,主要通過以下幾種方法:

1. 編譯選項使用-os,編譯優化;

2. 去掉-g選項,去除除錯資訊;

3. 通過strip工具裁剪符號及除錯資訊;

4. 只匯出必要符號;linux會預設匯出所有符號,並不僅僅匯出你開放的介面!

c++的還可以參照這裡:

轉博文:

操作步驟如下:

對效能影響不大時,避免使用c++的inline特性。

在不影響使用時,控制對stl的元件的使用。

避免使用stl的iostream的相關模板類。

構建目標動態庫時,控制符號的可見性。

對目標以及全部依賴,使用gc-sections特性。即:

對目標以及全部依賴,使用lto特性。

構建目標時,要求編譯器對目標占用的空間進行優化。

鏈結時,對於release版本,刪除不必要的除錯符號。

如下使用cmake的請求,描述選項。

# 關閉c++特性

set(cmake_cxx_flags "$ -fno-inline")

set(cmake_cxx_flags "$ -fno-exceptions")

set(cmake_cxx_flags "$ -fno-rtti")

# 控制符號的可見性

set(cmake_c_flags_release "$ -fvisibility=hidden")

set(cmake_cxx_flags_release "$ -fvisibility=hidden")

set(cmake_c_flags_release "$ -fvisibility-inlines-hidden")

set(cmake_cxx_flags_release "$ -fvisibility-inlines-hidden")

# 刪除除錯符號

set(cmake_c_flags_release "$ -s")

set(cmake_cxx_flags_release "$ -s")

# 開啟空間優化

set(cmake_c_flags_release "$ -oz")

set(cmake_cxx_flags_release "$ -oz")

else ()

set(cmake_c_flags_release "$ -os")

set(cmake_cxx_flags_release "$ -os")

endif ()

# 使用gc-section優化

set(cmake_c_flags_release "$ -ffunction-sections -fdata-sections")

set(cmake_cxx_flags_release "$ -ffunction-sections -fdata-sections")

set(cmake_exe_linker_flags "$ -wl,--gc-sections")

set(cmake_module_linker_flags "$ -wl,--gc-sections")

set(cmake_shared_linker_flags "$ -wl,--gc-sections")

# 使用icf優化

set(cmake_exe_linker_flags "$ -wl,--icf=safe")

set(cmake_module_linker_flags "$ -wl,--icf=safe")

set(cmake_shared_linker_flags "$ -wl,--icf=safe")

# 使用lto

set(cmake_c_flags_release "$ -flto=full")

set(cmake_cxx_flags_release "$ -flto=full")

set(cmake_exe_linker_flags "$ -flto=full")

set(cmake_module_linker_flags "$ -flto=full")

set(cmake_shared_linker_flags "$ -flto=full")

Linux下NDK編譯so庫

2 隨便在哪個目錄直接解壓 3 配置系統環境變數 vim etc profile 在檔案末尾新增如下內容 export android ndk ndk路徑 export path and roid ndk android ndk androi dn d k 1 建立jni目錄 mkdir jni 2...

Linux編譯 so模板

目標檔名 target libmymath.so 生成的目標所放置的位置 target path 編譯引數 cc g 依賴庫名稱,如 libs lpthread libs 指定依賴庫位置,多個引用庫之間以空格分開,如 ldflags l usr lib l lib ldflags 向 提供巨集定義,...

Linux下編譯靜態庫 a 和動態庫 so

靜態庫 在linux環境中,使用ar命令建立靜態庫檔案.如下是命令的選項 d 從指定的靜態庫檔案中刪除檔案 m 把檔案移動到指定的靜態庫檔案中 p 把靜態庫檔案中指定的檔案輸出到標準輸出 q 快速地把檔案追加到靜態庫檔案中 r 把檔案插入到靜態庫檔案中 t 顯示靜態庫檔案中檔案的列表 x 從靜態庫檔...