
Каким должен быть компилятор будущего?
Этот вопрос мы задавали себе на каждом этапе разработки AsmX. В мире, где скорость и удобство дистрибуции кода стали так же важны, как и его производительность, роль компилятора больше не может ограничиваться простой трансляцией исходников в бинарный файл. Этого уже недостаточно.
Компилятор будущего — это умный партнер, который берет на себя всю рутину, освобождая разработчика для творчества. Он должен понимать не только архитектуру процессора, но и экосистему, в которой будет жить приложение.
Мы считаем, что нашли ответ. Встречайте AsmX G3 v29.
Это не просто обновление. Это кульминация нашей эволюции: отточив в предыдущих версиях стабильность и скорость генерации кода, мы перешли на следующий уровень. AsmX теперь берет на себя самую сложную и рутинную часть работы — упаковку и подготовку к дистрибуции.
С этого дня AsmX G3 v29 — это первый в своем роде компилятор с нативной поддержкой упаковки для Debian-based систем (.deb).
Что это значит на практике?
Никаких сторонних утилит. Забудьте о сложных сборочных скриптах и ручной конфигурации пакетов.
Одна команда — полный цикл. Вы пишете код, а AsmX компилирует его, правильно упаковывает со всеми зависимостями и готовит к загрузке в репозитории.
Экосистемный подход. Мы понимаем, что Linux — это мир разнообразия. Поэтому мы реализовали нативную поддержку самых влиятельных форматов пакетов, покрывая огромную часть дистрибутивов от Ubuntu и Mint.
Добро пожаловать в будущее компиляции. Оно уже здесь.
Введение
Мы не просто выпускаем обновления. Мы переосмысливаем процесс разработки. Пока другие обсуждают, мы создаём. Пока скептики сомневаются, мы пишем код. AsmX G3 v29 — это не очередной релиз. Это наш ответ на вопрос: «Как должен выглядеть компилятор в 2025 году?». Это инструмент, который даёт разработчикам полный контроль над железом, от машинного кода до готовых к дистрибуции пакетов. Это философия, где производительность, простота и открытость — не компромисс, а стандарт.
Этот релиз — результат тысяч строк кода, бессонных ночей и обратной связи от сообщества. Мы услышали ваши вопросы, критику и предложения. Мы не пошли на компромиссы с нашим видением, но сделали AsmX ближе к реальным задачам: от низкоуровневого программирования до создания приложений, готовых к установке на миллионы Linux-систем. С поддержкой .deb
-пакетов мы открываем двери для разработчиков, которые хотят не просто писать код, а распространять его по всему миру.
Приготовьтесь. AsmX G3 v29 — это не просто компилятор. Это мост между вашим кодом и реальным миром который не просто создает программы, а доставляет их пользователю. Это наш вызов индустрии — и приглашение вам присоединиться к созданию будущего.
О главном: Прямые ответы на острые вопросы
В сообществе было много дискуссий. Я ценю обратную связь, даже самую резкую. Давайте проясним несколько моментов раз и навсегда.
1. «Не ясен кому этот проект нужен (то есть нет заказчика)...»
Заказчик? Скажите, кто был заказчиком у Кернигана и Ритчи, когда они в стенах Bell Labs создавали C
? Кто заказывал Линусу Торвальдсу ядро операционной системы, которое сегодня работает на большинстве серверов мира? Великие проекты рождаются не из коммерческих заказов, а из инженерной необходимости и видения будущего. Мы создаем инструмент для тех, кто понимает, что производительность и полный контроль — это не опция, а фундаментальное требование.
Пользователи приходят туда, где есть технология, решающая реальные задачи. Kotlin
годами был нишевым языком, пока его не признали стандартом для Android. Мы играем вдолгую. А что касается денег — да, я не против продавать этот продукт. Но он будет стоить дорого, потому что инновации, тысячи часов работы и бессонные ночи инженеров имеют свою цену.
2. «...сначала делают функциональную модель с элементами математики... Этого шага нет.»
Мы инженеры, а не теоретики. Наша "математическая модель" — это работающий код, подкрепленный исчерпывающими тестами. Мы не тратим время на построение абстрактных гипотез, популярных в академических кругах с их Haskell
и монадами. Наша лаборатория — это кодовая база, а наши доказательства — это работающие тесты, такие как опубликованный набор hwm/units
. Мы проверяем идеи на практике, в реальных условиях, потому что только так создаются инструменты, которыми действительно можно пользоваться, а не только восхищаться на бумаге. Это не "отсутствие шага", это другой, более прагматичный подход.
3. «Код проекта... ужасен... таблицы описания процессоров должны быть отделены от алгоритмов...»
Давайте говорить на языке фактов, а не эмоций. Описание архитектуры (ISA
) и алгоритмы её кодирования в модуле hwm
(Hardware Machine) уже разделены.
Описание архитектуры находится в файле
tbl.cts
. Это декларативные таблицы, которые определяют инструкции и их варианты.Алгоритм кодирования находится в
main.cts
. Это логика, которая берет описание изtbl
и преобразует его в машинный код.База данных регистров (
rdb
) co-лоцирована вmain.cts
для производительности и удобства, но логически это отдельная сущность.
Они существуют в разных файлах и выполняют разные, четко очерченные роли. Это и есть правильное разделение ответственности.
Теперь о JSON. Использовать его здесь — значит добровольно добавить хрупкий слой парсинга и потерять всю мощь и безопасность строгой типизации, которую нам дает TypeScript. Преобразование "сырых" данных из JSON в сложные, вложенные типизированные интерфейсы — это лишний шаг, который только увеличивает вероятность ошибок. Вы просили больше TypeScript — вы его получили, и мы используем его сильные стороны по максимуму. Мы выбираем инженерную надежность, а не слепое следование трендам.
4. «...про оптимизацию алгоритмов в вашем проекте – ни слова.»
Оптимизация чего именно? Абстрактных алгоритмов? Если речь о высокоуровневых оптимизациях, таких как формы SSA
(Static Single Assignment), то на уровне ассемблера они просто неуместны. AsmX — это инструмент для прямого управления железом. Его философия — не исправлять за программистом неэффективный код, а дать ему возможность написать изначально оптимальный.
Мы даем в руки хирурга скальпель, а не автоматизированный медицинский дрон. Интеграция с LLVM превратила бы проект в громоздкую, многоязыковую систему и лишила бы нас главного — полного контроля. Мы выбираем чистоту, скорость и прямоту. Оптимизация заложена в самой архитектуре компилятора, которая генерирует предсказуемый и эффективный машинный код без "черных ящиков".
Вперед, в 64-битное будущее: Почему мы не оглядываемся назад
Давайте начистоту: 32-битные системы — это прошлое. Технологический долг. Мы не создаем продукты для прошлого.
Начинать сегодня с поддержки x86
— это все равно что проектировать автомобиль с карбюратором. Зачем? Чтобы потом героически решать проблемы перехода на 64-битную архитектуру? Нет, спасибо. Мы сразу строим на современном фундаменте — amd64
(x86_64
), потому что именно здесь находится настоящее и будущее высокой производительности.
Гиганты индустрии, такие как gcc
и clang
, вынуждены тащить за собой огромный багаж совместимости, включая поддержку 32-битных систем. Этот "лишний вес" замедляет их и усложняет. Мы же свободны от этого. Наш фокус на amd64
— это не ограничение, а стратегическое преимущество. Мы создаем легкий, быстрый и современный инструмент для мира, который уже давно стал 64-битным.
Микроархитектуры: Почему мы говорим «Нет» безумию уровней
Давайте поговорим о микроархитектурах. Это сложная тема, полная нюансов, и, к сожалению, полная опасных упрощений. В мире разработки компиляторов и операционных систем то, как вы подходите к этому вопросу, определяет, создаете ли вы надежный инструмент или хрупкую абстракцию, готовую рассыпаться.
Многие из вас, вероятно, слышали о так называемых "уровнях" x86-64
: v2
, v3
, v4
. Это попытка классифицировать поколения процессоров по набору поддерживаемых инструкций. На первый взгляд, идея кажется здравой. Вот таблица, которая иллюстрирует этот подход:

