有时我们会遇到这种情况,可执行程序需要链接一些静态库,但是静态库中的函数并没有全部使用,只用了其中的几个,但是系统默认会自动把整个静态库全部链接到可执行程序中,造成可执行程序的大小大大增加,浪费了flash空间和内存空间。gcc为我们提供的解决这个问题的方法。
GCC在编译时可以使用 -ffunction-sections 和 -fdata-sections 将每个函数或符号创建为一个sections,其中每个sections名与function或data名保持一致。而在链接阶段, -Wl,–gc-sections 指示链接器去掉不用的section(其中-wl, 表示后面的参数 -gc-sections 传递给链接器),这样就能减少最终的可执行程序的大小了。
方法1:
通过gcc的-ffunction-sections和-fdata-sections选项与ld的–gc-sections选项
arm-linux-gcc -Os -ffunction-sections -fdata-sections -o boot.o boot.S
arm-linux-gcc -Os -ffunction-sections -fdata-sections -o main.o main.c
arm-linux-ld -T link.lds –gc-sections -o target.bin boot.o main.o
-ffunction-sections, -fdata-sections会使compiler为每个function和data item分配独立的section。 –gc-sections会使ld删除没有被使用的section。链接操作以section作为最小的处理单元,只要一个section中有某个符号被引用,该section就会被放入output中。这些选项一起使用会从最终的输出文件中删除所有未被使用的function和data, 只包含用到的unction和data。
Linux 如何设置编译选项只链接调用的函数
1、编译时候,GCC选项添加
COMPILE_FLAGS += -ffunction-sections -fdata-sections
2、LD选项添加
LDFLAGS += -Wl,-gc-sections
方法2:使用strip(不同编译器此名称不相同)
strip经常用来去除目标文件中(静态库/动态库)的一些符号表、调试符号表信息,减少包的大小。使用nm命令可以查看库文件的符号清单。
*.o *.a需要加–strip-unneeded参数,否则链接的时候会出错。