Система сборки и кросс-компиляция

Осваиваем build.zig и одну из лучших в индустрии кросс-компиляций.

Кросс-компиляция — сборка исполняемого файла под платформу, отличную от той, на которой идёт компиляция; в Zig это встроено и работает без установки сторонних тулчейнов.

Сборка в Zig описывается не отдельным языком (как Makefile или CMake), а файлом build.zig на самом Zig. Это снова принцип явности: логика сборки — обычный код, который вы читаете и отлаживаете как любой другой.

Файл build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    const exe = b.addExecutable(.{
        .name = "myapp",
        .root_source_file = b.path("src/main.zig"),
        .target = b.standardTargetOptions(.{}),
        .optimize = b.standardOptimizeOption(.{}),
    });
    b.installArtifact(exe);
}

Функция build — точка входа сборки. Она описывает, что собрать: исполняемый файл с именем, корневым исходником, целевой платформой и уровнем оптимизации. Запускают это командой zig build. Поскольку это код Zig, в нём можно ветвиться, генерировать шаги, подключать зависимости — всё средствами языка.

Кросс-компиляция «из коробки»

# собрать под Windows x86_64 с Linux — без доп. тулчейнов
zig build-exe main.zig -target x86_64-windows

# под ARM Linux
zig build-exe main.zig -target aarch64-linux

# под WebAssembly
zig build-exe main.zig -target wasm32-freestanding

Вот где Zig блистает: флаг -target указывает любую цель, и компилятор соберёт под неё, не требуя устанавливать кросс-тулчейн. Zig везёт с собой исходники стандартных библиотек C для множества платформ. Достичь этого в C/C++ традиционно мучительно, а здесь это одна строка.

Уровни оптимизации

// четыре режима, задаются при сборке:
// Debug         — проверки безопасности, без оптимизаций (по умолчанию)
// ReleaseSafe   — оптимизации + проверки переполнения/границ
// ReleaseFast   — максимум скорости, проверки сняты
// ReleaseSmall  — минимальный размер бинарника

Режим выбирают флагом -O, например -OReleaseFast. Важно помнить: проверки переполнения и границ (о которых мы говорили) активны в Debug и ReleaseSafe, но снимаются в ReleaseFast ради скорости. Это осознанный компромисс безопасность/производительность.

Как работает под капотом

Секрет кросс-компиляции — в том, что Zig включает полный набор заголовков и исходников libc для каждой поддерживаемой цели и собирает нужные части на лету. Бэкенд (LLVM или собственный) умеет генерировать код под разные архитектуры. Поэтому одной командой можно собрать бинарник под платформу, которой у вас даже нет под рукой — это делает Zig популярным инструментом сборки даже для проектов на чистом C.

Частые ошибки

Первая — искать Makefile или CMake: в Zig это build.zig на самом языке. Вторая — отлаживать в ReleaseFast и не понимать, почему переполнение не ловится: переключитесь на ReleaseSafe или Debug. Третья — думать, что кросс-компиляция требует доустановки тулчейнов: для большинства целей всё уже внутри Zig.

Итог

  • Сборку описывает build.zig — обычный код Zig, запускаемый через zig build.
  • Кросс-компиляция встроена: -target под Windows, ARM, WebAssembly без доп. тулчейнов.
  • Четыре режима оптимизации; проверки безопасности активны в Debug и ReleaseSafe.
  • Zig везёт исходники libc для многих платформ — отсюда лёгкость кросс-сборки.
Проверьте себя
1. На каком языке пишется файл сборки build.zig?
AНа особом DSL вроде Makefile
BНа самом Zig — это обычный код
CНа YAML
DНа CMake-синтаксисе
2. Что нужно установить для кросс-компиляции под другую платформу в Zig?
AОтдельный кросс-тулчейн для каждой цели
BНичего — кросс-компиляция встроена, достаточно флага -target
CGCC под целевую платформу
DВиртуальную машину