老样子,不多BiBi,直接进入主题!
首先我们通过三个文件生成一个对应的so库,然后演示如何调用对应的库。生成对应的五个文件,test_a.c,test_b,c,test_c.c,so_test.h,test.c。
<code>
so_test.h
#include "stdio.h"
void test_a();
void test_b();
void test_c();
</code>
<code>
test_a.c
#include "so_test.h"
void test_a()
{
printf("this is in test_a..n");
}
</code>
<code>
test_b.c
#include "so_test.h"
void test_b()
{
printf("this is in test_b..n");
}
</code>
<code>
test_c.c
#include "so_test.h"
void test_c()
{
printf("this is in test_c..n");
}
</code>
<code>
test.c
#include "so_test.h"
一、安装Qt
一、linux下的静态库
int main()
{
test_a();
test_b();
test_c();
return 0;
}
</code>
这里我使用的是Qt5.8,没有选择最新版本是怕其依赖的其它库版本太低而安装失败。
静态库中的被调用的函数的代码会在编译时一起被复制到可执行文件中去的!!可执行文件在运行不需要静态库的存在!
有时候在linux下编译好QT程序,用QTCreator运行没问题,打包移植到另一台机器上,用命令./XX执行就会报错:error while loading shared libraries:等等问题,有同学可能会问我的依赖库已经放在可执行文件同目录下了,怎么会找不到呢,这里需要把你的可执行文件的目录配置到ld.so.conf文件下,这里介绍两种方法:
生成动态库
编程三个文件生成so库,其中-shared指生成动态库,-fPIC指生成的库地址无关。
<code>gcc test_a.c test_b.c test_c.c -fPIC -shared -o
libtest.so</code>
使用动态库
<code>gcc -o test test.c -L. -ltest</code>
但是此时如果使用ldd或者运行test程序的话,就会发现程序还是运行不了。
<code>crystal@crystal:~/workspace/sotest$ ldd test
linux-vdso.so.1 => (0x00007ffea3b8a000)
libtest.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f095aa14000)
/lib64/ld-linux-x86-64.so.2 (0x00005564bf151000)</code>
这个因为我们个人的so库,并不能被系统直接识别,需要执行LD_LIBRARY_PATH 或者在/etc/ld.so.conf.d目录下面添加对应的库项。
执行<code>export
LD_LIBRARY_PATH=$(pwd)</code>然后重新运行程序。但是每次都这样会显得很麻烦,这是我们可以把我们放置so的目录添加到/etc/ld.so.conf.d/目录下面去,然后执行ldconfig命令
<code>
crystal@crystal:~/workspace/sotest$ sudo vim
/etc/ld.so.conf.d/test.conf
crystal@crystal:~/workspace/sotest$ cat
/etc/ld.so.conf.d/test.conf
/home/crystal/workspace/sotest
crystal@crystal:~/workspace/sotest$ sudo ldconfig
crystal@crystal:~/workspace/sotest$ ./test
this is in test_a..
this is in test_b..
this is in test_c..</code>
首先需要从官网获取安装包:
一、
生成静态库
生成对应的三个.o文件
<code>gcc -c test_a.c test_b.c test_c.c </code>
生成libtest.a静态库
<code>ar rcs libtest.a test_a.o test_b.o
test_c.o</code>
使用静态库
<code>gcc -o test test.c -static -L. -ltest</code>
然后运行和查看程序
<code>crystal@crystal:~/workspace/sotest$ ./test
this is in test_a..
this is in test_b..
this is in test_c..
crystal@crystal:~/workspace/sotest$ ldd test
不是动态可执行文件</code>
此时如果删除libtest.a文件程序也是可以正常运行的,并且test可执行程序会比其他动态可执行文件大很多。
直接进入5.8的文件夹,找到你对应的包就行。我选择的是下图的版本:
二、linux下动态库的构建和使用
1、cd /etc
NOTE
****编译参数解析
**
最主要的是GCC命令行的一个选项:-shared
该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
- -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
- -L.:表示要连接的库在当前目录中
- -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称l LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。
- 当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用
/sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。
调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。
静态库链接时搜索路径顺序: - ld会去找GCC命令中的参数-L2. 再找gcc的环境变量LIBRARY_PATH3.
再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile
gcc时写在程序内的
动态链接时、执行时搜索路径顺序: - 编译目标代码时指定的动态库搜索路径;
- 环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
- 配置文件/etc/ld.so.conf中指定的动态库搜索路径;
- 默认的动态库搜索路径/lib;
- 默认的动态库搜索路径/usr/lib。
有关环境变量:
LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径
1、动态库的构建
2、vim ld.so.conf
Linux 64位版本
gcc -fPIC -shared -o lib库名.so 源文件列表
3、添加你可执行文件的目录,也就是你的依赖库的路径,例如:/home/ninetripod/Desktop/test/debug
下载完成后,将工作目录切换到安装包所在的位置,依次执行:
4、配置完后运行ldconfig
# 确保安装包拥有可执行权限
chmod a+x qt-opensource-linux-x64-5.8.0.run
# 执行安装
./qt-opensource-linux-x64-5.8.0.run
例:
5、再次用命令执行即可运行
然后会出现安装引导界面,到这里就跟Windows下安装程序很像了。一路next/skip就可以了。
gcc -fPIC -shared -o libmylib.so max.c min.c
二、
1、cd /etc/ld.so.conf.d
安装引导界面
2、动态库使用
2、sudo vim exe.conf(新建一个conf文件)
等安装完成后,再进行一些配置。
gcc -o 最终的可执行文件 源文件列表 -L 动态库的目录 -l库名
3、在exe.conf里面添加你可执行文件的目录,也就是你的依赖库的路径,例如:/home/ninetripod/Desktop/test/debug
首先打开default.conf,在命令行中输入:sudo gedit /usr/lib/x86_64-linux-gnu/qt-default/qtchooser/default.conf
4、完成后执行ldconfig
然后将qt的安装路径添加进去:
例子:
5、再次执行你的可执行文件即可运行
# 把*******改为你的家目录名称即可
/home/*******/Qt5.8.0/5.8/gcc_8455澳门新,64/bin
/home/*******/Qt5.8.0
已经将int getMax(int,int)和getMin(int,int)打包在了libmylib.so中了,现在你即可把libmylib.so复制希望用你的库函数的人了!!
最后,安装libgl1-mesa-dev,在命令行中输入:sudo apt-get install libgl1-mesa-dev
使用你的库函数的人可能回这样使用:
本文由8455澳门新发布于新闻资讯,转载请注明出处:没有选择最新版本是怕其依赖的其它库版本太低