首先是关于我自己的一些背景:我不是C / C ++开发人员,尽管我在很久以前就学到了很多关于C和系统编程的知识。我的主要职业是Unix管理员(倾向于Solaris),我正在努力帮助一些内部开发人员将他们的开发环境从Solaris 8迁移到Solaris 10。
到目前为止,他们曾经在Solaris 8上开发应用程序。但是最近最后一台Solaris 8开发机器已经关闭,但当然没有人费心去测试是否所有应用程序在Solaris 10中都可以像在Solaris 8中那样进行编译。
现在我们有一个非常具体的应用程序,必须用gcc 3.2.1编译 - 我已经设法让开发人员能够编译,但是,编译的二进制文件不会在生产环境中运行 - 它在但是,开发环境。
生产系统中已编译二进制文件失败的原因是缺少某些库:
./myapp
ld.so.1: myapp: fatal: libstdc++.so.5: open failed: No such file or directory
Killed
现在奇怪的是,当在Solaris 8中构建二进制文件时,这个库(和libgcc_s.so.1也没有链接) - 这里是用于比较的ldd的两个输出,首先是新的在Solaris 10上构建(请注意两行“未找到文件”):
ldd myapp
librt.so.1 => /lib/64/librt.so.1
libpthread.so.1 => /lib/64/libpthread.so.1
libstdc++.so.5 => (file not found)
libm.so.2 => /lib/64/libm.so.2
libgcc_s.so.1 => (file not found)
libc.so.1 => /lib/64/libc.so.1
libaio.so.1 => /lib/64/libaio.so.1
libmd.so.1 => /lib/64/libmd.so.1
/platform/SUNW,Netra-T12/lib/sparcv9/libc_psr.so.1
/platform/SUNW,Netra-T12/lib/sparcv9/libmd_psr.so.1
现在仍然是在“真正的”Solaris 8环境中编译的旧二进制文件:
ldd myapp
libm.so.1 => /lib/64/libm.so.1
librt.so.1 => /lib/64/librt.so.1
libpthread.so.1 => /lib/64/libpthread.so.1
libc.so.1 => /lib/64/libc.so.1
libaio.so.1 => /lib/64/libaio.so.1
libmd.so.1 => /lib/64/libmd.so.1
libm.so.2 => /lib/64/libm.so.2
/platform/SUNW,Netra-T12/lib/sparcv9/libc_psr.so.1
/platform/SUNW,Netra-T12/lib/sparcv9/libmd_psr.so.1
我所知道的唯一区别(除了完全不同的操作系统环境)是他们以前在Solaris 8中使用的gcc调用在Solaris 10中不起作用。当尝试编译一个非常简单的C ++程序时,我们遇到了很多错误(示例代码广泛用于网络中的多个变体):
$ cat easy.cpp
#include <iostream>
int main()
{
std::cout << "Welcome to the wonderful world of C++!!!\n";
return 0;
}
使用“gcc”作为命令的结果(gcc32实际上是我们环境中gcc的链接,因为g ++ 32链接到g ++(使用适当的版本3.2.1)):
$ gcc32 -m64 -o easy easy.cpp
/var/tmp//ccWzG0Lj.o: In function `main':
/var/tmp//ccWzG0Lj.o(.text+0x4): undefined reference to `std::cout'
/var/tmp//ccWzG0Lj.o(.text+0x8): undefined reference to `std::cout'
/var/tmp//ccWzG0Lj.o(.text+0xc): undefined reference to `std::cout'
/var/tmp//ccWzG0Lj.o(.text+0x18): undefined reference to `std::cout'
/var/tmp//ccWzG0Lj.o(.text+0x34): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
/var/tmp//ccWzG0Lj.o: In function `__static_initialization_and_destruction_0(int, int)':
/var/tmp//ccWzG0Lj.o(.text+0xa4): undefined reference to `std::ios_base::Init::Init[in-charge]()'
/var/tmp//ccWzG0Lj.o(.text+0xec): undefined reference to `std::ios_base::Init::~Init [in-charge]()'
/var/tmp//ccWzG0Lj.o(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status
当我直接调用g ++时,程序只用一个警告编译:
$ g++32 -m64 -o easy easy.cpp
/home/user/tools/bin/ld: warning: libm.so.1, needed by /home/user/tools/gcc32/lib/gcc-lib/sparc-sun-solaris2.8/3.2.1/../../../sparcv9/libstdc++.so, may conflict with libm.so.2
当我尝试运行它时,我首先遇到了缺少的libstdc ++。so.5库,但是在开发机器上,LD_LIBRARY_PATH的调整解决了这个问题。
但是:目标生产机器没有安装libstdc ++。so.5(它们有版本6),虽然可能可以安装额外的gcclib软件包但问题仍然存在:为什么呢用g ++链接到这两个额外库的调用,而用gcc调用则没有 - 或者,改写:如何编译二进制文件以便它不需要额外的库,因为它之前不需要它们,当它是在Solaris 8中编译的吗?
非常感谢您的耐心等待(这已经成为一个很长的文字),任何提示都是最受欢迎的。
亲切的问候,
的Henning