linux下执行QT可执行文件报错

日期:2019-11-07编辑作者:操作系统

老样子,不多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"

 

int main()
{
test_a();
test_b();
test_c();
return 0;
}
</code>

有时候在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
www.129028.com金沙,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可执行程序会比其他动态可执行文件大很多。

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指定的动态库搜索路径;
  1. 配置文件/etc/ld.so.conf中指定的动态库搜索路径;
  2. 默认的动态库搜索路径/lib;
  3. 默认的动态库搜索路径/usr/lib。
    有关环境变量:
    LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径

2、vim ld.so.conf

3、添加你可执行文件的目录,也就是你的依赖库的路径,例如:/home/ninetripod/Desktop/test/debug

4、配置完后运行ldconfig

本文由www.129028.com金沙发布于操作系统,转载请注明出处:linux下执行QT可执行文件报错

关键词:

bash shell中测试命令

bash shell中测试命令      test 命令提供了 if - than 语句中测试不同条件的途径。如果 test 命令中列出的条件成立, ...

详细>>

常用文本操作命令

1. tr 按列替换 echo "{123}" | tr -d '{}' 删除输入中的 "{" 和 "}" cat testfile |tr a-z A-Z 将文件testfile中的小写字母全部转换成大...

详细>>

Windows 10 运行原生Bash【Ubuntu】

当前widnows用户的 AppDataLocallxss目录下安装了ubuntu,其中rootfs是和ubuntu安装的目录一致 bash进入的就是LINUX的SHELL,因此...

详细>>

linux下获取本机的获取内网和外网地址www.129028.com金沙

1.获取内网地址(私有地址) 获取IP地址,JS也可以获取客户端IP地址啦,大家知道JS不能跨域,所以这里借助了jquery,真...

详细>>