makefile如何减小可执行文件的大小(没有用到的函数不参与链接)
一、問題
在linux下玩makefile玩的多了,發(fā)現(xiàn)一個(gè)問題。程序總是越編越大,換句話說就是程序編譯出來的可執(zhí)行文件總是在不停的增大,特別是加入了外部的靜態(tài)庫之后,程序文件顯著增大,造成程序下載耗時(shí)增大,甚至造成程序空間溢出,FLASH不夠用。
我分析了一下,雖然所引用的靜態(tài)庫本身確實(shí)很大,但是我的程序中只用到了其中幾個(gè)函數(shù),按理來說,它只取這幾個(gè)函數(shù)進(jìn)行鏈接,鏈接之后的可執(zhí)行文件不應(yīng)該那么大才對(duì),肯定是哪里沒有設(shè)置好。我記得在windows下的KEIL或者IAR就不會(huì)這樣,它們里面有一個(gè)設(shè)置選項(xiàng),可以指定“沒有使用的函數(shù)不參與鏈接”之類的,那么makefile里面難道沒有類似的功能嗎?于是,一番百度和CSDN之后,輕松搞定!
二、原理
下文引自網(wǎng)絡(luò)博客:
因?yàn)镚CC鏈接操作以section作為最小的處理單元,一個(gè)section中可以包含很多個(gè)function,而一個(gè)section中只要有一個(gè)function被引用,該section就會(huì)被加入鏈接,最終生成可執(zhí)行文件。
換句話說就是,在缺省情況下,某個(gè).c程序中的所有function,實(shí)際上都會(huì)編譯成同一個(gè)section。那么,只要你的代碼中用到這個(gè).c生成的.o的其中任何一個(gè)function,系統(tǒng)就會(huì)將這整個(gè)section進(jìn)行鏈接。這就導(dǎo)致,我們?cè)谝猛獠快o態(tài)庫時(shí),不管你是引用其中一個(gè)函數(shù),還是引用全部的函數(shù),你最終編譯鏈接出來的可執(zhí)行文件都一樣大,系統(tǒng)并不會(huì)自動(dòng)根據(jù)你所引用的函數(shù)個(gè)數(shù)的多少而動(dòng)態(tài)的調(diào)整鏈接方式。
三、辦法
那么,要怎么修改呢?方法也很簡單,兩個(gè)步驟即可:
-
編譯時(shí):使用"-ffunction-sections"和"-fdata-sections"將每個(gè)function/data創(chuàng)建為一個(gè)sections,sections名與function/data名保持一致。
-
鏈接時(shí):采用"-Wl, -gc-sections"申明,告訴系統(tǒng)去掉那些沒用用到的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運(yùn)行結(jié)果對(duì)比:
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*可以看出,優(yōu)化后的bin文件,減少了 8896-8432=464 bytes。
五、注意
請(qǐng)注意:
1)使用了section選項(xiàng),當(dāng)函數(shù)被聲明了,但是函數(shù)沒有被調(diào)用,函數(shù)體不實(shí)現(xiàn)也編譯ok,但是函數(shù)體不能重復(fù)定義;
2)一但使用-Wl,-gc-sections選項(xiàng)之后,將無法使用gdb調(diào)試。也無法使用gprof工具;
總結(jié)
以上是生活随笔為你收集整理的makefile如何减小可执行文件的大小(没有用到的函数不参与链接)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10怎么将“我的电脑”设置到桌面
- 下一篇: 玩转GIT系列之【git submodu