boost库链接问题

编译打包和其他
回复
CoderWkm
帖子: 8
注册时间: 2023-09-12 11:37
系统: Ubuntu20.04

boost库链接问题

#1

帖子 CoderWkm » 2023-10-26 15:24

环境:Ubuntu20.04;

某个cpp项目,执行该可执行程序是情况如下所示:运行时链接的boost_filesystem库的位数不对
图片

该项目的可执行文件是在旧系统fedora17上编译生成的32位程序。可执行文件的链接等情况如下:
图片
图片

可以看出是boost库的filesystem、regex、system没有找到。我查看自己环境下的对应的动态库文件,都是1.71.0版本的。所以到boost官网找到源码下载并且编译,但是出现一些问题:

1. 编译boost库的过程中,执行./b2,会跳过regex的相关内容:
图片

2. 结果却是是filesystem、system的1.48.0版本已经存在,regex的so还没有,如下图所示。尽管regex编译出错,但是为什么filesystem、system还是没找到动态链接库?
图片


我看etc下的配置文件信息如下:
图片



1. 请问我该是哪个库的加载路径不对吗?
2. 还有就是关于boost库的编译为什么会出现这种跳过regex的问题?如果实在不行只能把这个项目重新make。


提前感谢大佬的回复!! :Adore
头像
astolia
论坛版主
帖子: 6478
注册时间: 2008-09-18 13:11

Re: boost库链接问题

#2

帖子 astolia » 2023-10-27 10:16

CoderWkm 写了: 2023-10-26 15:24 1. 请问我该是哪个库的加载路径不对吗?
你没搞交叉编译吧,编译出的库还是64位的,32位的程序当然用不了

CoderWkm 写了: 2023-10-26 15:24 2. 还有就是关于boost库的编译为什么会出现这种跳过regex的问题?如果实在不行只能把这个项目重新make。
编译时不是报了错吗?权限不足,mkdir失败,你该去检查为什么创建不了那个bin.v2/libs目录
CoderWkm
帖子: 8
注册时间: 2023-09-12 11:37
系统: Ubuntu20.04

Re: boost库链接问题

#3

帖子 CoderWkm » 2023-10-27 11:31

astolia 写了: 2023-10-27 10:16
CoderWkm 写了: 2023-10-26 15:24 1. 请问我该是哪个库的加载路径不对吗?
你没搞交叉编译吧,编译出的库还是64位的,32位的程序当然用不了

CoderWkm 写了: 2023-10-26 15:24 2. 还有就是关于boost库的编译为什么会出现这种跳过regex的问题?如果实在不行只能把这个项目重新make。
编译时不是报了错吗?权限不足,mkdir失败,你该去检查为什么创建不了那个bin.v2/libs目录
抱歉我确实不了解交叉编译,请问这方面知识怎么快速入门呢,确实比较着急。另外就是ldd显示的not found的意思是没找到32位,即使有64位的1.48库文件也是显示not found?
头像
astolia
论坛版主
帖子: 6478
注册时间: 2008-09-18 13:11

Re: boost库链接问题

#4

帖子 astolia » 2023-10-27 13:30

CoderWkm 写了: 2023-10-27 11:31 抱歉我确实不了解交叉编译,请问这方面知识怎么快速入门呢,确实比较着急
交叉编译说白了就是通过设置一些参数,让编译系统去调用特定的编译器并加上特定编译参数去编译出针对目标平台的代码,而非用默认的gcc和默认参数编译出针对当前平台的代码。你这种x86_64去编译x86的代码算是最简单的一种了
不同项目用不同的编译系统,搞交叉编译的方式也有所不同。libboost库可以去看它的官方文档 https://www.boost.org/build/doc/html/bb ... mpile.html
按你这次的需求,在编译用户的家目录里放一个user-config.jam文件,内容如下即可

代码: 全选

using gcc : : : <compileflags>-m32 <linkflags>-m32 ;
这样再执行./b2,它就会用gcc编译出32位的代码了。
但要注意的是,相关的依赖库(比如ICU)的开发包也需要安装32位的才行。就是像sudo apt install libicu-dev:i386这样

CoderWkm 写了: 2023-10-27 11:31 另外就是ldd显示的not found的意思是没找到32位,即使有64位的1.48库文件也是显示not found?
ldd又不是光看文件名是不是相同。它看的是程序执行时加载的库,加载不了的就不算。ldd本质是个shell脚本,你可以用文本编辑器打开看它的运行原理的。
CoderWkm
帖子: 8
注册时间: 2023-09-12 11:37
系统: Ubuntu20.04

