如何为Linux增加库
一. 静态库
在Linux下的静态库是以.a为后缀的文件。
1. 建静态库
h1.c 源文件
#include<stdio.h>
void hello1()
{
printf(“the first hello!\n”);
}
h2.c 源文件
#include<stdio.h>
void hello2()
{
printf(“the second hello!\n”);
}
2.主程序
hello.c 源文件
#include<stdio.h>
int main()
{
hello1();
hello2();
return 0;
}
输入命令:
gcc –c h1.c
gcc –c h2.c
ar –r libhello.a h1.o h2.o
ar –s libhello.a
ranlib libhello.a
最后再
gcc –static hello.c –L. –lhello –o hello即可生成可执行文件。注意要使用-static参数,否则生成的仍然是动态类型的文件,不过对于hello这个库则是采用静态方式来使用的而已。
二. 动态库
1.建动态库
#include<stdio.h>
void hello1()
{
printf(“the first hello!\n”);
}
h2.c 源文件
#include<stdio.h>
void hello2()
{
printf(“the second hello!\n”);
}
2. 主程序
hello.c 源文件
#include<stdio.h>
int main()
{
hello1();
hello2();
return 0;
}
输入命令:
gcc –fPIC –g –c h1.c –o libh1.o
gcc –fPIC –g –c h2.c –o libh2.o
gcc –g –shared –W1 –o libh1.so libh1.o –lc
gcc –g –shared –W1 –o libh2.so libh2.o –lc
然后再将主程序与库相连进行编译
gcc –g hello.c –o hello –L. –lh1 –lh2
最后再将当前路径放到库查找路径中去
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATY
最后再执行./hello即可运行。 
三. 动态库的查找过程
一旦连接器完成了自己的初始化工作,就查找程序所需要的库的名字。程序头中有一个指针指向dynamic段,它包含了动态连接的信息,dynamic段中的DT_STRTAB指向一个字符表,而其中的DT_NEEDED包含了一个相对于字符表的偏移,指向所需要的库名。
对于每一个库,连接器首先查找库文件位置,从本质上说是一个相当复杂的过程。DT_NEEDED所描叙的库文件名一般类似libXt.so.6 (Xt开发包, 版本6),库文件可能在任意的库文件目录中,还也可能有重名的文件。在我的系统中,这个库的实际文件名是/usr/X11R6/lib/libXt.so.6.0,最后的“.0”表示次版本号。

连接器查找下列几个地方:

 首先查看 .dynamic 段是否包含了一个叫DT_RPATH的项(它是一个以冒号分隔的库文件搜索目录列表)。这个项是在程序被连接器连接时,由命令行开关或者环境变量添加上去的。它常应用于子系统中,比如像数据库应用,我们要装载一些程序集合以及支持库到一个目录中去的时候。

 查看是否存在环境变量 LD_LIBRARY_PATH(它是一个以冒号分隔的库文件搜索目录列表)。这个项可以帮助开发者建立一个新版本的库,把他的路径添加到LD_LIBRARY_PATH中,把它和现存的可连接程序一同使用,用来测试新的库,

 连接器查看库高速缓存文件 /etc/ld.so.conf ,它包含了库名和路径的一个对应列表,如果库名存在,连接器就使用它对应的路径,用这个查找方法能够找到大部分的库(文件名不需要和要求完全符合,这点可以参考接下来的“库的版本”)。

 如果上叙的查找都失败,连接器就查找默认路径 /usr/lib ,如果库文件依旧没有找到,则显示一个错误然后退出。

连接器找到了库文件后,先打开它,然后读取ELF头,找到指向各个段的指针。连接器为库的代码段和数据段分配空间并映射到内存,随后是bss(不分配空间)。.通过库的 .dynamic 段,连接器添加这个库的符号表到符号表链,如果库所依赖的其它库没有装载的话,则添加那个库到装载队列中。

完成这个过程后,所有的库都已经被映射,loader在逻辑上拥有了一个全局的符号表,它是全部程序和被映射库的符号表的联合