Вы можете даже проверить, какие уровни поддерживает ваша собственная система, выполнив команду:
$ /lib64/ld-linux-x86-64.so.2 --help
Subdirectories of glibc-hwcaps directories, in priority order:
x86-64-v4 (supported, searched)
x86-64-v3 (supported, searched)
x86-64-v2 (supported, searched)
Надпись (supported, searched)
означает, что ваша система готова работать с этими наборами инструкций.
Казалось бы, удобно. Бери самый высокий поддерживаемый уровень и получай максимум производительности. Но здесь мы полностью и безоговорочно согласны с мнением человека, который знает о железе и системном программировании больше, чем кто-либо другой.
Посмотрите на это письмо от Линуса Торвальдса, создателя Linux. Это не просто мнение, это приговор.

Давайте разберем, почему он так категоричен, и почему мы разделяем его позицию на 100%.
1. Это искусственная и неофициальная модель.
Линус пишет: "The whole "v2", "v3", "v4" etc naming seems to be some crazy glibc artifact... as far as I can tell, the "microarchitecture levels" garbage... is's entirely unofficial".
Эти уровни — не стандарт Intel или AMD. Это внутренняя классификация, придуманная разработчиками glibc
для своих нужд. Пытаться сделать ее универсальным стандартом — значит строить дом на чужом, шатком фундаменте.
2. Линеаризация возможностей процессора — это фундаментально неверно.
"Trying to linearize those bits is technically wrong, since these things simply aren't some kind of linear progression."
Архитектура процессора — это не лестница, где каждая следующая ступенька включает в себя все предыдущие. Это сложное дерево возможностей. Процессор может поддерживать инструкцию из "v3" (например, AVX2
), но не иметь какой-то другой, более старой. Попытка втиснуть это многообразие в жесткие, линейные уровни — это самообман. Модель сломана в своей основе.
3. Это "упрощение", которое на самом деле всё усложняет.
Это ключевой аргумент Линуса: "And worse, it's a "simplification" that literally adds complexity. Now instead of asking "does this CPU support the cmpxchgb16 instruction?", the question instead becomes "what the hell does 'v3' mean again?"
Вместо прямого и честного вопроса к оборудованию ("Поддерживаешь ли ты X?"), разработчик вынужден обращаться к непрозрачной, искусственной таблице и вспоминать, что же именно скрывается за меткой v3
. Это путь к ошибкам, путанице и неоптимальным решениям.
Наш подход: Инженерная ��равда вместо хрупких абстракций
Правильный путь, о котором говорит Линус, — это ориентироваться на CPUID биты. Это механизм, с помощью которого процессор сам сообщает, какие наборы инструкций (ISA sets
) он поддерживает. Это единственный источник правды.
Поэтому в AsmX G3 мы не будем играть в эти уровни. Наша стратегия — дать разработчику возможность явно указывать, какие наборы инструкций он хочет использовать: SSE2
, AVX
, AVX512
, BMI2
и так далее. Это прозрачно, точно и напрямую отражает возможности железа.
Если в будущем появится SSE6
, он станет доступен на новых процессорах как новый, отдельный набор инструкций. Пытаться "втиснуть" его в существующую иерархию уровней было бы абсурдом.
Мы делаем компилятор для инженеров, которые ценят точность. Поэтому мы заканчиваем эту главу, цитируя финал того самого письма:
«So no. We are NOT introducing that idiocy in the kernel.»
И мы говорим то же самое:
Так что нет. Мы НЕ вводим этот идиотизм в наш компилятор.
Изменения в TAPI: Более гибкий парсинг командной строки
TAPI — это наш внутренний парсер аргументов терминала, который лежит в основе обработки всех флагов и команд. В v29 мы значительно улучшили его, сделав более удобным и устойчивым к ошибкам. Вот ключевые изменения:
Поддержка дефисов в длинных флагах. Раньше для длинных опций использовался символ
@
(например,--llvm@version
). Теперь мы перешли на стандартный подход с дефисами:--llvm-version
. Это делает CLI более интуитивным и совместимым с другими инструментами, такими какgcc
илиclang
. Внутренняя логика TAPI адаптирована под это: флаги очищаются от префиксов (--
) и заменяются на подчеркивания для нормализации (например,--llvm-version
становитсяllvm_version
).Добавлена обработка неизвестных флагов. Если флаг не распознан, TAPI теперь выбрасывает явную ошибку:
asmx: error: unrecognized command-line option ‘--unknown-flag’
. Это помогает отлавливать опечатки на ранних этапах и предотвращает тихие сбои.-
Новые флаги для удобства и отладки:
--emergency-panic
: Включает режим аварийной паники при ошибках. Если компилятор завершается с неясной причиной, выводится полный стек-трейс и диагностика. Полезно для баг-репортов: отправьте это в issues (если они открыты), но укажите детали и скриншоты.-q
/--quiet
: Подавляет все выводы, кроме сообщений отLLVM.js
. Идеально для автоматизации или когда нужен чистый результат без логов.-a
/--aliases
: Выводит список доступных алиасов (например, для архитектур:x86_64
→x86-64
,x64
,intel64
,amd64
). Полезно для быстрой справки.--help=llvm
: Отображает только флаги, связанные с LLVM (например,--llvm-version
,--llvm-dumpversion
,--llvm-repository
).--help=common
: Показывает общие опции.--help=package
: Выводит флаги для упаковки (подробнее ниже).--export-json-isa
: Экспортирует набор инструкций (ISA) в JSON-файл для выбранной архитектуры. Полезно для анализа или интеграции с другими инструментами.
Эти изменения делают TAPI более зрелым: теперь он не только парсит, но и валидирует ввод, снижая вероятность ошибок.
Изменения в проекте и kernel: Стабильность и новые возможности
Ядро компилятора (kernel.js
) получило значительные улучшения для лучшей производительности и удобства. Мы фокусируемся на практических вещах, которые упрощают жизнь разработчикам, которые ценят контроль.
JournalService: Новый менеджер логов. Это как упрощенный
journalctl
для AsmX. Он классифицирует сообщения (error, warn, info и т.д.) и позволяет контролировать вывод. Поддерживает эмодзи-префиксы для визуальной ясности (✔ для успеха, ⚠ для предупреждений). В тихом режиме (--quiet
) подавляет все, кроме критичного. Пока не контролирует выводыLLVM.js
, но это в планах. Представьте: вместо хаоса в терминале — структурированный лог, где ошибки подсвечены красным, а успехи — зелёным. Это инструмент для отладки.Улучшенный
--dumpversion
. Теперь выводит полную версию с ревизией:Version: v29 (rev 1.0)
. Полезно для трекинга обновлений в скриптах или CI/CD.Расширенная информация о CPU. При запуске компилятор выводит точные данные: архитектуру (например,
amd64-unknown-linux-gnu
) и микроархитектуру (например,Meteor Lake
для Intel 14-го поколения). Мы парсимos.cpus()
и сопоставляем с известными поколениями процессоров. Это помогает в отладке: "Ага, на Raptor Lake код работает быстрее благодаря AVX-512". Нет предположений — только факты от железа.Переход на
--target
вместо--march
. Для указания архитектуры теперь используйте--target amd64
(или алиасы вродеx86_64
). Это более стандартный термин, как вclang
. Старый флаг удален для чистоты кода — меньше путаницы, больше скорости.Общий дефолтный вывод для всех бэкендов. Теперь имя выходного файла по умолчанию —
a.out
для всех архитектур (раньше зависело от бэкенда). Логика вынесена в kernel:const outname = terminal_arguments.objname || GVE.GCR_DEFAULT_OUTPUT_FILENAME_FOR_ALL_BACKENDS;
. Это унифицирует поведение — компилируй на amd64 или в будущем на arm64, результат предсказуем.Новый слой:
__asmx_prepare_pipeline_factory_fn
. Это пайплайн для обработки флагов: заменяет алиасы (например,x64
→amd64
), проверяет наличие бэкендов и пакетов в директориях./backend/targets
и./backend/packages
. Если архитектура или тип пакета не поддерживается, ошибка с подсказкой:Server.journal.error("The ${pair_v} architecture is not supported");
. Код используетfs.readdirSync
для сканирования иaliases.getTargetAlias
для нормализации. В будущем — рефакторинг: разбить на модули.Счетчик предупреждений и ошибок. Теперь в конце компиляции выводится:
0 Warnings, 0 Errors.
(или актуальные числа). Реализовано черезJournalService
:this.count_warnings += 1;
вthrow_warning()
, иprintWarningStats()
. Пока это в kernel иZGEN
; в JITC добавим позже.
Революция в дистрибуции: Как AsmX научился упаковывать код в .deb пакеты — и почему это меняет всё

