Загружаемые сборки
Загружаемые сборки (англ. bootstrappable builds) — это процесс компиляции программного обеспечения, не зависящий от (компиляторных) бинарных файлов, которые не были собраны из исходных текстов в рамках этого же процесса[1][2].
Данный процесс позволяет защититься от закладок в компиляторах: если процесс сборки не зависит от бинарного кода, аудит которого затруднён, то внедрить скрытую закладку в бинарных файлах компилятора становится невозможно.
Методы
Одним из способов решить эту задачу для дистрибутива программного обеспечения является уменьшение объёма бинарных файлов, используемых для начальной сборки (bootstrap), до тех пор, пока они вовсе не станут не нужны или их размер не уменьшится настолько, чтобы люди могли их легко просмотреть и проверить[3].
Многие компиляторы для разных языков программирования написаны на том же языке, для которого они предназначены. Например, официальный компилятор Go (gc) реализован на языке Go.
Проблема циклической зависимости для Go решена путём использования версии Go 1.4, написанной на C, которая применяется для последовательной сборки более новых версий[4]. Язык Rust также достиг полной загружаемости через альтернативный компилятор mrustc, написанный на C++[4].
Для реализации загружаемых сборок часто можно найти более старую версию компилятора, которую можно собрать из исходных текстов. Далее возможно написать код, автоматически собирающий последовательно следующие версии компилятора вплоть до современной. Определение, какие версии компиляторов способны собирать последующие, зачастую представляет собой нетривиальную задачу, а сам процесс может быть весьма длительным по времени. Иногда для этого приходится поддерживать старые версии компиляторов и внедрять в них поддержку новых архитектур процессоров, чтобы обеспечить сборку на современных системах. К примеру, GCC 4.7 — последняя версия, которую можно собрать с помощью tcc, а затем использовать её для сборки всех последующих выпусков GCC[5].
Этот процесс можно заменить или дополнить иными способами начального построения (bootstrap) компиляторов.
Например, также возможно создать новый компилятор для языка, написанный на другом языке программирования.
Подобные приёмы позволяют уменьшить размер бинарных файлов, необходимых для инициализации сборки дистрибутива.
Для сборки самого первого компилятора, который затем будет использоваться для построения остальных компиляторов, возможно уменьшить размер исходного бинарника до 357 байт (файла hex0)[6], после чего использовать многостадийную процедуру, проходящую через hex1, M0, M2-Planet, GNU Mes, TinyCC и старые версии GCC вплоть до современного компилятора[7][8].
Проблемы и ограничения
Некоторые программные продукты могут зависеть от самих себя при сборке, причём их первая версия могла быть собрана способом, не соответствующим принципам загружаемых сборок.
Одним из таких примеров является Gradle, разработчики которого не планируют поддерживать независимую сборку из-за использования Kotlin DSL и сложностей обновления[9]. При этом для Scala (первая версия которой основывалась на проприетарных компонентах[10]) и Kotlin по-прежнему нет пути сборки без бинарных артефактов[10].
Связь с воспроизводимыми сборками
Воспроизводимые сборки (англ. reproducible builds) гарантируют побитовую идентичность артефактов при использовании одних и тех же исходных кодов и инструкций. В свою очередь, загружаемые сборки решают проблему доверия к самому компилятору[11]. Только комбинация этих двух подходов обеспечивает полную безопасность и проверяемость пути от исходного кода к конечному бинарному файлу[12].
История
Проект «Bootstrappable Builds» был начат в 2016 году как ответвление от инициативы «Reproducible Builds»[2].
В 2019 году дистрибутивы Guix, NixOS и Debian создали побитово идентичные бинарные файлы GNU Mes с помощью разных версий GCC, подтвердив эффективность метода разнообразной двойной компиляции (diverse double-compiling). С октября того же года Guix начал использовать компилятор MesCC для сборки TinyCC и последующей сборки GCC.
В 2020 году применение GNU Mes позволило сократить размер бинарного семени для начальной загрузки Guix на 50 %. В 2021 году бинарные семена для MesCC-Tool и GNU Mes были заменены на Stage0 и M2-Planet, что позволило достичь полной начальной загрузки системы исключительно из исходных кодов (Full Source Bootstrap).
В 2022 году система управления пакетами Guix впервые получила возможность собираться, начиная с того самого 357-байтового бинарного файла[6].
26 апреля 2026 года на конференции LinuxFest Northwest Вагрант Каскадиан представил доклад о взаимосвязи свободного программного обеспечения, воспроизводимых и загружаемых сборок. В том же году команда релиза Debian приняла новую политику, согласно которой начиная с версии forky дистрибутив будет поставлять только воспроизводимые пакеты, блокируя миграцию невоспроизводимых.