8.29.1. Установка пакета GCC
        
        
          При сборке на x86_64 измените имя каталога по умолчанию для
          64-битных библиотек на «lib»:
        
        
          Измените имя каталога по умолчанию для 64-битных библиотек на
          «lib»:
        
        sed -e '/m64=/s/lib64/lib/' \
    -e '/m32=/s/m32=.*/m32=..\/lib32$(call if_multiarch,:i386-linux-gnu)/' \
    -i.orig gcc/config/i386/t-linux64
        
          Документация GCC рекомендует собирать GCC в отдельном каталоге:
        
        mkdir -v build
cd       build
        
          Подготовьте GCC к компиляции:
        
        mlist=m64,m32
../configure --prefix=/usr               \
             LD=ld                       \
             --enable-languages=c,c++    \
             --enable-default-pie        \
             --enable-default-ssp        \
             --enable-multilib           \
             --with-multilib-list=$mlist \
             --disable-bootstrap         \
             --disable-fixincludes       \
             --with-system-zlib
        
          GCC поддерживает семь различных языков программирования, но
          предварительные условия для большинства из них еще не выполнены.
          См. страницу 
          BLFS Book GCC для получения инструкций о том, как собрать все
          языки, поддерживаемые GCC
        
        
          
            Значение новых параметров настройки:
          
          
            - 
              LD=ld
- 
              
                Этот параметр указывает скрипту configure использовать ld,
                установленный программой Binutils, собранной ранее в этой
                главе, а не кросс версию, которая использовалась бы в
                противном случае.
               
- 
              --disable-fixincludes
- 
              
                По умолчанию во время установки GCC некоторые системные
                заголовки будут «исправлены» для использования с GCC.
                Это не обязательно для современной системы Linux и
                потенциально опасно, если пакет будет переустановлен после
                установки GCC. Этот параметр не позволяет GCC «исправлять»
                заголовки.
               
- 
              --with-system-zlib
- 
              
                Этот параметр указывает GCC ссылаться на установленную в
                системе копию библиотеки Zlib, а не на собственную внутреннюю
                копию.
               
 
        
          ![[Примечание]](../images/note.png) 
          
            Примечание
          
          
            PIE (позиционно-независимые исполняемые файлы) — это двоичные
            программы, которые можно загружать в любое место памяти. Без PIE
            функция безопасности под названием ASLR (рандомизация размещения
            адресного пространства) может применяться к общим библиотекам, но
            не к самим исполняемым файлам. Включение PIE позволяет
            использовать ASLR для исполняемых файлов в дополнение к общим
            библиотекам и смягчает некоторые атаки, основанные на
            фиксированных адресах конфиденциального кода или данных в
            исполняемых файлах.
          
          
            SSP (Stack Smashing Protection - защита от разрушения стека) —
            это метод, гарантирующий, что стек параметров не будет поврежден.
            Повреждение стека может, например, изменить адрес возврата
            подпрограммы, тем самым передав управление какому-то опасному
            коду (существующему в программе или общих библиотеках или
            каким-то образом внедренному злоумышленником).
          
         
        
          Скомпилируйте пакет:
        
        make
        
          ![[Важно]](../images/important.png) 
          
            Важно
          
          
            В этом разделе набор тестов для GCC считается важным, но занимает
            много времени. Начинающим сборщикам не рекомендуется пропускать
            его. Время выполнения тестов можно значительно сократить, добавив
            -jx в приведенную ниже команду make
            -k check, где x - количество ядер процессора в
            вашей системе.
          
         
        
          Известно, что один набор тестов GCC переполняет стек по умолчанию,
          поэтому увеличьте размер стека перед запуском тестов:
        
        ulimit -s 32768
        
          Выполните тестирование под непривилегированным пользователем, но не
          останавливайтесь на ошибках:
        
        chown -R tester .
