使用交叉编译工具链编译程序时,编译后得到一个可执行程序,该程序运行时用到的库在编译时必须存在吗?比如说 opencv 的 imshow() 函数,这个函数运行时依赖 gtk2.0 的库,所以我必须把 gtk2.0 的库准备好才可以编译吗?还是说编译时不需要该库仅仅是在运行时需要
是的,是要准备好才能编译;你可以自己实验一下;
静态编译:编译时要,运行时不需要;
动态编译,编译时要,运行时要;
程序运行时用到的库,也就是ldd命令的输出内容,是在链接时就已经决定了去哪个目录寻找吗?还是说程序运行时会动态的自己去寻找?
我不太会表达,我遇到的问题是,怎么说呢,就是:
我在虚拟机上使用 cmake 交叉编译了一个opencv程序,编译通过了,然后我把可执行程序放在开发板上,并且把交叉编译产生的库文件也一同拷贝到了开发版上,但是 opencv的库文件依赖gtk库,我在开发板上使用apt install libgtk2.0-dev 安装了gtk库,程序可以执行,直到运行到imshow函数(这个函数依赖gtk库)报错,imshow函数显示找不到gtk库。
所以我很疑惑,萌发了几个问题:
第一个问题是我在虚拟机上没有交叉编译gtk2.0库,但是opencv可执行程序成功编译出来了,好奇怪呀?他本身的源代码里没有 gtk 库,但是依赖于gtk库的函数确可以正常编译,为什么呢?
第二个问题是。那么在这个程序在开发版上运行时,他会去哪寻找gtk库呢?我猜是他去开发版的默认配置好的某个 lib 目录下寻找,请问是这样吗?
第三个问题是,如果第二个问题的假设成立,那就说明,程序运行时需要的gtk库在编译的链接过程中根本不需要存在,也就是虚拟机不用交叉编译gtk库(gtk交叉编译很复杂,我也懒得在虚拟机交叉编译了,这是为什么呀,为什么不需要呀,好懵逼呀,但是程序确实是在没有gtk库的情况下编译出来了),只需要在开发版上下载厂商提供的交叉编译好的gtk库就行了,请问我这样说对吗?
第四个问题是,如果以上说的都成立,我的程序中使用gtk库的imshow函数就可以运行,但事实是哪怕我在开发版上下载好了gtk库,程序会在那个函数卡死,提示找不到gtk库,好奇怪,请问我在哪一步推理出问题了?
大哥可以指点一下嘛?
问:程序运行时用到的库,也就是ldd命令的输出内容,是在链接时就已经决定了去哪个目录寻找吗?还是说程序运行时会动态的自己去寻找?
答:程序运行时会动态的自己去寻找,一般寻找 /lib /usr/lib 目录;
问:第一个问题是我在虚拟机上没有交叉编译gtk2.0库,但是opencv可执行程序成功编译出来了,好奇怪呀?他本身的源代码里没有 gtk 库,但是依赖于gtk库的函数确可以正常编译,为什么呢?
答:或许和环境有关系?我也不理解;
问:第四个问题是,如果以上说的都成立,我的程序中使用gtk库的imshow函数就可以运行,但事实是哪怕我在开发版上下载好了gtk库,程序会在那个函数卡死,提示找不到gtk库,好奇怪,请问我在哪一步推理出问题了?
答:要么库不在默认路径,要么库的格式不是交叉编译程序想要的;
1. 使用 file 命令查看应用和库的格式是否一致;
2. 将 gtk 库的路径添加到库的默认环境变量中,一般为 LD_LIBRARY_PATH
我好像懂了,我刚刚使用 file 命令查看了,gkt 库 和 程序格式一样,路径之前我也指定过,所以说,板子上下载的 gtk 库我程序运行不了的原因可能是我没有在虚拟机提前编译 gtk2.0 库,但是程序确奇怪的编译出来了,可以说这是一个注定运行不了的程序吗?
然后的话,关于交叉编译一个能成功运行在板子上的程序,可以这样理解吗:
交叉编译某些依赖于第三方库的程序是很困难的,首先应该下载该程序源代码,然后交叉编译源代码生成库文件,还得提前把该程序依赖的第三方库(它本身源代码里没有提供)交叉编译好放在交叉编译工具链的 lib 目录下,有了这些准备,应该就可以在虚拟机成功交叉编译一个应用程序了。
然后把可执行程序拷贝到开发板,再把可执行程序源代码交叉编译生成的库拷贝到开发板,然后再把交叉编译好的(刚刚放到交叉编译工具链的 /lib 目录下的库)可执行程序依赖的第三方库拷贝到开发板。
通过这些操作,我的程序大概率能成功运行,这样说对吗?请大哥指点一下
差不多吧,实践出真知;
感谢大哥,感谢感谢
请问你的问题解决了吗,我也遇到了一样的问题!求解谢谢
qq1816362135,其实我也不是特别懂