打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
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.c	gcc -Wl,-gc-sections -o test_optimized main.onormal:	gcc -c main.c	gcc -o test_normal main.oclean:	-@rm *.o test_normal test_optimized

运行结果对比:

leon@Ubuntu:~/studytest/z_mydesign/section_test2$ make normal gcc -c main.cgcc -o test_normal main.oleon@Ubuntu:~/studytest/z_mydesign/section_test2$ make optimized gcc -ffunction-sections -fdata-sections -c main.cgcc -Wl,-gc-sections -o test_optimized main.oleon@Ubuntu:~/studytest/z_mydesign/section_test2$ ll总用量 44drwxrwxr-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工具;

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
GCC警告选项例解
【linux草鞋应用编程系列】_4_ 应用程序多线程
makefile的简单使用
JavaScript 回调(callback)函数
(转)Makefile中用宏定义进行条件编译(gcc
makefile自动依赖和隐式规则测试,顺便探讨下通用的makefile的写法
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服