Clang++ не может найти lstdc++ после обновления системы

Вопрос или проблема

У меня есть небольшой проект на 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).

Итак, мои вопросы:

  1. Как мне это исправить? (Похоже, переустановка в третий/четвертый раз решила эту проблему.)

  2. Почему это произошло в первую очередь, если единственное, что я сделал, это обновление системы?

Это очень странно, но удаление пакета 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++. Ваша проблема может быть связана с неправильной настройкой системных путей к библиотекам или отсутствием необходимых библиотек после обновления системы. В данной статье я предложу решения вашей проблемы и постараюсь объяснить причины её возникновения.

Решение проблемы

  1. Проверка наличия библиотеки libstdc++:
    Первым делом нужно удостовериться, что библиотека libstdc++ установлена в системе. Вы можете использовать следующую команду для проверки:

    dpkg -l | grep libstdc++

    Если библиотека не установлена, вы можете установить её с помощью команды:

    sudo apt-get install libstdc++6
  2. Проверка символических ссылок:
    Убедитесь, что символические ссылки для библиотеки 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
  3. Установка libc++ (при необходимости):
    Если после описанных выше шагов проблема сохраняется, попробуйте установить пакет libc++:

    sudo apt-get install libc++1
    sudo apt-get install libc++abi1
  4. Переменные окружения:
    Иногда конфигурация окружения может вызывать проблемы с нахождением библиотек. Проверьте вашу переменную окружения LD_LIBRARY_PATH:

    echo $LD_LIBRARY_PATH

    Убедитесь, что она содержит пути к библиотекам C++.

  5. Использование компромиссного решения через 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

Причины возникновения проблемы

  1. Обновление системы:
    При обновлении системы могут возникнуть ситуации, когда определённые пакеты не обновляются должным образом, в результате чего библиотеки могут отсутствовать или их местоположение может измениться.

  2. Конфликтующие пакеты:
    Вы упомянули, что удаление пакета gcc-go помогло. Иногда могут возникать конфликты между установленными пакетами, которые мешают правильной работе компилятора и его вспомогательных библиотек.

  3. Ошибки в конфигурации:
    Порой обновление системы вносит изменения в конфигурационные файлы, что может повлиять на то, как компилятор ищет и использует библиотеки.

Заключение

Следуя данным шагам, вы сможете успешно разрешить проблему с нахождением libstdc++ при использовании clang++. Если ни одно из предложенных решений не помогло, рекомендуется проверить форумы сообщества или задать вопрос на специализированных ресурсах, таких как Stack Overflow.

Оцените материал
Добавить комментарий

Капча загружается...