如何在Linux下添加函数库的更多相关文章

  1. 标准c库函数与Linux下系统函数库 区别 (即带不带缓冲区的学习)

    我们都知道,C语言在UNIX/Linux系统下有一套系统调用(系统函数),比如文件操作open().close().write().read()等,而标准C语言的库函数中也有一套对文件的操作函数fop ...

  2. 如何在Linux下添加自己的驱动

    在此Linux驱动开发采用网络的方式,介绍两种驱动开发的方法:一.驱动编译到内核 1.先选择一个放置驱动代码的位置,例:drivers/char/xxx.c 2.在drivers/char/Kconf ...

  3. Linux下c函数dlopen实现加载动态库so文件代码举例

    dlopen()是一个强大的库函数.该函数将打开一个新库,并把它装入内存.该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的.这种机制使得在系统中添加或者删除一个模块时,都不需要重新编译了. ...

  4. linux下添加动态链接库路径、动态库加载等方法

    linux下添加动态链接库路径的方法 2017年01月20日 10:08:17 阅读数:5596   Linux共享库路径配置 Linux下找不到共享库文件的典型现象为明明已经安装某个软包(如libn ...

  5. linux下的静态库和动态库

    一.linux下的静态库   静态库中的被调用的函数的代码会在编译时一起被复制到可执行文件中去的!!可执行文件在运行不需要静态库的存在!   二.linux下动态库的构建和使用 1.动态库的构建   ...

  6. linux下的静态库和共享库

    转载&&增加:      我们在编写一个C语言程序的时候,经常会遇到好多重复或常用的部分,如果每次都重新编写固然是可以的,不过那样会大大降低工作效率,并且影响代码的可读性,更不利于后期 ...

  7. 一步一步教你如何在linux下配置apache+tomcat(转)

    一步一步教你如何在linux下配置apache+tomcat   一.安装前准备. 1.   所有组件都安装到/usr/local/e789目录下 2.   解压缩命令:tar —vxzf 文件名(. ...

  8. linux下syscall函数,SYS_gettid,SYS_tgkill

    出处:http://blog.chinaunix.net/uid-28458801-id-4630215.html     linux下syscall函数,SYS_gettid,SYS_tgkill  ...

  9. 对于linux下system()函数的深度理解(整理)

    原谅: http://blog.sina.com.cn/s/blog_8043547601017qk0.html 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同 ...

随机推荐

  1. GDB in Action

    GDB in Action 入门 编译 gcc -g -O0 -o word2vec.c word2vec -g 选项:要求 gcc 编译器保留调试符号信息. -O0 选项表示不优化,从 O1 ~ O ...

  2. #const#const int *p 为何可以不初始化

    摘自http://www.myexception.cn/cpp/1900041.html const int *p 为什么可以不初始化?c++ primer 5th   P53 写道:const 对象 ...

  3. 王之泰201771010131《面向对象程序设计(java)》第六周学习总结

    第一部分:理论知识学习部分 第五章 第五章学习内容主要分为七个模块,分别为: 1.类.超类和子类: a. 类继承的格式: class 新类名extends已有类名. b. 已有类称为:超类(super ...

  4. visual studio中csproj文件中的project guid改为小写

    安装了vs2019之后,发现有的项目中引用的其他项目的源码,但是无法识别了. 最后发现是因为project guid是大写导致的. https://stackoverflow.com/question ...

  5. HDU4745--区间DP+回文串

    这题的题意为,给你一个环状的字符串,有两只兔子分别从某任意的石头上开始跳跃.一只顺时针跳.一只逆时针跳.两只兔子每一次落脚处石头的质量都相同.兔子要一步一步的跳,且不能跳到之前跳到过的地方.总的来说, ...

  6. SSH框架整合,css、js会被过滤器过滤掉

    如果是默认状态 <!--struts2过滤器--> <filter> <filter-name>struts2</filter-name> <fi ...

  7. Series.str——字符串批量处理方法

    针对dataframe中的某一行(或列)想做批量字符串处理时,可采用此方法 series.str.python内置的str方法 例如: series.str.replace('A','B')   # ...

  8. 为django项目创建虚拟环境

    1. 先创建一个存放虚拟环境的目录  /opt/venl mkdir /opt/venl 2. cd 到该存放虚拟环境的目录下,并创建一个虚拟环境 virtualenv是如何创建“独立”的Python ...

  9. 移动端滑动轮播,原生JS

    因为公司需要自定义两个轮播图联动,又不想引入第三方库,所以自己研究了下. 下面只是一个简单的轮播图,由此再拓展一下即可实现两个轮播图联动. <!DOCTYPE html> <html ...

  10. CentOS 6快捷安装RabbitMQ教程

    1.安装Erlang yum install erlang 2.安装RabbitMQ yum install rabbitmq-server 3.配置开机自启动 chkconfig rabbitmq- ...