LINUX.ORG.RU

Wild 0.10

 , , wild


1

2

4 августа состоялся выпуск Wild 0.10 — свободного компоновщика, написанного на Rust и предназначенного прежде всего для быстрой сборки программ в Linux. Компоновщик выполняет заключительный этап сборки: объединяет объектные файлы и библиотеки в готовый исполняемый файл или разделяемую библиотеку. Wild может использоваться как замена GNU ld, LLD и Mold, хотя заявленная разработчиками конечная цель — инкрементальная компоновка — пока не реализована.

Одним из главных новшеств стала поддержка параметров --gdb-index и --no-gdb-index. При включении этой возможности Wild создаёт в выходном файле секцию .gdb_index с индексом отладочной информации. Благодаря этому GDB может быстрее находить необходимые символы в крупных программах, не формируя индекс отдельно после сборки. Реализация поддерживает девятую версию формата GDB Index; операции сканирования, объединения и записи индекса были распараллелены.

Значительно расширена работа со сценариями компоновщика. Добавлена поддержка:

  • секции /DISCARD/ для исключения ненужных входных секций;
  • пользовательских заголовков программ PHDRS;
  • функций SIZEOF_HEADERS, DEFINED и SEGMENT_START;
  • ключевого слова AT и функции LOADADDR;
  • условных выражений с тернарным оператором;
  • команд SORT, SORT_BY_NAME и SORT_BY_ALIGNMENT;
  • символа __bss_start;
  • шаблонов заполнения выходных секций;
  • команд OUTPUT_FORMAT и OUTPUT_ARCH;
  • нескольких относительных счётчиков текущего адреса.

Полная совместимость с GNU ld пока не достигнута. Например, часть возможностей команды MEMORY, секции OVERLAY и некоторые способы размещения секций остаются незавершёнными. Разработчики отдельно ведут таблицу возможностей, необходимых для компоновки ядра Linux.

Улучшена производительность при размещении результатов сборки на Btrfs и VFAT. Wild теперь автоматически использует режим --no-mmap-output-file и не отображает выходной файл в память через mmap. В проведённом разработчиком испытании компоновки Zed на Btrfs время сократилось примерно с 2,6–2,8 до 1,5–1,8 секунды. При этом автор изменения предупреждает, что даже после оптимизации Btrfs в данном сценарии остаётся значительно медленнее tmpfs; для Ext4 и XFS использование mmap, напротив, оказалось выгоднее.

Продолжается перенос Wild на другие форматы и платформы. Экспериментальная версия для WebAssembly уже способна компоновать ряд программ, а порт для Mach-O — простейшие исполняемые файлы. Начата работа над 32-разрядными целевыми платформами, что в дальнейшем должно упростить применение Wild в разработке встраиваемых систем. Также добавлена начальная обработка объектных файлов PowerPC64 ELFv2 и продолжено развитие поддержки Mach-O, включая универсальные объектные файлы и прямую компоновку с динамическими библиотеками. Эти порты пока не следует считать готовыми для повседневного использования.

Библиотечный вариант компоновщика libwild теперь может получать входные файлы и сохранять результат непосредственно в памяти. Это позволяет другим программам встраивать Wild без обязательного создания промежуточных файлов на диске. Кроме того, библиотека больше не переопределяет глобальный пул потоков Rayon, а поддержку сжатия Zstandard можно отключить во время сборки.

В релиз вошло множество исправлений для x86-64, AArch64, RISC-V и LoongArch64. Устранены ошибки обработки TLS, PLT, LTO, сжатой отладочной информации, больших выравниваний и перемещений в PIE- и разделяемых объектах. Исправлены возможные аварийные завершения при разборе сценариев компоновщика и ошибки формирования секций .tbss, .strtab и .eh_frame.

Wild поддерживает Linux на архитектурах x86-64, AArch64 и RISC-V; поддержка LoongArch64 и PowerPC64LE пока обозначена как начальная. Установить компоновщик можно из готовых архивов, через cargo-binstall, Homebrew, Nix или командой cargo install --locked wild-linker. Исходный код распространяется на выбор пользователя под лицензиями Apache 2.0 или MIT.

>>> Источник

★★★★★

Проверено: cetjs2 ()
Последнее исправление: cetjs2 (всего исправлений: 1)

wild c wild'ом собирается дольше, чем с mold'ом.

Ololo_Trololo ★★
()
Ответ на: комментарий от bernd

типа быстрый, но он довольно активно развивается, если случится ещё про него новость делать, обязательно учту замечание

unclestephen ★★★★★
() автор топика
Ответ на: комментарий от troizet

Никогда. И слава всем богам.
Команда GCC делом занята, а не переписыванием ради переписывания ради прохождения синтетического набора тестов ради гранта от дядь.

DzenPython
()
Ответ на: комментарий от gns

А чем их ld-то не устраивает?

