Previous: The Full-Source Bootstrap, Up: Начальная загрузка [Contents][Index]
The figure above shows the very beginning of the dependency graph of the
distribution, corresponding to the package definitions of the (gnu
packages bootstrap)
module. A similar figure can be generated with
guix graph
(see Вызов guix graph
), along the lines of:
guix graph -t derivation \ -e '(@@ (gnu packages bootstrap) %bootstrap-gcc)' \ | dot -Tps > gcc.ps
or, for the further Reduced Binary Seed bootstrap
guix graph -t derivation \ -e '(@@ (gnu packages bootstrap) %bootstrap-mes)' \ | dot -Tps > mes.ps
At this level of detail, things are slightly complex. First, Guile itself
consists of an ELF executable, along with many source and compiled Scheme
files that are dynamically loaded when it runs. This gets stored in the
guile-2.0.7.tar.xz tarball shown in this graph. This tarball is part
of Guix’s “source” distribution, and gets inserted into the store with
add-to-store
(see Хранилище).
But how do we write a derivation that unpacks this tarball and adds it to
the store? To solve this problem, the guile-bootstrap-2.0.drv
derivation—the first one that gets built—uses bash
as its
builder, which runs build-bootstrap-guile.sh
, which in turn calls
tar
to unpack the tarball. Thus, bash, tar, xz,
and mkdir are statically-linked binaries, also part of the Guix
source distribution, whose sole purpose is to allow the Guile tarball to be
unpacked.
Once guile-bootstrap-2.0.drv
is built, we have a functioning Guile
that can be used to run subsequent build programs. Its first task is to
download tarballs containing the other pre-built binaries—this is what the
.tar.xz.drv derivations do. Guix modules such as
ftp-client.scm
are used for this purpose. The
module-import.drv
derivations import those modules in a directory in
the store, using the original layout. The module-import-compiled.drv
derivations compile those modules, and write them in an output directory
with the right layout. This corresponds to the #:modules
argument of
build-expression->derivation
(see Деривации).
Finally, the various tarballs are unpacked by the derivations
gcc-bootstrap-0.drv
, glibc-bootstrap-0.drv
, or
bootstrap-mes-0.drv
and bootstrap-mescc-tools-0.drv
, at which
point we have a working C tool chain.
Bootstrapping is complete when we have a full tool chain that does not
depend on the pre-built bootstrap tools discussed above. This no-dependency
requirement is verified by checking whether the files of the final tool
chain contain references to the /gnu/store directories of the
bootstrap inputs. The process that leads to this “final” tool chain is
described by the package definitions found in the (gnu packages
commencement)
module.
The guix graph
command allows us to “zoom out” compared to the
graph above, by looking at the level of package objects instead of
individual derivations—remember that a package may translate to several
derivations, typically one derivation to download its source, one to build
the Guile modules it needs, and one to actually build the package from
source. The command:
guix graph -t bag \ -e '(@@ (gnu packages commencement) glibc-final-with-bootstrap-bash)' | xdot -
displays the dependency graph leading to the “final” C library42, depicted below.
Первый инструмент, который собирается с помощью двоичных файлов начальной
загрузки, - это GNU Make—отмеченный make-boot0
выше—который
является обязательным для всех следующих пакетов. После собираются Findutils
и Diffutils.
Затем идут Binutils и GCC, построенные как псевдо-кросс-инструменты—т.е. с
--target
, равным --host
. Они используются для сборки
libc. Благодаря этому кросс-сборочному трюку, libc гарантированно не будет
содержать никаких ссылок на начальный набор инструментов.
Оттуда создаются финальные версии Binutils и GCC (не показаны выше). GCC
использует ld
из финального Binutils и связывает программы с только
что созданным libc. Эта цепочка инструментов используется для сборки других
пакетов, используемых Guix и система сборки GNU: Guile, Bash, Coreutils и
т.д.
И вуаля! Теперь у нас есть полный набор инструментов сборки, который ожидает
система сборки GNU. Они находятся в переменной %final-input
модуля
(gnu packages commencement)
и неявно используются любым пакетом,
использующим gnu-build-system
(see gnu-build-system
).
Поскольку окончательный набор инструментов не зависит от двоичных файлов
начальной загрузки, их редко требуется обновлять. Тем не менее, полезно
иметь автоматический способ их создания, если произойдет обновление, и это
то, что обеспечивает модуль (gnu packages make-bootstrap)
.
Следующая команда создает tar-архивы, содержащие двоичные файлы начальной загрузки (Binutils, GCC, glibc, для традиционной загрузки и linux-libre-headers, bootstrap-mescc-tools, bootstrap-mes для начальной загрузки Reduced Binary Seed, Guile и tarball содержащий смесь Coreutils и других основных инструментов командной строки):
tar архив начальной сборки guix
Сгенерированные тарболы - это те, на которые нужно ссылаться в модуле
(gnu packages bootstrap)
, упомянутом в начале этого раздела.
Все еще здесь? Тогда, может быть, вы задались вопросом: когда мы достигнем фиксированной точки? Это интересный вопрос! Ответ неизвестен, но если вы хотите продолжить исследование (и располагаете значительными вычислительными ресурсами для этого), сообщите нам.
Our traditional bootstrap includes GCC, GNU Libc, Guile, etc. That’s a lot of binary code! Why is that a problem? It’s a problem because these big chunks of binary code are practically non-auditable, which makes it hard to establish what source code produced them. Every unauditable binary also leaves us vulnerable to compiler backdoors as described by Ken Thompson in the 1984 paper Reflections on Trusting Trust.
This is mitigated by the fact that our bootstrap binaries were generated from an earlier Guix revision. Nevertheless it lacks the level of transparency that we get in the rest of the package dependency graph, where Guix always gives us a source-to-binary mapping. Thus, our goal is to reduce the set of bootstrap binaries to the bare minimum.
The Bootstrappable.org web site lists on-going projects to do that. One of these is about replacing the bootstrap GCC with a sequence of assemblers, interpreters, and compilers of increasing complexity, which could be built from source starting from a simple and auditable assembler.
Our first major achievement is the replacement of GCC, the GNU C Library and Binutils by MesCC-Tools (a simple hex linker and macro assembler) and Mes (see GNU Mes Reference Manual in GNU Mes, a Scheme interpreter and C compiler in Scheme). Neither MesCC-Tools nor Mes can be fully bootstrapped yet and thus we inject them as binary seeds. We call this the Reduced Binary Seed bootstrap, as it has halved the size of our bootstrap binaries! Also, it has eliminated the C compiler binary; i686-linux and x86_64-linux Guix packages are now bootstrapped without any binary C compiler.
Work is ongoing to make MesCC-Tools and Mes fully bootstrappable and we are also looking at any other bootstrap binaries. Your help is welcome!
You may notice the glibc-intermediate
label,
suggesting that it is not quite final, but as a good approximation,
we will consider it final.
Previous: The Full-Source Bootstrap, Up: Начальная загрузка [Contents][Index]