问题背景
我在Ubuntu20.04中安装了2019版本的Vitis和Vivado,然后想看BSP提供了外设文档,这些文档都是html格式的文件,按理说点一下就会有浏览器打开文档,但结果没有文档出现,像是卡住了。
原因分析
多点几下之后可以在打开Vitis的命令行窗口里看到这样的报错信息:
应该是libstdc++.so.6的版本不够,里面缺少GLIBCXX_3.4.26。而且这里有一个很奇怪的地方,就是这个libstdc++.so.6不是在/usr/lib目录下被找到的,而是在Vitis的安装目录下被找到的,我猜是找错了文件,实际要用的文件应该在系统目录下。可能这也反映了2019版本的Vivado或Vitis并不完全适合装在20.04版本的Ubuntu系统里。
找一下系统里这个动态链接库实际的位置:
whereis libstdc++.so.6
然后再想办法看看两个动态链接库有什么不同。动态链接库在编译的时候通常会包含一些字符串常量来记录版本号,可以用strings命令查看,比如GLIBCXX_3.4.26就是一个版本号。
- 查看Vitis安装目录下的libstdc++.so.6:
strings /tools/Xilinx/Vitis/2019.2/lib/lnx64.o/Ubuntu/libstdc++.so.6 | grep ^GLIBCXX
- 查看/usr/lib目录下的libstdc++.so.6:
strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep ^GLIBCXX
可以看到确实/usr/lib目录下是有它所需的版本号的,而Vitis安装目录下没有这个版本号。目前大概找到了问题,但还有一个问题是要搞清楚为什么会找错文件。在此之前首先要清楚Linux环境下动态链接库的搜索顺序。
动态链接库搜索顺序
- 程序自身指定的相对路径或者程序运行的目录。这个一般不会出现问题,程序安装的时候依赖的一些动态库也随着安装,相对位置是确定的,不会出现找错的情况。
- 环境变量LD_LIBRARY_PATH指定的路径。
- /etc/ld.so.conf文件中的设置
- 默认路径/lib和/usr/lib
搜索路径的设置
我在~/.bashrc中加入了添加Vivado和Vitis运行环境初始化的脚本:
source /tools/Xilinx/Vivado/2019.2/settings64.sh
这个脚本虽然是在Vivado目录下,但是它不光初始化Vivado的环境,而且也会一同初始化Vitis的环境。而在Vitis的环境设置里,就有对LD_LIBRARY_PATH的修改。
而/usr/lib目录下的那个libstdc++.so.6是在/etc/ld.so.conf文件中设置的。
查看LD_LIBRARY_PATH环境变量,它包含的路径里就有libstdc++.so.6,而且它又是较早被搜索的,所以这里的动态库就被拿去用了。
echo $LD_LIBRARY_PATH | tr : '\n'
问题解决
/usr/lib目录下的libstdc++.so.6版本更高一些,可以加一个软件链接把较低版本的库替换为较高版本的。这么做不知道会不会有什么副作用,但是确实能够解决我目前firfox打不开html文档的问题。
先做一个备份:
sudo mv libstdc++.so.6 libstdc++.so.6.bak
再添加新的软链接:
sudo ln -s /usr/lib/x86_64-linux-gnu/libstdc++.so.6 libstdc++.so.6
然后就可以用firefox正常打开文档了。