如何让静态库中的可执行程序不调用的函数不链接进该可执行程序?(-ffunction-sections -Wl,--gc-sections)

如何让静态库中的可执行程序不调用的函数不链接进该可执行程序?(-ffunction-sections -Wl,--gc-sections)

关键词:

-Wl,--gc-sections   -ffunction-sections  链接  elf   库

有时我们会遇到这种情况,可执行程序需要链接一些静态库,但是静态库中的函数并没有全部使用,只用了其中的几个,但是系统默认会自动把整个静态库全部链接到可执行程序中,造成可执行程序的大小大大增加,浪费了flash空间和内存空间。gcc为我们提供的解决这个问题的方法。

请看下面的例子:

fun1.c

#include <stdio.h>

void fun1_0(void)
{

    printf("filename: %s \tfunctionname = %s\n", __FILE__ , __FUNCTION__);
}

void fun1_1(void)
{

    printf("filename: %s \tfunctionname = %s\n", __FILE__ , __FUNCTION__);
}

void fun1_2(void)
{

    printf("filename: %s \tfunctionname = %s\n", __FILE__ , __FUNCTION__);
}

void fun1_3(void)
{

    printf("filename: %s \tfunctionname = %s\n", __FILE__ , __FUNCTION__);
}

fun1.h

extern void fun1_0(void);

main.c

#include <stdio.h>
#include "fun1.h"

int main(int argc, const char *argv[])
{
    fun1_0();
    printf("file:%s\tfunc:%s\n", __FILE__, __FUNCTION__);
    return 0;
}

然后执行下面的命令:

gcc -c -ffunction-sections fun1.c

ar -r libfun1.a fun1.o

gcc -c -ffunction-sections main.c

gcc main.o -L. -I. libfun1.a -Wl,--gc-sections -o main  或者 gcc main.o -L. -I. -lfun1 -Wl,--gc-sections -o main

利用nm命令可以看到main中的符号信息

可以看到其中只出现了fun1_0的符号信息,并没有出现fun1.c中其他函数的符号信息。

为了对比,我们使用下面的命令,再次生成一次main

gcc -c fun1.c

ar -r libfun1.a fun1.o

gcc -c main.c

gcc main.o -L. -I. libfun1.a -o main  或者  gcc main.o -L. -I. -lfun1 -o main

再次使用nm命令进行查看:

可以看到其中包含可fun1.c中所有的函数的符号信息。

gcc的-ffunction-sections和-fdata-sections选项与ld的--gc-sections选项  

2011-05-13 14:30:01|  分类: toolchain|举报|字号 订阅

下载LOFTER我的照片书  |

-ffunction-sections, -fdata-sections会使compiler为每个function和data item分配独立的section。 --gc-sections会使ld删除没有被使用的section。

链接操作以section作为最小的处理单元,只要一个section中有某个符号被引用,该section就会被放入output中。

这些选项一起使用会从最终的输出文件中删除所有未被使用的function和data, 只包含用到的unction和data。

时间: 2024-08-10 20:30:37

如何让静态库中的可执行程序不调用的函数不链接进该可执行程序?(-ffunction-sections -Wl,--gc-sections)的相关文章

使用“在静态库中使用 MFC”的静态库

开发工具:visual studio 2013 pro 一共是两个项目,一个是A:项目名称MySdk,静态库,多字节,在静态库中使用 MFC,运行库使用“多线程调试 DLL (/MDd)”:另一个是B:可执行程序,多字节,在静态库中使用 MFC,预处理器定义增加_AFXDLL,运行库使用“多线程调试 DLL (/MDd)”. 项目A的接口文件中: #ifdef MYSDKINTERFACE_STATIC #define MYSDKINTERFACE_API #else #ifdef MYSDKI

在共享DLL中使用MFC 和在静态库中使用MFC的区别

