Команда aarch64-linux-gnu-gcc запускает кросс-компилятор GCC, который собирает исполняемые файлы для 64-битной архитектуры ARM (AArch64) прямо на обычном x86-64 компьютере с Linux. Если при сборке проекта вы видите ошибку вида «aarch64-linux-gnu-gcc: command not found», это означает, что кросс-тулчейн просто не установлен в системе, и проблема решается установкой соответствующего пакета.
Такой инструмент нужен разработчикам встраиваемых систем, сборщикам ядер Linux для ARM-плат (Raspberry Pi, серверные ARM-платы, одноплатные компьютеры) и всем, кто готовит ПО для устройств, где нет возможности или смысла компилировать код локально. Ниже разберём, что скрывается за именем тулчейна, как его поставить и как избежать типовых ошибок.
Что означает имя aarch64-linux-gnu-gcc
Имя кросс-компилятора — это не случайный набор слов, а триплет целевой платформы плюс название инструмента. Каждый сегмент несёт конкретный смысл:
- 🧩 aarch64 — целевая архитектура: 64-битный ARM (ARMv8-A и новее);
- 🐧 linux — целевая операционная система, то есть Linux;
- 🔧 gnu — ABI и стандартная библиотека: GNU libc (glibc) и соглашения GNU;
- ⚙️ gcc — сам компилятор из набора GNU Compiler Collection.
Рядом могут существовать похожие варианты: aarch64-none-elf-gcc для «голого железа» без ОС, или aarch64-linux-musl-gcc для систем на musl libc. Путать их нельзя: бинарник, собранный под glibc, не запустится на системе с musl, и наоборот.
Установка кросс-компилятора
В Debian, Ubuntu и производных тулчейн доступен из штатных репозиториев. Установка выполняется одной командой:
sudo apt update
sudo apt install gcc-aarch64-linux-gnu
Если нужен ещё и компилятор C++, добавьте пакет g++-aarch64-linux-gnu. Для Fedora и родственных дистрибутивов пакет обычно называется gcc-aarch64-linux-gnu и ставится через dnf. Точное имя пакета зависит от дистрибутива, поэтому при неудаче поищите его через apt search aarch64 или аналог вашего пакетного менеджера.
Проверить результат можно запросом версии:
aarch64-linux-gnu-gcc --version
Если команда выводит версию компилятора — тулчейн на месте. Если снова «command not found», проверьте, что пакет действительно установился, и что каталог /usr/bin присутствует в переменной PATH.
Первая кросс-компиляция программы
Начните с минимального примера, чтобы убедиться, что вся цепочка работает. Создайте файл hello.c с обычным выводом строки и скомпилируйте его:
aarch64-linux-gnu-gcc hello.c -o hello
Убедиться, что получился именно ARM64-бинарник, поможет утилита file:
file hello
В выводе должно быть указано ELF 64-bit LSB executable, ARM aarch64. Обратите внимание: запустить такой файл на x86-машине напрямую не получится — ядро сообщит об ошибке формата. Для локального запуска используют эмуляцию через qemu-user либо копируют файл на целевое устройство.
☑️ Проверка рабочего тулчейна
Статическая и динамическая линковка
По умолчанию компилятор линкует программу динамически, и на целевом устройстве потребуются совместимые версии glibc и динамического загрузчика. Если версии библиотек на хосте сборки и устройстве различаются, программа может не запуститься с ошибкой вида «version GLIBC_X.XX not found».
Для простых утилит удобен выход — статическая сборка:
aarch64-linux-gnu-gcc -static hello.c -o hello
Файл получится заметно больше, зато не будет зависеть от библиотек целевой системы. Это особенно полезно для диагностических инструментов и программ, которые должны работать на разных прошивках.
⚠️ Внимание: статическая линковка с glibc имеет известные ограничения — функции, связанные с NSS (разрешение имён пользователей и хостов), могут вести себя иначе, чем при динамической сборке. Для сетевых демонов тестируйте такой вариант особенно тщательно.
Сборка проектов с Makefile и CMake
Реальные проекты редко собираются одной командой. Для Makefile-сборки обычно достаточно переопределить переменные компилятора:
make CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++
В CMake принято использовать toolchain-файл, где задаются система, процессор и пути к компиляторам. Минимальный вариант такого файла:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
Затем конфигурация запускается с параметром -DCMAKE_TOOLCHAIN_FILE=путь/к/файлу. Если проект зависит от сторонних библиотек, их тоже нужно собрать или раздобыть в ARM64-варианте и указать пути через CMAKE_FIND_ROOT_PATH — иначе сборка подхватит x86-библиотеки с хоста и упадёт на этапе линковки.
Типичные ошибки и их причины
| Ошибка | Вероятная причина | Что проверить |
|---|---|---|
| command not found | Тулчейн не установлен | Установить пакет gcc-aarch64-linux-gnu |
| cannot find -l<имя> | Нет ARM64-версии библиотеки | Собрать зависимость кросс-компилятором или настроить sysroot |
| Exec format error при запуске | Запуск ARM-бинарника на x86 | Использовать qemu-aarch64 или целевое устройство |
| GLIBC_X.XX not found | На устройстве старее glibc, чем на хосте | Собрать статически или под систему устройства |
| undefined reference при линковке | Подхвачены библиотеки хостовой архитектуры | Проверить пути поиска и CMAKE_FIND_ROOT_PATH |
⚠️ Внимание: никогда не указывайте в кросс-сборке пути к библиотекам хоста вроде -L/usr/lib без sysroot — линкер может молча подхватить x86-64 объекты, и ошибка проявится только на последнем этапе сборки или вообще на устройстве.
Отдельный частый случай — сборка модулей ядра: внешний модуль должен компилироваться тем же тулчейном и с теми же заголовками ядра, что и само ядро целевой платы. Несовпадение версий приводит к отказу загрузки модуля с ошибкой о неверном формате или несоответствии vermagic.
Запуск и отладка через QEMU и GDB
Для запуска ARM64-программ без реального железа установите пакет qemu-user. Статически собранный бинарник запускается напрямую:
qemu-aarch64 ./hello
Для динамически слинкованных программ потребуется указать каталог с ARM-библиотеками через параметр -L. Отладка возможна связкой aarch64-linux-gnu-gdb на хосте и gdbserver на устройстве либо в QEMU: отладчик подключается по сети и позволяет ставить точки останова, смотреть переменные и стек вызовов как при обычной отладке.
Чем aarch64 отличается от armhf и armel
armel и armhf — тулчейны для 32-битного ARM (ARMv7 и старше), причём armhf использует аппаратную FPU. aarch64 — 64-битная архитектура ARMv8+, несовместимая с 32-битными бинарниками на уровне ABI. Выбирать тулчейн нужно строго под систему, установленную на устройстве: проверить её можно командой uname -m на самом устройстве (aarch64 или armv7l).
Часто задаваемые вопросы
Чем aarch64-linux-gnu-gcc отличается от обычного gcc?
Обычный gcc собирает код под архитектуру машины, на которой запущен (чаще x86-64). Кросс-компилятор aarch64-linux-gnu-gcc работает на хосте, но генерирует машинный код для 64-битного ARM. Сами исходники при этом могут быть одинаковыми.
Можно ли собрать ядро Linux этим тулчейном?
Да, это один из основных сценариев. При сборке ядра указывают ARCH=arm64 и CROSS_COMPILE=aarch64-linux-gnu- в команде make. Конфигурацию берут из defconfig целевой платы или из работающей системы устройства.
Почему программа не запускается на устройстве с ошибкой о GLIBC?
Возможная причина — на хосте сборки glibc новее, чем на целевой системе, и бинарник ссылается на символы, которых там нет. Варианты решения: статическая сборка, сборка в окружении со старой glibc (например, в контейнере) или использование sysroot с библиотеками устройства.
Нужен ли отдельный тулчейн для Raspberry Pi?
Для 64-битной ОС на Raspberry Pi подходит обычный aarch64-linux-gnu-gcc. Для 32-битных систем Raspberry Pi OS нужен тулчейн под armhf — это другая цель, и смешивать их нельзя. Проверьте разрядность системы командой uname -m на самом устройстве.
Как узнать, какие библиотеки нужны ARM-бинарнику?
Используйте aarch64-linux-gnu-objdump -p файл или readelf -d файл из пакета binutils — они покажут список зависимостей (NEEDED) без запуска программы. Обычный ldd на хосте для чужой архитектуры не подойдёт.