Это то событие, которое для меня как прорыв в космос. Помните, как SpaceX впервые посадила Falcon 9? Вот так же и здесь: AsmX G3 v29 не просто компилирует код — он упаковывает его в полноценные .deb
пакеты, готовые к установке на Ubuntu, Debian, Mint и другие. Это не фича на полке; это мост от сырых бинарников к реальному миру дистрибуции. Я просидел над этим неделями, разбирая форматы архивов, скрипты и зависимости. И это круто, потому что решает проблему: "Скомпилировал — а как распространить?" Теперь просто: скомпилируй, упакуй, установи через dpkg
. Без лишних инструментов, прямо из AsmX.
Давайте разберём это как инженеры: шаг за шагом, от формата .deb
до нашего кода. Я объясню, как работает .deb
под капотом, почему мы выбрали именно этот подход, и покажу иллюстрации структур. Без пафоса — просто факты и код, чтобы вы могли повторить или улучшить.
Почему .deb? И почему именно сейчас?
.deb
— это стандарт для Debian-based систем, которые доминируют в серверах и десктопах (Ubuntu — 30% рынка Linux). Формат простой, но мощный: позволяет встраивать зависимости, скрипты, иконки и даже desktop-интеграцию. Мы начали с него, потому что он решает 80% случаев: от простых утилит до приложений с GUI. В будущем добавим другие типы пакетов, но .deb
— это база.
В AsmX мы реализовали это в ./backend/packages/deb/builder.cjs
и драйвере ./backend/packages/driver.cjs
. Нет зависимостей от dpkg-deb
или fakeroot
— всё на чистом Node.js с fs
, zlib
и crypto
. Почему? Чтобы AsmX работал везде, даже без Debian-tools. Это даёт контроль: мы генерируем пакеты на Windows или macOS для Linux-целей.
Как устроен .deb-пакет: Разбор формата от А до Я