使用VS2008,在项目属性中有一项MFC的使用,有三种设置: 1.使用标准Windows库 2.在共享DLL中使用MFC 3.在静态库中使用MFC 第一种顾名思义. 第二种指的是打包时一些MFC的DLL的内容没有被包含在EXE文件中,所以EXE文件较小,但是运行时要求系统中要有相关的DLL文件. 第三种是将DLL中的相关代码写进EXE文件中,文件较大,但是可以在没有相关DLL的机器上运行. 同时,如果程序本来是第二种方式,发给同事,在同事机器上运行时,可能会出现错误: “无法启动程序……,由于

plist文件无法打包进.a静态库中

问题: 之前一直在做静态库的编写与维护,也一直知道静态库的图片资源是没办法打进.a中的.可是突然有个想法.由于有非常多參数的配置是在一个plist文件里的.尽管也知道这是一个plist文件,可是想想和图片资源还是有一定差别的.所以就尝试着是否能把plist打进静态库中. 分析: 1. 创建了一个简单的生成静态库的功能,然后公开了一个接口.用来输出读取plist文件的结果. 2. 创建一个简单的project,来使用上一步生成的.a文件,然后调用那个公开的接口. 3. 结果是无法读取,输出为nul

iOS framework静态库中使用xib和图片资源详解

一.新建bundle 前2篇文章介绍了iOS 最新framework和.a静态库制作及使用全解   iOS 工程套子工程,主工程和framework工程或.a library静态库工程联调 我现在是在主工程的子工程里进行,当然你在创建静态库工程(子工程)的时候也可以.前面我是懒得再建工程了,接着现成主工程套子工程的项目. 1.按下图步骤操作 2.因为iOS框架中没有bundle,要选中OS X框架找到bundle,如下图 二.往bundle加资源文件 将工程中的资源文件都加入到刚刚建的bundl

如何使用C/C++动态库与静态库中的宏

在哪个cpp文件中使用的该动态库或静态库,就在该h/cpp文件所在的工程的预处理命令中添加库中的宏. 如有库工程add,其头文件如下 #ifndef _ADD_H #define _ADD_H #if defined( _WIN32 ) || defined( __MINGW32__ ) # if defined( ADD_EXPORTS ) # define ADD_EXPORT __declspec(dllexport) # elif defined( ADD_USE_DLL_IMPORT

LINUX下C语言编程调用其他函数、链接头文件以及库文件

LINUX下C语言编程经常需要链接其他函数,而其他函数一般都放在另外.c文件中,或者打包放在一个库文件里面,我需要在main函数中调用这些函数,主要有如下几种方法: 1.当需要调用函数的个数比较少时,可以直接在main函数中包含该文件,比如一个文件夹下包含add.c和main.c文件: 方法一: 文件add.c定义两个整数相加的函数,code如下: #include <stdio.h> #include <math.h> int add(int a,int b) { int z;

Java中通过脚本引擎调用js函数

1 import java.io.*; 2 import javax.script.Invocable; 3 import javax.script.ScriptEngine; 4 import javax.script.ScriptEngineManager; 5 import javax.script.ScriptException; 6 import org.slf4j.Logger; 7 import org.slf4j.LoggerFactory; 8 import com.ppcre

VC/MFC中通过CWebPage类调用javascript函数(给js函数传参,并取得返回值)

转自:http://www.cnblogs.com/javaexam2/archive/2012/07/14/2632959.html ①需要一个别人写好的类CWebPage,将其对于的两个文件WebPage.h和WebPage.cpp添加到工程中. CWebPage类头文件和实现文件下载地址: http://download.csdn.net/detail/masikkk/4427190 ②添加WebBrowser控件,在视图/对话框类的头文件中#include "webbrowser2.h&

Objective-C静态库中含有category怎么办?

1.苹果推荐的方法 找到 target,更改其 Other Linker Flags 为: -all_load 或 -force_load -force_load,后跟随一个文件位置,可以更精确地加载所需文件. 简单点说就是,Objective-C 的动态特性使得需要,为链接器添加一个标签(设置 Other Linker Flags 为 -ObjC)来解决通过 Category 向类添加方法的问题. 但这个标签 -ObjC 在 64 位 和 iOS 中有问题,需要使用 -all_load 或 -