Вопрос или проблема
У меня есть небольшой проект на C++, который компилировался нормально, пока я не обновил Xubuntu до версии 15.04. Когда я попытался его пересобрать с помощью cmake, в середине вывода появилось следующее сообщение:
/usr/bin/ld: не удается найти -lstdc++
Я решил написать простую программу, чтобы проверить, не виноват ли в этом cmake
:
int main() {
return 0;
}
Смешно, но g++
компилирует:
$ g++ main.cpp
$ ls
a.out main.cpp
$ ./a.out
$
Но когда я пытаюсь использовать clang++
…
$ clang++ main.cpp
/usr/bin/ld: не удается найти -lstdc++
clang: ошибка: команда компоновщика завершилась с кодом 1 (используйте -v для просмотра вызова)
$
Попытки с clang++ main.cpp -lc++
(как предложено здесь) или с флагом -static
(здесь) дают такую же ошибку. Запустив с -v
, как предложил сам clang
, я получаю следующее:
$ clang++ main.cpp -v
Ubuntu clang version 3.6.0-2ubuntu1 (tags/RELEASE_360/final) (основан на LLVM 3.6.0)
Цель: x86_64-pc-linux-gnu
Модель потоков: posix
Обнаружена установка GCC: /usr/bin/../lib/gcc/i686-linux-gnu/4.9
Обнаружена установка GCC: /usr/bin/../lib/gcc/i686-linux-gnu/4.9.2
Обнаружена установка GCC: /usr/bin/../lib/gcc/i686-linux-gnu/5.0.1
Обнаружена установка GCC: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.7
Обнаружена установка GCC: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.7.4
Обнаружена установка GCC: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
Обнаружена установка GCC: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9.2
Обнаружена установка GCC: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1
Обнаружена установка GCC: /usr/lib/gcc/i686-linux-gnu/4.9
Обнаружена установка GCC: /usr/lib/gcc/i686-linux-gnu/4.9.2
Обнаружена установка GCC: /usr/lib/gcc/i686-linux-gnu/5.0.1
Обнаружена установка GCC: /usr/lib/gcc/x86_64-linux-gnu/4.7
Обнаружена установка GCC: /usr/lib/gcc/x86_64-linux-gnu/4.7.4
Обнаружена установка GCC: /usr/lib/gcc/x86_64-linux-gnu/4.9
Обнаружена установка GCC: /usr/lib/gcc/x86_64-linux-gnu/4.9.2
Обнаружена установка GCC: /usr/lib/gcc/x86_64-linux-gnu/5.0.1
Выбрана установка GCC: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1
Кандидат multilib: .;@m64
Кандидат multilib: 32;@m32
Кандидат multilib: x32;@mx32
Выбрана multilib: .;@m64
"/usr/lib/llvm-3.6/bin/clang" -cc1 -triple x86_64-pc-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name main.cpp -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -target-linker-version 2.25 -v -dwarf-column-info -resource-dir /usr/lib/llvm-3.6/bin/../lib/clang/3.6.0 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/../../../../include/c++ -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/../../../../include/c++/x86_64-linux-gnu -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/../../../../include/c++/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-3.6/bin/../lib/clang/3.6.0/include -internal-externc-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -fdebug-compilation-dir /home/ryu/Dropbox/Aperture/working/C/learn-sdl/src -ferror-limit 19 -fmessage-length 100 -mstackrealign -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/main-efcd57.o -x c++ main.cpp
clang -cc1 версия 3.6.0 на основе LLVM 3.6.0, целевая система x86_64-pc-linux-gnu
игнорируя несуществующий каталог "/usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/../../../../include/c++/x86_64-linux-gnu"
игнорируя несуществующий каталог "/usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/../../../../include/c++/backward"
игнорируя несуществующий каталог "/include"
поиск заголовков "..." начинается здесь:
поиск заголовков <...> начинается здесь:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/../../../../include/c++
/usr/local/include
/usr/lib/llvm-3.6/bin/../lib/clang/3.6.0/include
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/include
/usr/include/x86_64-linux-gnu
/usr/include
Конец списка поиска.
"/usr/bin/ld" --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/../../../x86_64-linux-gnu/crt1.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/../../../x86_64-linux-gnu/crti.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/crtbegin.o -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/../../.. -L/usr/lib/llvm-3.6/bin/../lib -L/lib -L/usr/lib /tmp/main-efcd57.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/crtend.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.0.1/../../../x86_64-linux-gnu/crtn.o
/usr/bin/ld: не удается найти -lstdc++
clang: ошибка: команда компоновщика завершилась с кодом 1 (используйте -v для просмотра вызова)
$
В котором я не смог найти источник ошибки.
Я попробовал удалить и переустановить build-essential
, clang
и g++
, но безуспешно. Я также гуглил это, но нашел только эту ссылку 2013 года (да, я заметил, что это для Red Hat).
Итак, мои вопросы:
-
Как мне это исправить? (Похоже, переустановка в третий/четвертый раз решила эту проблему.)
-
Почему это произошло в первую очередь, если единственное, что я сделал, это обновление системы?
Это очень странно, но удаление пакета gcc-go
помогло мне.
Проверьте, правильно ли вы связали stdc++. Например, попробуйте собрать с помощью g++, и используйте ldd, чтобы проверить, где находится библиотека. Затем проверьте, есть ли полная иерархия связей, например (для stdc++):
lrwxrwxrwx 1 root root 40 14 фев 12:34 /usr/lib/x86_64-linux-gnu/libstdc++.so -> libstdc++.so.6
lrwxrwxrwx 1 root root 19 11 мая 02:36 /usr/lib/x86_64-linux-gnu/libstdc++.so.6 -> libstdc++.so.6.0.22
-rw-r--r-- 1 root root 1,6M 11 мая 03:05 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
В Ubuntu иногда отсутствует (возможно, у вас это не первое).
У меня нет идеи, почему это сломано (я на свежей установке Linux Mint, и получаю эту ошибку), но я сделал такой грязный фикс.
В моем .bashrc:
stdcxxpath() { if [ -n "${stdcxxpath:-}" ]; then echo "$stdcxxpath"; return; fi; stdcxxpath=$(g++ -xc++ /dev/null -Wl,--print-map 2>&1 |awk '/libstdc\+\+.so/ { print $2; exit }'|sed 's|/[^/]*$||'); stdcxxpath; }
alias clang++='clang++ -L$(stdcxxpath)' #найти, откуда libstdc++.so из gcc и использовать его
Запомненная функция оболочки stdcxxpath() находит libstdc++ и передает его компоновщику, используемому clang++
(Более простой способ: dirname $(locate '*/libstdc++.so')
тоже работает, хотя с небольшой задержкой.
Ответ или решение
После обновления Xubuntu до версии 15.04 вы столкнулись с ошибкой компиляции при использовании clang++
, которая сообщает, что не удается найти библиотеку libstdc++
. Ваша проблема может быть связана с неправильной настройкой системных путей к библиотекам или отсутствием необходимых библиотек после обновления системы. В данной статье я предложу решения вашей проблемы и постараюсь объяснить причины её возникновения.
Решение проблемы
-
Проверка наличия библиотеки
libstdc++
:
Первым делом нужно удостовериться, что библиотекаlibstdc++
установлена в системе. Вы можете использовать следующую команду для проверки:dpkg -l | grep libstdc++
Если библиотека не установлена, вы можете установить её с помощью команды:
sudo apt-get install libstdc++6
-
Проверка символических ссылок:
Убедитесь, что символические ссылки для библиотекиlibstdc++
корректно настроены. Проверьте наличие библиотеки в системе:ls -l /usr/lib/x86_64-linux-gnu/libstdc++.so*
Убедитесь, что вывод включает правильные ссылки на библиотеку, например:
/usr/lib/x86_64-linux-gnu/libstdc++.so -> libstdc++.so.6 /usr/lib/x86_64-linux-gnu/libstdc++.so.6 -> libstdc++.so.6.0.22
Если ссылка отсутствует, вы можете восстановить её с помощью:
sudo ldconfig
-
Установка libc++ (при необходимости):
Если после описанных выше шагов проблема сохраняется, попробуйте установить пакетlibc++
:sudo apt-get install libc++1 sudo apt-get install libc++abi1
-
Переменные окружения:
Иногда конфигурация окружения может вызывать проблемы с нахождением библиотек. Проверьте вашу переменную окруженияLD_LIBRARY_PATH
:echo $LD_LIBRARY_PATH
Убедитесь, что она содержит пути к библиотекам C++.
-
Использование компромиссного решения через
alias
:
Это может быть временным решением, но вы можете настроитьalias
дляclang++
, чтобы он всегда ссылался на нужный путь:Добавьте в ваш
~/.bashrc
следующее:stdcxxpath() { if [ -n "${stdcxxpath:-}" ]; then echo "$stdcxxpath"; return; fi; stdcxxpath=$(g++ -xc++ /dev/null -Wl,--print-map 2>&1 |awk '/libstdc\+\+.so/ { print $2; exit }'|sed 's|/[^/]*$||'); stdcxxpath; } alias clang++='clang++ -L$(stdcxxpath)'
После этого обновите профиль:
source ~/.bashrc
Причины возникновения проблемы
-
Обновление системы:
При обновлении системы могут возникнуть ситуации, когда определённые пакеты не обновляются должным образом, в результате чего библиотеки могут отсутствовать или их местоположение может измениться. -
Конфликтующие пакеты:
Вы упомянули, что удаление пакетаgcc-go
помогло. Иногда могут возникать конфликты между установленными пакетами, которые мешают правильной работе компилятора и его вспомогательных библиотек. -
Ошибки в конфигурации:
Порой обновление системы вносит изменения в конфигурационные файлы, что может повлиять на то, как компилятор ищет и использует библиотеки.
Заключение
Следуя данным шагам, вы сможете успешно разрешить проблему с нахождением libstdc++
при использовании clang++
. Если ни одно из предложенных решений не помогло, рекомендуется проверить форумы сообщества или задать вопрос на специализированных ресурсах, таких как Stack Overflow.