我正在尝试在 Solaris 上运行我的第一个 C++ 程序。只是一个简单的 Hello World 程序。当我尝试跑步时。我得到了错误libstdc++.so.6:open failed:No such file or directory
。当然,我做了一些谷歌搜索,发现可以通过设置环境变量来解决这个问题:
export LD_LIBRARY_PATH=/usr/local/lib
重新登录后发现这并不是一劳永逸的解决办法。我猜这与编译期间链接 libstdc++.so.6 有关。这是我从一开始就执行的步骤:
bash-3.2# gcc -c test.cpp
bash-3.2# gcc -o test test.o -lstdc++
bash-3.2# ./test
libstdc++.so.6:open failed:No such file or directory
bash-3.2# ldd test | grep not
libstdc++.so.6 => (file not found)
bash-3.2# /usr/ccs/bin/elfdump test | grep RUNPA
bash-3.2# find /usr -name libstdc++.so.6
/usr/local/lib/libstdc++.so.6
我在编译过程中错过了标志或其他东西吗?如何创建软链接以便它知道在运行该程序时在哪里查找?
这是我正在使用的平台:
bash-3.2# uname -a
SunOS ms-sparc8 5.8 Generic_108528-13 sun4u sparc SUNW,Sun-Blade-100
bash-3.2# gcc -v
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/3.3.2/specs
Configured with: ../configure --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld --disable-nls --disable-libgcj --enable-languages=c,c++
Thread model: posix
gcc version 3.3.2
答案1
设置 Solaris 运行时链接器搜索路径的最简单方法是使用crle
,但这样做时需要非常小心,因为如果破坏系统,很容易使系统无法使用!添加/usr/local/bin
到链接器路径:
# crle -u -l /usr/local/lib
完成此操作后,请crle
自行调用以验证新的搜索路径。
另一种方法是将路径编译到二进制文件本身中:
$ gcc -Wl,-rpath,/usr/local/lib -o test test.o -lstdc++
上面是一个更好的选择,因为二进制文件可以在其他系统上工作,而无需调整链接器路径。
答案2
问题是索拉里斯加载器找不到该库。
最好的办法是LD_RUN_PATH
在编译期间将环境变量设置为所在目录libstdc++.so.xxxx(你的版本号)还活着。这告诉链接器在运行时搜索该目录。
请注意,
LD_RUN_PATH
不要与 混淆LD_LIBRARY_PATH
。后者在运行时进行解析,而LD_RUN_PATH
本质上是在库路径中编译为可执行文件,因此不需要设置LD_LIBRARY_PATH
来查找其库。
如果所有其他方法都失败,您始终可以从适当设置环境变量的包装器 shell 脚本运行程序LD_LIBRARY_PATH
。
这是一个要点,
设置LD_LIBRARY_PATH,如果它不包含在内
/usr/local/lib
:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ; export LD_LIBRARY_PATH
海湾合作委员会文件通常安装到
/usr/lib/gcc/
.
然后将 libstdc++.so.6 从安装目录链接到/usr/lib
或/usr/local/lib
使用软链接
sudo ln -s libstdc++.so.6 /usr/lib/<filename>
答案3
首先,没有必要使用 crle (除非你真的明白你在做什么,否则远离它;相信我,当你使用错误时,你会因为疯狂的运行时错误而把自己锁在外面)
其次,不需要设置 LD_LIBRARY_PATH(大多数情况下),也不需要在 /usr 中符号链接任何第三方库
只需按照 mjturner 的建议进行操作并在编译时为 gcc 提供正确的运行时路径即可
PS:C++代码应该用g++编译
链接:
http://notes.theorbis.net/2010/01/how-to-screw-up-solaris-with-crle.html http://prefetch.net/articles/linkers.badldlibrary.html
答案4
如果您使用 g++ 前端,它将知道如何正确链接 C++ 代码与 libstdc++ 库。对于 Solaris 来说尤其如此。
无论您做什么,在任何情况下都不要使用 LD_RUN_PATH 或 LD_LIBRARY_PATH,因为这些变量旨在供共享对象库开发人员帮助调试,而不是用于最终链接。使用这些将插入来自不同版本的共享对象库的符号,并可能导致难以调试的潜在崩溃,因为由于上述插入,人们将不知道运行时正在使用哪些符号。
始终通过 g++ 前端链接。如果您需要将其他 RPATH 信息传递给链接编辑器,正确的做法是 g++ -Wl,-R/path/to/lib 或 g++ -m64 -Wl,-R/path/to/lib/64 (与 GNU/Linux 上的“lib64”不同),具体取决于编译的是 32 位还是 64 位。 Solaris 上的 GCC 编译器是多架构的。