makefile如何减小可执行文件的大小(没有用到的函数不参与链接)
一、問題
在linux下玩makefile玩的多了,發現一個問題。程序總是越編越大,換句話說就是程序編譯出來的可執行文件總是在不停的增大,特別是加入了外部的靜態庫之后,程序文件顯著增大,造成程序下載耗時增大,甚至造成程序空間溢出,FLASH不夠用。
我分析了一下,雖然所引用的靜態庫本身確實很大,但是我的程序中只用到了其中幾個函數,按理來說,它只取這幾個函數進行鏈接,鏈接之后的可執行文件不應該那么大才對,肯定是哪里沒有設置好。我記得在windows下的KEIL或者IAR就不會這樣,它們里面有一個設置選項,可以指定“沒有使用的函數不參與鏈接”之類的,那么makefile里面難道沒有類似的功能嗎?于是,一番百度和CSDN之后,輕松搞定!
二、原理
下文引自網絡博客:
因為GCC鏈接操作以section作為最小的處理單元,一個section中可以包含很多個function,而一個section中只要有一個function被引用,該section就會被加入鏈接,最終生成可執行文件。
換句話說就是,在缺省情況下,某個.c程序中的所有function,實際上都會編譯成同一個section。那么,只要你的代碼中用到這個.c生成的.o的其中任何一個function,系統就會將這整個section進行鏈接。這就導致,我們在引用外部靜態庫時,不管你是引用其中一個函數,還是引用全部的函數,你最終編譯鏈接出來的可執行文件都一樣大,系統并不會自動根據你所引用的函數個數的多少而動態的調整鏈接方式。
三、辦法
那么,要怎么修改呢?方法也很簡單,兩個步驟即可:
-
編譯時:使用"-ffunction-sections"和"-fdata-sections"將每個function/data創建為一個sections,sections名與function/data名保持一致。
-
鏈接時:采用"-Wl, -gc-sections"申明,告訴系統去掉那些沒用用到的section。
四、示例
main.c
#include <stdio.h> #include <stdlib.h> #include <string.h>int fun_0() {printf("this is a test function. %s: %d\n", __FUNCTION__, __LINE__);return 0; }int fun_1() {printf("this is a test function. %s: %d\n", __FUNCTION__, __LINE__);return 0; }int fun_2() {printf("this is a test function. %s: %d\n", __FUNCTION__, __LINE__);return 0; }int fun_3() {printf("this is a test function. %s: %d\n", __FUNCTION__, __LINE__);return 0; }int fun_4() {printf("this is a test function. %s: %d\n", __FUNCTION__, __LINE__);return 0; }int fun_5() {printf("this is a test function. %s: %d\n", __FUNCTION__, __LINE__);return 0; }int fun_6() {printf("this is a test function. %s: %d\n", __FUNCTION__, __LINE__);return 0; }int main() {fun_0();return 0; }makefile
optimized:gcc -ffunction-sections -fdata-sections -c main.cgcc -Wl,-gc-sections -o test_optimized main.onormal:gcc -c main.cgcc -o test_normal main.oclean:-@rm *.o test_normal test_optimized運行結果對比:
leon@Ubuntu:~/studytest/z_mydesign/section_test2$ make normal gcc -c main.c gcc -o test_normal main.o leon@Ubuntu:~/studytest/z_mydesign/section_test2$ make optimized gcc -ffunction-sections -fdata-sections -c main.c gcc -Wl,-gc-sections -o test_optimized main.o leon@Ubuntu:~/studytest/z_mydesign/section_test2$ ll 總用量 44 drwxrwxr-x 2 leon leon 4096 3月 20 14:02 ./ drwxrwxr-x 5 leon leon 4096 3月 20 13:45 ../ -rw-rw-r-- 1 leon leon 496 3月 20 14:02 main.c -rw-rw-r-- 1 leon leon 3696 3月 20 14:02 main.o -rw-rw-r-- 1 leon leon 206 3月 20 13:50 Makefile -rwxrwxr-x 1 leon leon 8896 3月 20 14:02 test_normal* -rwxrwxr-x 1 leon leon 8432 3月 20 14:02 test_optimized*可以看出,優化后的bin文件,減少了 8896-8432=464 bytes。
五、注意
請注意:
1)使用了section選項,當函數被聲明了,但是函數沒有被調用,函數體不實現也編譯ok,但是函數體不能重復定義;
2)一但使用-Wl,-gc-sections選項之后,將無法使用gdb調試。也無法使用gprof工具;
總結
以上是生活随笔為你收集整理的makefile如何减小可执行文件的大小(没有用到的函数不参与链接)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10怎么将“我的电脑”设置到桌面
- 下一篇: ultraiso如何制作u盘启动盘(u盘