今天問了我這個問題,我就順便記錄一下。客戶問為什麼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 從靜態庫檔...