Why another linker?
Mold is already very fast, however it doesn't do incremental linking and the author has stated that they don't intend to. Wild doesn't do incremental linking yet, but that is the end-goal. By writing Wild in Rust, it's hoped that the complexity of incremental linking will be achievable.
hippi90 ★★★★★
()
Ответ на: комментарий от bernd

Если c mold и быстрее, то на одну-пару секунд. Короче, счас перепроверил, можно сказать, что паритет.

Ololo_Trololo ★★
()
Последнее исправление: Ololo_Trololo (всего исправлений: 1)
Ответ на: комментарий от moonmadness

Да всем все можно... Только я делаю то, чего еще не было. А он переделывает то, что уже есть. Алгоритмы инкрементального линкера проще не станут от того, что кто-то их на Расте напишет. Дело не в расте, а в голове разработчика. И выигрыш в скорости там сомнительный.

gns ★★★★★
()
Ответ на: комментарий от gns

Только я делаю то, чего еще не было

Верю, конечно, а посмотреть где?

А он переделывает то, что уже есть

Типа гнутые разрабы застолбили за собой право пилить «один линкер, один компилятор, один бинутилс (c)», а после них уже низзя?

Дело не в расте, а в голове разработчика

Так это же ты у себя в голове обиделся на раст, а чувак просто пилит софт.

И выигрыш в скорости там сомнительный.

Гнутый линкер – медленная шляпа, все это знают, кроме экспертов с лора почему-то.

moonmadness
()
Ответ на: комментарий от hippi90

Mold is already very fast, however it doesn’t do incremental linking and the author has stated that they don’t intend to.

Вот что пишет автор mold в design.md#rejected-ideas:

Incremental linking

Idea: Incremental linking is a technique to patch a previous linker's output file so that only functions or data that are updated from the previous build are written to it. It is expected to significantly reduce the amount of data copied from input files to an output file and thus speed up linking. GNU BFD and gold linkers support it.

Reason for rejection: I turned it down because it (1) is complicated, (2) doesn't seem to speed it up that much and (3) has several practical issues. Let me explain each of them.

First, incremental linking for real C/C++ programs is not as easy as one might think. Let me take malloc as an example. malloc is usually defined by libc, but you can implement it in your program, and if that's the case, the symbol malloc will be resolved to your function instead of the one in libc. If you include a library that defines malloc (such as libjemalloc or libtbbmallc) before libc, their malloc will override libc's malloc.

Assume that you are using a nonstandard malloc. What if you remove your malloc from your code, or remove -ljemalloc from your Makefile? The linker has to include a malloc from libc, which may include more object files to satisfy its dependencies. Such code change can affect the entire program rather than just replacing one function. The same is true for adding malloc to your program. Making a local change doesn't necessarily result in a local change in the binary level. It can easily have cascading effects.

Some ELF fancy features make incremental linking even harder to implement. Take the weak symbol as an example. If you define atoi as a weak symbol in your program, and if you are not using atoi at all in your program, that symbol will be resolved to address 0. But if you start using some libc function that indirectly calls atoi, then atoi will be included in your program, and your weak symbol will be resolved to that function. I don't know how to efficiently fix up a binary for this case.

This is a hard problem, so existing linkers don't try too hard to solve it. For example, IIRC, gold falls back to full link if any function is removed from a previous build. If you want to not annoy users in the fallback case, you need to make full link fast anyway.

Second, incremental linking itself has an overhead. It has to detect updated files, patch an existing output file and write additional data to an output file for future incremental linking. GNU gold, for instance, takes almost 30 seconds on my machine to do a null incremental link (i.e. no object files are updated from a previous build) for chrome. It's just too slow.

Third, there are other practical issues in incremental linking. It's not reproducible, so your binary isn't going to be the same as other binaries even if you are compiling the same source tree using the same compiler toolchain. Or, it is complex and there might be a bug in it. If something doesn't work correctly, "remove --incremental from your Makefile and try again" could be a piece of advice, but that isn't ideal.

So, all in all, incremental linking is tricky. I wanted to make full link as fast as possible, so that we don't have to think about how to work around the slowness of full link.
dataman ★★★★★
()
Ответ на: комментарий от moonmadness

Верю, конечно, а посмотреть где?

У наших заказчиков например.

Я на раст не обиделся, мне как-то похрену. Гнаться за скоростью надо там, где в этом есть смысл. Компиляция по любому дольше линковки.

Гнутый линкер – медленная шляпа, все это знают, кроме экспертов с лора почему-то.

Я как-то видел систем больше десятка, и не только линукс. И чот на скорость линковки не жаловался. Ну кроме генерации операционных систем на PDP-11. Вот там действительно долго, пока система из объектников компонуется можно пообедать с пивом успеть. Но линковщик для RT-11 вряд ли кто-то на расте переписывать будет :)

gns ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.