Re: boost库链接问题

#5

帖子 CoderWkm » 2023-10-30 11:57

astolia 写了: 2023-10-27 13:30
CoderWkm 写了: 2023-10-27 11:31 抱歉我确实不了解交叉编译,请问这方面知识怎么快速入门呢,确实比较着急
交叉编译说白了就是通过设置一些参数,让编译系统去调用特定的编译器并加上特定编译参数去编译出针对目标平台的代码,而非用默认的gcc和默认参数编译出针对当前平台的代码。你这种x86_64去编译x86的代码算是最简单的一种了
不同项目用不同的编译系统,搞交叉编译的方式也有所不同。libboost库可以去看它的官方文档 https://www.boost.org/build/doc/html/bb ... mpile.html
按你这次的需求,在编译用户的家目录里放一个user-config.jam文件,内容如下即可

代码: 全选

using gcc : : : <compileflags>-m32 <linkflags>-m32 ;
这样再执行./b2,它就会用gcc编译出32位的代码了。
但要注意的是,相关的依赖库(比如ICU)的开发包也需要安装32位的才行。就是像sudo apt install libicu-dev:i386这样

CoderWkm 写了: 2023-10-27 11:31 另外就是ldd显示的not found的意思是没找到32位,即使有64位的1.48库文件也是显示not found?
ldd又不是光看文件名是不是相同。它看的是程序执行时加载的库,加载不了的就不算。ldd本质是个shell脚本,你可以用文本编辑器打开看它的运行原理的。
感谢您关于交叉编译和ldd的解答!
我还有最后两个问题,就是在ubuntu中make这个项目的时候,ld提醒找不到regex库文件,如下:
图片

我已经把对应的32位regex库的文件放在的ld搜索的默认路径/usr/lib/x86_644-linux-gnu下。尽管截图中显示的makefile指定的-L参数是旧环境的路径。但是我觉得应该还是能找到,看了部分博客感觉说的ld搜索顺序比较简略,希望您能解答一下该问题。

最后一个就是,关于这种linux下C/C++的编译环境问题,您有没有什么好的学习建议?别人之前推荐我学习一下docker,希望前辈不吝赐教!
头像
astolia
论坛版主
帖子: 6478
注册时间: 2008-09-18 13:11

Re: boost库链接问题

#6

帖子 astolia » 2023-10-30 15:48

CoderWkm 写了: 2023-10-30 11:57 我已经把对应的32位regex库的文件放在的ld搜索的默认路径/usr/lib/x86_644-linux-gnu下
你用make时,传递给cc的参数没有包含-m32,是在编译针对当前平台的64位程序,你给个32位的库是没用的。

另外,你传递-labc这种参数给gcc时,gcc会依次去寻找1)当前目录下名为-labc的文件,2)各库文件目录下名为libabc.so的文件,3)各库文件目录下名为abc.a的文件。所以你要复制的话,不能光复制带版本号的libabc.so.1.2.0,要么你把它更名为libabc.so,要么建立个软链接libabc.so指向它。

还有啊,我看你都在从源码重新编译了,那干嘛不干脆编译出一个依赖boost 1.71的64位程序呢?你开头就来编译boost,我还以为没源码只剩个可执行文件了
CoderWkm 写了: 2023-10-30 11:57 最后一个就是,关于这种linux下C/C++的编译环境问题,您有没有什么好的学习建议?别人之前推荐我学习一下docker,希望前辈不吝赐教!
我的建议是去查官方文档。流行的项目在这方面的文档一般都做得不错。对那些没提供文档的,记住一些最基本的概念及相关的专业英文词汇,到google上用英文搜一下。就那你这个boost的例子来说,我看到你的帖子,就猜到应该是交叉编译的问题。然后下了个boost的代码,看到它用的编译构建系统我不认识,然后上google搜boost cross compile就搜到了那篇官方文档,然后从文档里找到了配置方法。

