Я пытаюсь запустить свою первую программу на C++ в Solaris. Просто простая программа 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
настройка для поиска своих библиотек.
Если ничего не помогает, вы всегда можете запустить свои программы из скриптов оболочки, которые LD_LIBRARY_PATH
соответствующим образом устанавливают переменную окружения.
Это вкратце,
установитьLD_LIBRARY_PATH, если он не включен в
/usr/local/lib
:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ; export LD_LIBRARY_PATH
gccФайлы обычно устанавливаются в
/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 (в отличие от "lib64" в GNU/Linux) в зависимости от того, компилируете ли вы 32- или 64-битную версию соответственно. Компиляторы GCC в Solaris являются многоархитектурными.