su tester -c "PATH=$PATH make -k check"
        
          Чтобы получить сводку результатов набора тестов, выполните:
        
        ../contrib/test_summary
        
          Чтобы отфильтровать только итоговую сводку, передайте вывод через
          pipe grep -A7 Summ.
        
        
          Результаты можно сравнить с результатами, размещенными на https://mirror.linuxfromscratch.ru/lfs/build-logs/12.1/
          и https://gcc.gnu.org/ml/gcc-testresults/.
        
        
          Известно, что восемь тестов gcc (из более чем 185 000):
          pr56837.c и семь тестов из каталога
          analyzer завершились неудачно. Также
          провалился один тест libstdc++ (из более чем 15 000) — это
          copy.cc. Известно, что для g++ 21
          тест (из примерно 250 000), 14 тестов «AddressSanitizer*» и 7
          тестов interception-malloc-test-1.C
          завершились неудачно. Кроме того, несколько тестов из каталога
          vect завершаются неудачно, если
          оборудование не поддерживает AVX.
        
        
          Не всегда удается избежать неожиданных сбоев. Разработчики GCC
          обычно знают об этих проблемах, но еще не решили их. Если
          результаты теста не сильно отличаются от результатов по указанному
          выше URL-адресу, можно продолжать.
        
        
          Установите пакет:
        
        make install
        
          Каталог сборки GCC теперь принадлежит пользователю tester, и владелец каталога заголовочных файлов
          (и его содержимого) указан неверно. Измените владельца на
          пользователя и группу root:
        
        chown -v -R root:root \
    /usr/lib/gcc/$(gcc -dumpmachine)/13.2.0/include{,-fixed}
        
          Создайте символическую ссылку, требуемую FHS
          по "историческим" причинам.
        
        ln -svr /usr/bin/cpp /usr/lib
        
          Многие пакеты используют имя cc для вызова компилятора языка
          Си. Мы уже создали cc
          как символическую ссылку в GCC-Проход 2, теперь создайте
          символическую ссылку на его справочную страницу:
        
        ln -sv gcc.1 /usr/share/man/man1/cc.1
        
          Добавьте символическую ссылку совместимости, чтобы включить сборку
          программ с оптимизацией времени компоновки (LTO):
        
        ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/13.2.0/liblto_plugin.so \
        /usr/lib/bfd-plugins/
        
          Теперь, когда наш окончательный набор инструментов готов, важно еще
          раз убедиться, что компиляция и компоновка будут работать так, как
          ожидалось. Мы сделаем это, выполнив проверку работоспособности:
        
        echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'
        
          Ошибок быть не должно, и вывод последней команды будет (с учетом
          платформо-зависимых различий в имени динамического компоновщика):
        
        [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
        
          Теперь убедитесь, что мы настроили использование правильных
          стартовых файлов:
        
        grep -E -o '/usr/lib.*/S?crt[1in].*succeeded' dummy.log
        
          Вывод последней команды должен быть:
        
        /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.0/../../../../lib/Scrt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/13.2.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/13.2.0/../../../../lib/crtn.o succeeded
        
          В зависимости от архитектуры вашего компьютера вышеуказанные
          параметры могут незначительно отличаться. Разница будет заключаться
          в имени каталога после /usr/lib/gcc.
          Здесь важно обратить внимание на то, что gcc нашел все три файла
          crt*.o в каталоге /usr/lib.
        
        
          Убедитесь, что компилятор ищет правильные заголовочные файлы:
        
        grep -B4 '^ /usr/include' dummy.log
        
          Эта команда должна вернуть следующий вывод:
        
        #include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.0/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.0/include-fixed
 /usr/include
        
          Опять же, имя каталога может отличаться от указанного выше, в
          зависимости от архитектуры вашей системы.
        
        
          Затем убедитесь, что новый компоновщик использует правильные пути
          поиска:
        
        grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
        
          Ссылки на пути, содержащие компоненты с '-linux-gnu', следует
          игнорировать, но в противном случае вывод последней команды должен
          быть таким:
        
        SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
        
          Затем убедитесь, что мы используем правильную libc:
        
        grep "/lib.*/libc.so.6 " dummy.log
        
          Вывод последней команды должен быть:
        
        attempt to open /usr/lib/libc.so.6 succeeded
        
          Убедитесь, что GCC использует правильный динамический компоновщик:
        
        grep found dummy.log
        
          Вывод последней команды должен быть (с учетом различий в имени
          динамического компоновщика, зависящих от платформы):
        
        found ld-linux-x86-64.so.2 at /usr/lib/ld-linux-x86-64.so.2
        
          Если вывод выглядит не так, как показано выше, или вообще не
          получен, значит, где-то серьезная ошибка. Изучите и повторите шаги,
          чтобы выяснить, в чем проблема, и исправьте ее. Любые проблемы
          должны быть решены, прежде чем вы продолжите процесс.
        
        
          Как только все заработает правильно, удалите тестовые файлы:
        
        rm -v dummy.c a.out dummy.log
        
          Наконец, переместите файл:
        
        mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib