Связывание g++ 4.8 с libstdC++

Я скачал и собрал gcc 4.8.1 на своем рабочем столе под управлением 64-битной Ubuntu 12.04. Я создал его из исходного кода, как рекомендуют документы, и с помощью команд

../../gcc-4.8.1/configure --prefix=$HOME --program-suffix=-4.8
make
make -k check
make install

Казалось, что все тесты пройдены, и я установил все в свой домашний каталог с суффиксом -4.8, чтобы отличить его от системы gcc, которая является версией 4.6.3.

К сожалению, когда я компилирую программы на C++ с использованием g ++ - 4.8, он ссылается на системные libc и libstdC++, а не на новые, скомпилированные из gcc-4.8.1. Я скачал и собрал gcc 4.8, потому что хотел поэкспериментировать с новыми функциями C++11 в стандартной библиотеке, поэтому такое поведение определенно не то, что я хотел. Что я могу сделать, чтобы gcc-4.8 автоматически связывался со стандартными библиотеками, которые поставлялись вместе с ним, а не со стандартными библиотеками системы?

3 ответа

Решение

Когда вы связываете с вашим собственным GCC, вам нужно добавить дополнительные пути поиска компоновщика во время выполнения с -Wl,-rpath,$(PREFIX)/lib64 так что во время выполнения он находит разделяемые библиотеки, соответствующие вашему gcc.

Я обычно создаю оболочку с именем gcc а также g++ в том же каталоге, что и gcc-4.8 а также g++-4.8 который я призываю вместо gcc-4.8 а также g++-4.8, как предписано в динамическом компоновщике не удается найти библиотеки GCC:

#!/bin/bash
exec ${0}SUFFIX -Wl,-rpath,PREFIX/lib64 "$@"

При установке SUFFIX а также PREFIX следует заменить на то, что было передано configure:

cd ${PREFIX}/bin && rm -f gcc g++ c++ gfortran
sed -e 's#PREFIX#${PREFIX}#g' -e 's#SUFFIX#${SUFFIX}#g' gcc-wrapper.sh > ${PREFIX}/bin/gcc
chmod +x ${PREFIX}/bin/gcc
cd ${PREFIX}/bin && ln gcc g++ && ln gcc c++ && ln gcc gfortran

(gcc-wrapper.sh это тот фрагмент bash)


Приведенное выше решение не работает с некоторыми версиями libtool так как g++ -Wl,... -v предполагает режим связывания и завершается с ошибкой.

Лучшее решение - использовать файл спецификаций. Как только gcc/g++ собран, вызовите следующую команду, чтобы добавить gcc/g++ -rpath в командной строке компоновщика (заменить ${PREFIX}/lib64 как необходимо):

g++ -dumpspecs | awk '/^\*link:/ { print; getline; print "-rpath=${PREFIX}/lib64", $0; next } { print }' > $(dirname $(g++ -print-libgcc-file-name))/specs

У меня просто была такая же проблема при сборке gcc-4.8.2. У меня нет root-доступа на этом компьютере, поэтому мне нужно установить его в свой домашний каталог. Потребовалось несколько попыток, прежде чем я понял магию, необходимую для того, чтобы заставить это работать, поэтому я воспроизведу это здесь, чтобы другим людям было легче. Это команды, которые я использовал для настройки gcc:

prefix=/user/grc/packages

export LDFLAGS=-Wl,-rpath,$prefix/lib
export LD_RUN_PATH=$prefix/lib
export LD_LIBRARY_PATH=$prefix/lib

../../src/gmp-4.3.2/configure  --prefix=$prefix
../../src/mpfr-2.4.2/configure --prefix=$prefix
../../src/mpc-0.8.1/configure  --prefix=$prefix --with-mpfr=$prefix --with-gmp=$prefix
../../src/gcc-4.8.2/configure  --prefix=$prefix --with-mpfr=$prefix --with-gmp=$prefix --with-mpc=$prefix --enable-languages=c,c++

Это дало мне работающий двоичный файл, но любая программа, которую я собрал с этой версией g++, не будет работать правильно, если я не соберу ее с опцией -Wl,-rpath,$prefix/lib64. Можно заставить g++ автоматически добавить эту опцию, предоставив файл спецификации. Если вы бежите

strace g++ 2>&1 | grep specs

Вы можете увидеть, какие каталоги он проверяет для спецификации файла. В моем случае это был $prefix/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/specs, поэтому я запустил g++ -dumpspecs для создания нового файла specs:

cd $prefix/lib/gcc/x86_64-unknown-linux-gnu/4.8.2
$prefix/bin/g++ -dumpspecs > xx
mv xx specs

а затем отредактировал этот файл для предоставления опции -rpath. Ищите строки как это:

*link_libgcc:
%D

и отредактируйте, чтобы добавить опцию rpath:

*link_libgcc:
%D -rpath /user/grc/packages/lib/%M

%M расширяется до../lib или../lib64 в зависимости от того, собираете ли вы 32-битный или 64-битный исполняемый файл.

Обратите внимание, что когда я попробовал этот же трюк на более старой сборке gcc-4.7, он не работал, потому что он не расширил%M. Для более старых версий вы можете удалить%M и просто жестко кодировать lib или lib64, но это жизнеспособное решение, если вы когда-либо собираете только 32-битные исполняемые файлы (с lib) или только когда-либо собираете 64-битные исполняемые файлы (с lib64).

gcc -print-search-dirs скажет вам, где ваш компилятор ищет библиотеки времени выполнения и т. д. Вы можете переопределить это с помощью -B<prefix> вариант.

Другие вопросы по тегам