Как утверждают разработчики компилятора, в GCC 5 стало всё хорошо с LTO. Учитывая, что по не зависящим от меня причинам я давно систему не обновлял, я решил проверить это утверждение на практике и пересобрать мир посредством GCC 5.4 с мультитредом, LTO и gold линкером. Прошлые мои эксперименты с LTO на GCC 4.7 были признаны неудовлетворительными: большое количество пакетов не собирались, а из тех, которые формально собрались, какая-то часть (непонятно какая) собиралась по факту без lto
благодаря дефолтному fat-objects
, который позволял в случае неудачи тихонечко собрать пакет с кодом, сгенерённым на этапе компиляции безо всякого lto. На графит я решил не заморачиваться: выигрыш сомнительный, а стабильность сильно под вопросом.
Дисклеймер: автор не несёт ответственности за сломанную вами систему при попытке следовать этому руководству. Я попытался сделать его максимально подробным, но это всего лишь примерное описание шагов, который не заменит понимания того, как работает система и что надо делать. Без этого понимания невозможно будет решить возникшие проблемы – а они будут! Используйте это как опорный конспект – на свой страх и риск.
Итак,
-
Собираем GCC 5.4 из нестабильной ветки,
root # echo “sys-devel/gcc” >> /etc/portage/package.accept_keywords
root # emerge -u sys-devel/gcc
root # gcc-config -l[1] x86_64-pc-linux-gnu-4.9.4 *
[2] x86_64-pc-linux-gnu-5.4.0
2. Переключаем компилятор командой
root # gcc-config 2
3. Пересобираем libtools
и устанавливаем binutils
посвежее (9999 не обязательно, достаточно размаскировать нестабильную версию)
root # env-update && source /etc/profile
root # emerge --oneshot libtool
root # echo "sys-devel/binutils" >> /etc/portage/package.accept_keywords
root # emerge --oneshot binutils
4. Переключаем линковщик
root # binutils-config --linker ld.gold
Чтобы подхватывались нужные ar nm
и ranlib
, необходимо создать симлинк
root # ln -s /usr/libexec/gcc/x86_64-pc-linux-gnu/5.4.0/liblto_plugin.so.0.0.0 /usr/x86_64-pc-linux-gnu/binutils-bin/lib/bfd-plugins
Некоторые устаревшие руководства предлагают поместить в make.conf
“обёртки” для этих программ, на настоящий момент этого делать не нужно, достаточно прописать симлинк.
Далее руководство по gcc советует
5. обновить зависимые пакеты
root # revdep-rebuild --library 'libstdc\+\+.so.6' -- --exclude gcc
В моём случае, учитывая, что я изменил режим компиляции и накопил большое количество обновлений, я попросту пересобрал мир. Мои флаги под AMD Athlon™ X4 760K:
CFLAGS="-march=native -pipe -Wno-all -O3 -flto=4 -fuse-ld=gold -mprefer-avx128 -mvzeroupper"
CXXFLAGS="${CFLAGS}"
LDFLAGS="-Wl,-O3,--sort-common,--hash-style=gnu,--as-needed -fuse-linker-plugin -s ${CGLAGS}"
Дальше процесс таков:
6. Создаём в директории /etc/portage/env
файл с названием no-lto.conf
следующего содержания:
CFLAGS="${CFLAGS} -fno-lto -fno-use-linker-plugin"
CXXFLAGS="${CXXFLAGS} -fno-lto -fno-use-linker-plugin"
LDFLAGS="${LDFLAGS} -fno-lto -fno-use-linker-plugin"
Кроме него, нам понадобятся файлы no-lto-bfd.conf
CFLAGS="${CFLAGS} -fno-lto -fno-use-linker-plugin -fuse-ld=bfd"
CXXFLAGS="${CXXFLAGS} -fno-lto -fno-use-linker-plugin -fuse-ld=bfd"
LDFLAGS="${LDFLAGS} -fno-lto -fno-use-linker-plugin"
vanilla-O3.conf
CFLAGS="-march=native -O3 -pipe -Wno-all"
CXXFLAGS="${CFLAGS}"
LDFLAGS="${LDFLAGS} -fno-lto -fno-use-linker-plugin"
gold.conf
EXTRA_ECONF="--enable-gold=default"
Создаём файл /etc/portage/package.env
следующего содержания:
sys-devel/binutils gold.conf
нужный для того, чтобы при пересборке binutils
не съехал линковщик. Далее настало время
7. собрать мир
emerge -e world
Если какой-то пакет не собирается, emerge
вылетит с ошибкой. Смотрим, какой файл не собрался, и добавляем строку в наш package.env
<категория/пакет> no-lto.conf
У меня получился следующий файл
sys-libs/zlib no-lto.conf
dev-lang/perl no-lto.conf
x11-base/xorg-server no-lto.conf
sys-libs/ncurses no-lto.conf
sys-devel/gettext no-lto.conf
dev-qt/qtscript no-lto.conf
dev-lang/spidermonkey no-lto.conf
media-libs/x264 no-lto.conf
dev-python/notify-python no-lto.conf
app-text/rarian no-lto.conf
x11-libs/wxGTK:2.8 no-lto.conf
media-video/mediainfo no-lto.conf
media-libs/alsa-lib no-lto.conf
app-emulation/qemu no-lto.conf
Состав этого файла зависит от архитектуры, версии компилятора и пакетов и от состава установленных пакетов и приводится в качестве примера.
8. Особые случаи. В большинстве случаев предложенный подход сработает, но не всегда. Есть пакеты, которые собираются только с минимальным набором флагов, в моём случае это
dev-lang/python vanilla-O3.conf
sys-boot/grub vanilla-O3.conf
Есть пакеты, которые собираются, но не работают, у меня это
#сегфолтится с lto
media-sound/timidity++ no-lto.conf
Есть пакеты, которые не собираются с gold-линковщиком
# требуют bfd
app-text/tesseract no-lto-bfd.conf
app-i18n/poedit no-lto-bfd.conf
media-gfx/enblend no-lto-bfd.conf
sys-apps/gsmartcontrol no-lto-bfd.conf
media-gfx/rawtherapee no-lto-bfd.conf
Надо отметить, что при чтении elog
файлов видно, что некоторые пакеты переключают линковщик сами и не требуют специальных манипуляций. Спасибо мейнтейнерам!
И наконец, самая хитрая категория: библиотеки, которые прекрасно собираются, но при оптимизации из них вычищаются нужные символы (объявленные локально?), из-за чего не собираются другие пакеты (у меня это poedit qemu rawtherapy gsmartcontrol и inkscape. Последний при этом даже собирается с lto, если библиотеки собраны без).
#В этих библиотеках иначе не видны все символы
dev-cpp/gtkmm no-lto.conf
dev-cpp/glibmm no-lto.conf
dev-cpp/atkmm no-lto.conf
dev-cpp/cairomm no-lto.conf
dev-libs/libaio no-lto.conf
Это полный список проблемных пакетов в системе, содержащей порядка 1100 пакетов. На настоящий момент система работает быстро и стабильно, хотя со временем могут выплыть ещё какие-то неожиданности. Так что, если кому-то будет нечего делать на праздники…