.deb
пакетаДавайте нырнем в технические детали. Я не люблю поверхностные объяснения — они как ракеты без топлива: выглядят круто, но не взлетают. Поэтому разберём формат .deb
шаг за шагом, с примерами кода из нашего проекта и иллюстрациями структур. Это не академический трактат, а инженерный гид: вы сможете взять это и реализовать сами, если захотите.
.deb
— это не просто ZIP с метаданными. Это ar-архив (да, тот самый формат от Unix, используемый в библиотеках вроде .a
), содержащий ровно три файла:
debian-binary: Текстовый файл с версией формата (всегда "2.0\n"). Это маркер, чтобы инструменты вроде
dpkg
знали, что перед ними валидный.deb
. Вar
-архиве файл должен называться точноdebian-binary
(без расширений).control.tar.gz: Сжатый
tar
-архив с метаданными пакета. Здесь контрольные файлы:control
(описание пакета), скрипты вродеpostinst
(что делать после установки) иpostrm
(после удаления).
data.tar.gz: Сжатый
tar
-архив с самими данными — вашим исполняемым файлом, иконками, desktop-файлами и всем остальным.
Посмотреть содержимое control
можно:
$ dpkg -f myapp_1.0.0_amd64.deb
Package: myapp
Version: 1.0.0
Architecture: amd64
Maintainer: AsmX Developer
Description: An application created with the AsmX compiler.
Section: devel
Priority: optional
Installed-Size: 2
Depends: libc6
Структура выглядит так (ASCII-арт для ясности):
.deb (ar-архив)
├── debian-binary (Buffer: '2.0\n')
├── control.tar.gz (gzip(tar(DEBIAN/)))
│ └── DEBIAN/
│ ├── control (метаданные: имя, версия, зависимости)
│ ├── postinst (опционально: скрипт после установки)
│ └── postrm (опционально: скрипт после удаления)
└── data.tar.gz (gzip(tar(файлы приложения/)))
├── usr/
│ ├── bin/ (исполняемый файл)
│ ├── share/
│ │ ├── applications/ (.desktop файл)
│ │ └── icons/... (иконка .png)
└── ...
Почему ar
? Потому что он простой: последовательность файлов с заголовками, без сжатия. Это позволяет быстро извлекать части без распаковки всего. В AsmX мы генерируем это в createArArchive
из builder.ts
:
async function createArArchive(
outputPath: string,
files: { name: string; content: Buffer }[]
): Promise<void> {
let arContent = Buffer.from('!\n'); // Магический заголовок ar
for (const file of files) {
const header = Buffer.alloc(60); // Заголовок 60 байт
header.write(file.name.padEnd(16), 0); // File identifier
// File modification timestamp
header.write(Math.floor(Date.now() / 1000).toString().padEnd(12), 16);
header.write('0'.padEnd(6), 28); // Owner ID
header.write('0'.padEnd(6), 34); // Group ID
header.write('100644'.padEnd(8), 40); // File mode
header.write(file.content.length.toString().padEnd(10), 48); // File size
header.write('\x60\n', 58); // Ending characters
arContent = Buffer.concat([arContent, header, file.content]);
if (file.content.length % 2 !== 0) { // Паддинг до чётного размера
arContent = Buffer.concat([arContent, Buffer.from('\n')]); // Padding
}
}
await fs.writeFile(outputPath, arContent);
}
Этот код — сердце упаковщика. Мы создаём буфер для заголовка (фиксированные позиции полей — классика Unix), конкатенируем с контентом и добавляем паддинг (ar требует чётные размеры). Нет внешних библиотек — чистый Node.js для портативности.
Теперь разберём ar-архив подробнее. Он начинается с магической строки !\n
(8 байт). Затем — последовательность файлов, каждый с 60-байтным заголовком:
Offset |
Length |
Name |
Format |
---|---|---|---|
0 |
16 |
Имя файла (паддинг пробелами до 16) |
ASCII |
16 |
12 |
Timestamp (секунды с эпохи, строкой, паддинг пробелами) |
Decimal |
28 |
6 |
Owner ID |
Decimal |
34 |
6 |
Group ID |
Decimal |
40 |
8 |
Mode (восьмеричное, как в chmod) |
Octal |
48 |
10 |
Размер файла (bytes) |
Decimal |
58 |
2 |
Ending characters |
|
Можем посмотреть ar
заголовок:
$ dd if=myapp_1.0.0_amd64.deb bs=1 count=68 2>/dev/null | hexdump -C
00000000 21 3c 61 72 63 68 3e 0a 64 65 62 69 61 6e 2d 62 |!.debian-b|
00000010 69 6e 61 72 79 20 20 20 31 37 35 36 39 39 34 36 |inary 17569946|
00000020 30 30 20 20 30 20 20 20 20 20 30 20 20 20 20 20 |00 0 0 |
00000030 31 30 30 36 34 34 20 20 34 20 20 20 20 20 20 20 |100644 4 |
00000040 20 20 60 0a | `.|
00000044
Объяснение команды:
dd if=myapp_1.0.0_amd64.deb
: Указываеn входной файл.bs=1
: Устанавливает размер блока в 1 байт.count=68
: Указывает, что нужно прочитать 68 байтов. (8 байтов с magic и 60 байтов сам заголовок)2>/dev/null
: Игнорирует сообщения об ошибках, если они есть.| hexdump -C
: Передает вывод вhexdump
для отображения в шестнадцатеричном и ASCII формате.
После заголовка — контент файла, затем паддинг \n
если размер нечётный. Всё последовательно — никаких индексов или деревьев. Простота = надёжность.
В AsmX мы вызываем это так:
await createArArchive(outputPath, [
{ name: 'debian-binary', content: debianBinary },
{ name: 'control.tar.gz', content: controlTarGz },
{ name: 'data.tar.gz', content: dataTarGz }
]);
Это генерирует валидный .deb
, который dpkg -i
примет без вопросов.
Tar-архив: Фундамент data.tar и control.tar

.tar
archive and .tar.gz
Tar (Tape ARchive) — это контейнер для файлов и директорий, без сжатия. В .deb
мы используем USTAR-вариант (POSIX-стандарт). Каждый файл в tar
имеет 512-байтный заголовок, за которым следует контент (паддинг до 512-байтных блоков).
Field |
Size (bytes) |
Byte Offset |
Description |
---|---|---|---|
|
100 |
0 |
File name |
|
8 |
100 |
File permissions |
|
8 |
108 |
User ID |
|
8 |
116 |
Group ID |
|
12 |
124 |
File size in bytes |
|
12 |
136 |
Modification time (UNIX timestamp) |
|
8 |
148 |
Header checksum |
|
1 |
156 |
File type (e.g., regular file, directory) |
|
100 |
157 |
Name of linked file (if symbolic link) |
|
6 |
257 |
Format identifier (e.g., |
|
2 |
263 |
Format version ( |
|
32 |
265 |
User name |
|
32 |
297 |
Group name |
|
8 |
329 |
Major device number (if special file) |
|
8 |
337 |
Minor device number (if special file) |
|
155 |
345 |
Prefix for file name (for long file names) |
|
12 |
500 |
Padding to make the header 512 bytes |
Чек-сумма вычисляется суммируя все байты заголовка (заменяя поле суммы на пробелы) и записывая как восьмеричное число. В нашем коде (tar-utils
):
function calculateTarChecksum(header: Buffer): number {
let sum = 0;
for (let i = 0; i < 512; i++) {
if (i >= 148 && i < 156) {
sum += 32; // Spaces in checksum field
} else {
sum += header[i];
}
}
return sum;
}
Для создания tar
мы сканируем директорию (FsUtils.getAllFiles
), и строим последовательность: заголовок + контент + паддинг. В конце — два нулевых блока (1024 байта) для завершения.
export async function createTar(
sourceDir: string,
excludeDirs: string[] = []
): Promise<Buffer> {
const files = await FsUtils.getAllFiles(sourceDir, excludeDirs);
let tarContent = Buffer.alloc(0);
for (const file of files) {
const relativePath = path.relative(sourceDir, file).replace(/\\/g, '/');
const stats = await fs.stat(file);
const content = await fs.readFile(file);
const header = createTarHeader(relativePath, stats.size, stats.mode);
tarContent = Buffer.concat([tarContent, header, content]);
const padding = 512 - (content.length % 512);
if (padding < 512) {
tarContent = Buffer.concat([tarContent, Buffer.alloc(padding)]);
}
}
tarContent = Buffer.concat([tarContent, Buffer.alloc(1024)]);
return tarContent;
}
Это создаёт raw tar. Затем сжимаем в gz.
Сжатие: .tar.gz с помощью zlib
Gz — это gzip-сжатие, стандарт для Unix. Мы используем встроенный zlib.gzip
в Node.js:
export function gzip(data: Buffer): Promise<Buffer> {
return new Promise((resolve, reject) => {
zlib.gzip(data, (err, result) => {
if (err) return reject(err);
resolve(result);
});
});
}
// В builder
const controlTar = await createTar(debianDir);
const controlTarGz = await gzip(controlTar);
Gzip добавляет заголовок (10 байт: магический ID, метод сжатия и т.д.), сжатые данные (DEFLATE) и футер (CRC32 + размер). Мы не углубляемся в DEFLATE (это LZ77 + Huffman), но важно: это lossless, быстрое и эффективное для текстов/бинарников.
Как AsmX строит .deb: Обзор builder и driver

.deb
file В AsmX процесс создания .deb
-пакета реализован через два ключевых модуля: driver (driver.ts
) и DebBuilder (builder.ts
). Это не просто обёртка над dpkg-deb
, а полноценный генератор пакетов, работающий на чистом Node.js без внешних зависимостей. Давайте разберём, как это устроено, шаг за шагом, с примерами кода и пояснениями.
Роль driver
driver.ts
— это точка входа, которая обрабатывает аргументы командной строки, проверяет окружение и координирует сборку. Он отвечает за:
Проверку окружения: Убеждается, что сборка выполняется на Linux (требование для
.deb
), проверяет наличиеldd
для анализа зависимостей ELF.Парсинг аргументов: Собирает флаги вроде
--package-name
,--package-version
,--package-icon
и передаёт их вDebBuilder
.Анализ зависимостей: Использует
ldd
для динамических библиотек или fallback на статические сборки.Вызов DebBuilder: Передаёт конфигурацию и запускает процесс упаковки.
Роль DebBuilder
DebBuilder
(builder.ts
) — это рабочая лошадка, которая формирует .deb
-пакет. Она:
Создаёт временную директорию: Использует
FsUtils.createTempDirectoryRecursive
для изоляции.-
Генерирует структуру:
Копирует бинарник в
usr/bin/
.Создаёт
.desktop
-файл (если--package-desktop
).Копирует иконку в
usr/share/icons/hicolor/
(если--package-icon
).Формирует
DEBIAN/control
и скрипты (postinst
,postrm
).
-
Строит архивы:
control.tar.gz
с метаданными.data.tar.gz
с файлами приложения.ar
-архив для финального.deb
.
Чистит за собой: Удаляет временные файлы.
Ключевые моменты
Размер пакета:
calculateInstalledSize
рекурсивно суммирует размеры файлов вdataDir
(в байтах, потом делим на 1024 дляInstalled-Size
в KB).Права файлов: Бинарники —
755
(rwxr-xr-x), остальные —644
(rw-r--r--).Зависимости: Автоматически определяются через
ldd
. Если бинарник статический,Depends
остаётся пустым.Имена файлов: Валидируются regex’ами (
^[a-z0-9][a-z0-9.-]*$
для имени,\d+\.\d+\.\d+
для версии).
Пример вызова
asmx main.asmx --release --target amd64 -o myapp --package \
--package-type deb \
--package-name my-application --package-version 1.0.0 \
--package-description "My awesome app" --package-author "Dev <dev@example.com>" \
--package-icon icon.png --package-desktop
Вывод: my-application_1.0.0_amd64.deb
, готовый к установке через dpkg -i
.
Флаги для пакетов в AsmX

AsmX предоставляет набор флагов командной строки для настройки .deb
-пакетов, позволяя гибко задавать метаданные, GUI-интеграцию и зависимости. Эти флаги обрабатываются в driver.ts
и передаются в DebBuilder
для формирования пакета. Вот полный разбор флагов, их функциональности и примеров использования.
Name |
Type |
Description |
---|---|---|
|
bool |
Включает режим упаковки. Без него AsmX только компилирует бинарник |
|
string |
Указывает тип пакета ( |
|
string |
Имя пакета. Должно соответствовать regex |
|
string |
Версия пакета. Требуется формат |
|
string |
Описание пакета для |
|
string |
Имя и email автора для |
|
path |
Путь к иконке (.png, рекомендуется 256x256). Копируется в |
|
bool |
Создаёт .desktop-файл для GUI-меню в |
Как флаги обрабатываются
Флаги парсятся в driver.ts
с помощью TAPI (Terminal Argument Parser Interface) и формируют объект DebConfig
:
export interface DebConfig extends BasePackageConfig {
type: 'deb';
deb: {
maintainer?: string;
section?: string;
priority?: string;
depends?: string[];
suggests?: string[];
conflicts?: string[];
replaces?: string[];
postinst?: string;
postrm?: string;
};
}
Валидация:
--package-name
: Проверяется через/^[a-z0-9][a-z0-9.-]*$/
. Имя не должно начинаться или заканчиваться точкой/дефисом, чтобы соответствовать стандартамdpkg
.--package-version
: Требуется формат/^\d+\.\d+\.\d+$/
. В будущем возможно расширение до поддержки версий вида1.0.0-1
или1.0.0~beta1
.
Подводные камни
Имя пакета:
dpkg
отклонит пакет, если имя содержит заглавные буквы или нарушает формат. Например,MyApp
недопустимо — используйтеmyapp
илиmy-app
.Иконка: Должна быть
.png
, желательно256x256
. Некорректный формат или размер может привести к тому, что GNOME/KDE не отобразят иконку.Версия: Формат
\d+\.\d+\.\d+
обязателен. Неверный формат (например,1.0
) вызовет ошибку валидации.
AsmX G3 как AUR-пакет

Мы рады объявить, что asmx-g3-git
теперь доступен в Arch User Repository (AUR)! Это важный шаг для интеграции AsmX в экосистему Arch Linux, позволяя пользователям устанавливать и обновлять наш компилятор через стандартные инструменты, такие как yay
или paru
. Пакет asmx-g3-git
предоставляет последнюю версию из Git-репозитория, включая все новейшие фичи и исправления.
Что такое AUR и почему это важно?
AUR — это сообщественный репозиторий для Arch Linux, где пользователи публикуют PKGBUILD-скрипты для сборки и установки программ. Публикация asmx-g3-git
, asmx-stable
и asmx-official
в AUR делает компилятор доступным для широкой аудитории, упрощая установку и обновление без необходимости ручного клонирования репозитория или настройки окружения. Это шаг к тому, чтобы AsmX стал частью повседневного инструментария разработчиков на Arch-based системах.
Доступные пакеты
asmx-g3-git
: Bleeding-edge версия, основанная на последнем состоянии Git-репозитория (https://github.com/AsmXFoundation/AsmX-G3.git
). Подходит для разработчиков, которые хотят тестировать новейшие фичи, такие как поддержка.deb
-пакетов, улучшенный TAPI.asmx-stable
: Стабильная версия, привязанная к конкретным релизам (+v29-rev1.0
). Рекомендуется для пользователей, которым нужна надёжность в проектах, где стабильность важнее экспериментов.asmx-official
: Официальная версия, поддерживаемая командой AsmX. Может включать дополнительные проверки качества, документацию или оптимизации для продакшен-окружений. Идеальна для enterprise-пользователей или тех, кто хочет гарантированную совместимость.
Как установить пакеты
Убедитесь, что у вас установлен AUR-хелпер, например
yay
илиparu
.-
Выполните команду:
yay -S asmx-g3-git # Для bleeding-edge версии yay -S asmx-stable # Для стабильной версии yay -S asmx-official # Для официальной версии
paru -S asmx-g3-git
paru -S asmx-stable
paru -S asmx-officialИли, если используетеparu
:paru -S asmx-g3-git paru -S asmx-stable paru -S asmx-official
-
Пакет автоматически:
Скачает исходный код из репозитория https://github.com/AsmXFoundation/AsmX-G3.git.
Установит зависимости (
nodejs
,bash
,npm
,jq
,typescript
).Компилирует проект с помощью
npm run build
(дляasmx-g3-git
) или использует готовые бинарники (дляasmx-stable
иasmx-official
).Установит бинарник
asmx
в/usr/bin/
и документацию в/usr/share/doc/asmx-g3-git/
.
Что делает PKGBUILD
PKGBUILD для asmx-g3-git
обеспечивает чистую и надёжную установку:
Источник: Клонирует Git-репозиторий AsmX (
git+
https://github.com/AsmXFoundation/AsmX-G3.git
).-
Зависимости:
Для работы:
nodejs
,bash
.Для сборки:
git
,npm
,jq
(для обработки package.json), typescript.
-
Сборка:
Устанавливает локальные зависимости для разработки (
typescript
,@types/node
).Выполняет
npm install --ignore-scripts
для минимизации лишних действий.Компилирует проект через
npm run build
.
-
Установка:
Копирует модуль в
/usr/lib/node_modules/asmx-g3/
.Создаёт симлинк
/usr/bin/asmx
для удобного вызова.Устанавливает корректные права (755 для бинарника, 644 для остальных файлов).
Чистит
package.json
от внутренних npm-полей (с помощьюjq
) и ссылок на временные пути.Устанавливает документацию (
README.md
) в/usr/share/doc/asmx-g3-git/
.
Версия: Формируется динамически через Git:
r<количество коммитов>.<короткий хэш>
(например,r17.c89a3ce
).
Преимущества
Удобство: Установка через AUR интегрирует AsmX в систему, делая его доступным из терминала командой
asmx
.Выбор: Три пакета (
asmx-g3-git
,asmx-stable
,asmx-official
) дают гибкость — от экспериментов до продакшена.Обновления: AUR-хелперы отслеживают новые коммиты (
asmx-g3-git
) или релизы (asmx-stable
,asmx-official
), упрощая обновления.Сообщество: Публикация в AUR привлекает Arch-пользователей, расширяя аудиторию и собирая обратную связь.
Подводные камни
Git-версия:
asmx-g3-git
— это bleeding-edge, поэтому возможны нестабильные изменения. Для надёжности выбирайтеasmx-stable
илиasmx-official
.Зависимости: Убедитесь, что
nodejs
,npm
иtypescript
обновлены до последних версий, чтобы избежать ошибок сборки. Также требуетсяjq
для обработкиpackage.json
.AUR-хелперы: Используйте проверенные инструменты (
yay
,paru
) для надёжной установки.Права: Если симлинк
/usr/bin/asmx
не работает, проверьте права на/usr/lib/node_modules/asmx-g3/bin/asmx
(должно быть 755).Выбор пакета: Если вы не уверены, какой пакет выбрать, начните с
asmx-stable
для баланса между новыми фичами и надёжностью.
Как внести вклад
AUR-пакет — это открытый проект. Если вы нашли баг или хотите улучшить PKGBUILD, создайте issue или pull request на странице AUR или в репозитории AsmXFoundation/AsmX-G3
. Мы ценим вклад сообщества!
Заключение
AsmX G3 v29 — это не просто обновление, а эволюционный скачок. Мы не только улучшили ядро компилятора, добавив стабильность и новые возможности, но и сделали огромный шаг в сторону дистрибуции. Поддержка .deb
-пакетов позволяет превратить ваш код в полноценное приложение, готовое к установке на Debian-based системах. Публикация трёх пакетов в AUR — asmx-g3-git
для экспериментаторов, asmx-stable
для надёжных проектов и asmx-official
для продакшена — открывает AsmX для Arch-сообщества и упрощает установку, делая AsmX частью экосистемы Linux.
Мы остаёмся верны нашей философии: полный контроль, никаких чёрных ящиков, максимальная производительность. Отказ от устаревших 32-битных систем и искусственных микроархитектурных уровней (v2
, v3
, v4
) в пользу прямого использования CPUID — это наш ответ на вызовы современности. Мы строим инструмент для инженеров, которые ценят точность и готовы брать на себя ответственность за свой код.
Но это не конец. Впереди — поддержка новых форматов пакетов. AsmX — это проект для тех, кто смотрит в будущее. Код открыт, AUR-пакет доступен, сообщество растёт. Ждём ваших идей, отправляйте баг-репорты. Мы не ждём одобрения — мы строим. Присоединяйтесь к нам, и давайте создадим будущее вместе.
Комментарии (6)
Shermike
05.09.2025 05:26Если речь о высокоуровневых оптимизациях, таких как формы
SSA
(Static Single Assignment), то на уровне ассемблера они просто неуместны.SSA
- это не оптимизация, а просто популярная форма IR.А вообще, у меня складывается ощущение, что это какой-то троллинг. Трудно поверить, чтобы кто-то это все делал всерьез. Например, какой смысл уделять время такой нерелавантой тут вещи, как парсер командной строки, зачем тут генерация deb пакета и тд? Это все такое вторичное в контексте проекта компилятора.
Ну и наконец зачем делать сотни пустых коммитов в репозитории:)
eugenk
Бред какой-то...