docker这种容器化方案,解决的是部署环境一致性的问题。你这种在旧系统上可以运行,在新系统上缺这缺那也算是部署环境不一致导致的。但docker和其他一些容器化技术主要是针对服务,一般的应用程序可以用ubuntu家力推的snap、redhat推的flatpak、或者appimage。
反正这些技术的核心思想说白了就是把可执行程序和它所有依赖的东西带在一起,这样就不会缺了。不用这些花里胡哨的,自己手动把相关依赖带上也是一样的。至于上面那些提供的沙盒化功能,一般应用也不怎么需要。新人的话,最好先把这些基础的原理性的东西搞清楚,再看这些技术也没啥神秘的了
CoderWkm
帖子: 8
注册时间: 2023-09-12 11:37
系统: Ubuntu20.04

Re: boost库链接问题

#7

帖子 CoderWkm » 2023-10-30 17:11

还有啊,我看你都在从源码重新编译了,那干嘛不干脆编译出一个依赖boost 1.71的64位程序呢?你开头就来编译boost,我还以为没源码只剩个可执行文件了
因为进度的原因,一开始想着缺库文件就补,让可执行文件运行就好了。而且这个项目时间久远,先于C++11,我担心新编译器不兼容一些旧特性,同时也是没有技术文档(make本身写的也有问题,自定义变量结尾总是多出来多余的$),就不太敢动源码。

但是勉强补齐1.48的旧32位链接库,可执行文件报错:segmentation fault。就感觉是源码有问题,所以想重新编译。
:Cry
————————————————————————————————————————————————————————————————————————————————————————
中午在等待回复的,我通过ubuntu软件源又下了个libboost-all-dev,再make就报编译错误(虽然已经通过apt-get purge libboost-all):
图片
这下真的是不面对源码都不行了 :Cry
头像
astolia
论坛版主
帖子: 6478
注册时间: 2008-09-18 13:11

Re: boost库链接问题

#8

帖子 astolia » 2023-10-31 12:51

CoderWkm 写了: 2023-10-30 17:11 中午在等待回复的,我通过ubuntu软件源又下了个libboost-all-dev,再make就报编译错误(虽然已经通过apt-get purge libboost-all):
图片
这下真的是不面对源码都不行了 :Cry
你不会连最基本的软件包安装删除的知识都不清楚吧。
apt install abc会安装abc和它依赖的软件包,而apt purge abc只会删除abc和依赖abc的包,abc依赖的包是不会动的。要删除顺带安装上的依赖包,要加--auto-remove参数,或者用apt autoremove abc --purge。

另外你那些-fpermissive的错改起来也很简单啊,把默认参数放到函数申明里而非定义里就行了
就是把

代码: 全选

template <typename T> T inc(T x);
...
template <typename T> T inc(T x=0) { return x + 1; }
改成

代码: 全选

template <typename T> T inc(T x=0);
...
template <typename T> T inc(T x) { return x + 1; }
这样。话说回来,把默认参数放定义里,纯粹是c++没学好
CoderWkm
帖子: 8
注册时间: 2023-09-12 11:37
系统: Ubuntu20.04

Re: boost库链接问题

#9

帖子 CoderWkm » 2023-11-01 0:52

astolia 写了: 2023-10-31 12:51
CoderWkm 写了: 2023-10-30 17:11 中午在等待回复的,我通过ubuntu软件源又下了个libboost-all-dev,再make就报编译错误(虽然已经通过apt-get purge libboost-all):
图片
这下真的是不面对源码都不行了 :Cry
你不会连最基本的软件包安装删除的知识都不清楚吧。
apt install abc会安装abc和它依赖的软件包,而apt purge abc只会删除abc和依赖abc的包,abc依赖的包是不会动的。要删除顺带安装上的依赖包,要加--auto-remove参数,或者用apt autoremove abc --purge。

另外你那些-fpermissive的错改起来也很简单啊,把默认参数放到函数申明里而非定义里就行了
就是把

代码: 全选

template <typename T> T inc(T x);
...
template <typename T> T inc(T x=0) { return x + 1; }
改成

代码: 全选

template <typename T> T inc(T x=0);
...
template <typename T> T inc(T x) { return x + 1; }
这样。话说回来,把默认参数放定义里,纯粹是c++没学好
抱歉,我不是c++没学好,是压根就没学过面向对象类的语言,只有c的基础 :Cry ,现在正在看c++ primer;
之前对于linux只看过《鸟叔》,对Ubuntu不是很了解,一直是需要什么就man,感觉知识不成体系,效率也挺低的 :Cry
回复