Прежде всего, немного истории о себе: я не разработчик 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
Теперь странно то, что эта библиотека (и libgcc_s.so.1, тоже) не были связаны, когда двоичный файл был собран в Solaris 8 — вот два вывода 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
Единственное различие, которое я знаю (за исключением совершенно другой среды ОС), заключается в том, что вызов gcc, который они использовали в Solaris 8, не работал в 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
Задача ещё не решена.
Других решений пока нет …