8.29.1. Установка пакета GCC
        
        
          При сборке на x86_64 измените имя каталога по умолчанию для
          64-битных библиотек на «lib»:
        
        case $(uname -m) in
  x86_64)
    sed -e '/m64=/s/lib64/lib/' \
        -i.orig gcc/config/i386/t-linux64
  ;;
esac
        
          Документация GCC рекомендует собирать GCC в отдельном каталоге:
        
        mkdir -v build
cd       build
        
          Подготовьте GCC к компиляции:
        
        ../configure --prefix=/usr            \
             LD=ld                    \
             --enable-languages=c,c++ \
             --enable-default-pie     \
             --enable-default-ssp     \
             --enable-host-pie        \
             --disable-multilib       \
             --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 может потребоваться больше места в стеке для компиляции
          некоторых сложных шаблонов кода. В качестве меры предосторожности
          для хост-дистрибутивов с жестким ограничением стека явно установите
          неограниченный жесткий предел. В большинстве хост-дистрибутивов (и
          в собранной LFS) жесткий предел по умолчанию неограничен, но нет
          ничего плохого в том, чтобы установить его явно. Также нет
          необходимости изменять мягкий предел размера стека, поскольку GCC
          автоматически установит для него соответствующее значение, если это
          значение не превышает жесткий предел:
        
        ulimit -s -H unlimited
        
          Теперь удалите/исправьте несколько известных ошибок тестирования:
        
        sed -e '/cpython/d'               -i ../gcc/testsuite/gcc.dg/plugin/plugin.exp
sed -e 's/no-pic /&-no-pie /'     -i ../gcc/testsuite/gcc.target/i386/pr113689-1.c
sed -e 's/300000/(1|300000)/'     -i ../libgomp/testsuite/libgomp.c-c++-common/pr109062.c
sed -e 's/{ target nonpic } //' \
    -e '/GOTPCREL/d'              -i ../gcc/testsuite/gcc.target/i386/fentryname3.c
        
          Выполните тестирование от имени непривилегированного пользователя,
          но не останавливайтесь на ошибках:
        
        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.2/
          и https://gcc.gnu.org/ml/gcc-testresults/.
        
        
          Не всегда удается избежать неожиданных сбоев. В некоторых случаях
          неудачное завершение тестов - это следствие их выполнения на
          конкретном оборудовании системы. Если результаты теста не сильно
          отличаются от результатов по указанному выше URL-адресу, можно
          продолжать.
        
        
          Установите пакет:
        
        make install
        
          Каталог сборки GCC теперь принадлежит пользователю tester, и владелец каталога заголовочных файлов
          (и его содержимого) указан неверно. Измените владельца на
          пользователя и группу root:
        
        chown -v -R root:root \
    /usr/lib/gcc/$(gcc -dumpmachine)/14.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)/14.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/14.2.0/../../../../lib/Scrt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/14.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/14.2.0/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/14.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");
        
          32-разрядная система может использовать несколько других каталогов.
          Например, вот вывод с компьютера i686:
        
        SEARCH_DIR("/usr/i686-pc-linux-gnu/lib32")
SEARCH_DIR("/usr/local/lib32")
SEARCH_DIR("/lib32")
SEARCH_DIR("/usr/lib32")
SEARCH_DIR("/usr/i686-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