一文教你如何构建静态链接库

话说ISOC99有自己的一系列标准C函数库,例如我们熟悉的libc.a(包含标准I/O函数、字符串操作函数和整数数学函数)和libm.a(浮点数数学函数),可供我们在使用gcc编译工具编译程序时调用。那么,如果我们在日常学习或项目开发中积累了许多好的函数,希望日后在其他项目中能够复用时,我们又该如何去保存他们呢?今天我就告诉大家怎么办?

1. 看gcc编译器都干了些什么?

所谓,知己知彼,百战不殆。
首先,用一个例子带大家了解一下gcc的编译过程。

//main.c
int sum (int *a, int n);

int array[2] = {1, 2};

int main()
{
    int val = sum(array, 2);
    return val;
}

//sum.c
int sum(int *a, int n)
{
    int i, s = 0;
    for(i=0; i < n; i++){
        s += a[i];
    }
    return s;
}

假如一个项目共有以上2个源程序组成。main函数初始化一个整数数组,然后调用一个定义在另一个文件中的sum函数来对数组元素求和。

一般,我们会直接在命令行下键入gcc -Og -o prog main.c sum.c来直接编译出二进制的可执行的ELF格式的目标文件prog。那在此之间,gcc到底都干了些什么工作呢?

备注可以在gcc命令中添加参数-v观察到工作过程。
看图☞

静态链接

1.1 cpp预处理

cpp main.c -o main.i

预处理器cpp将源代码main.c翻译成一个ASCII码的中间文件main.i。

1.2 ccl编译

ccl -Og main.i -o main.s

C编译器ccl将中间文件翻译成一个ASCII码的汇编语言文件main.s。
备注:-O参数选择优化级别,由低到高分别为g<1<2<3。一般g和1优化级别用于调试阶段,2和3用于最后交付前的优化阶段。

1.3 as汇编

as main.s -o main.o

汇编器as将汇编文件翻译成一个二进制的可重定位的目标文件main.o。

1.4处理其他源文件

经过相同的步骤,将另一个源文件sum.c转换成sum.o

1.5 ld链接

ld -o prog main.o sum.o

1.6 加载运行

以上步骤都做完之后,最后在命令行(shell)键入./prog就可以运行啦。shell会调用操作系统中一个叫加载器的函数,它将可执行文件中的代码和数据复制到内存,然后将控制权交给该程序。

2. 创建自己的函数库

假设在某个项目中你自己编写了两个函数addvec() 和mulvec(),感觉很牛逼很好用,希望以后在其他项目里也能用的上。这里有两种方法,一是保存他们的源代码,以后编写程序时插进去;二是将他们加入到一个自己的私有库中,在使用时可在其他文件中直接调用。

前者or后者哪个方便?

如果你选择前者,好的你可以结束阅读课,选择后者,请继续往下看:

2.1 制作目标文件

gcc -c myfuncs.c 

将包含你所需要打包的函数的c文件编译成可重定位的目标文件

2.2生成静态库

ar rcs libmyfuncs.a myfuncs.o

利用AR库制作工具,创建我们所需的静态库。

2.3 制作.h头文件

新建一个头文件myfuncs.h,要求其中包含所有myfuncs.a库中函数的原型语句。

3. 使用方法

假设我们在示例程序main2.c中需要使用静态库libvector.a中的函数。我们该怎么办呢?

3.1 添加头文件;

将头文件vector.h添加到自己的工程目录中,并在main2.c文件的顶端添加#include "vector.h"语句,之后在后续的编程语句中就可以调用库中的函数了(假设我们需要调用库中的addvec()函数)。

3.2 正确使用编译选项

当你的程序main2.c编写完毕后,需要在命令行链接我们的自定义静态库libvector.a。

gcc -c main2.c
gcc -static -o prog2c main2.o -L. -lvector

或者

gcc -c main2.c
gcc -static -o prog2c main2.o ./libvector.a
  • 第一条语句用来生成目标文件main2.o;
  • 第二条语句中,
    • -static参数告诉连接器应该构建一个完全链接的(所有函数和全局变量的地址均已添加进ELF格式的文件了)可执行目标文件,它可以直接加载到内存并运行,且在加载时无需再做其他链接。
    • -L 告诉链接器应该在当前目录下查找库(因为L后面跟的是一个点,而点在linux系统中代表当前目录)。
    • -l 后面直接跟你需要链接的库的名字的缩写myfuncs,而不是全称libmyfuncs.a。
    • 切记:链接器是从左到右依次解析各个目标文件的,并把在各个目标文件中找到的所有外部应用符号记录下来,最后在标准C库文件和命令行上指定的库文件中寻找定义。如果都能找到,它就合并及重定位所有目标文件,最终构建输出可执行文件。如果有任一个符号未找到定义,就输出错误并终止。所以,被依赖的库文件一定要位于引用它文件的后面!!!如果有循环依赖,那么就在命令行上多写几次。

假设tmp.c调用libx.a中的函数,该库又调用liby.a中的函数,而liby.a又调用libx.a中的函数。那么,libx.a必须在命令行上重复出现2次:gcc tmp.c libx.a liby.a libx.a

  • 注意:链接器还会默认链接C标准函数库libc.a。

3.3 全局过程

获取更多知识,请点击关注:
嵌入式Linux&ARM
CSDN博客
简书博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容