Здравствуйте, коллеги-разработчики! Я Максим, и я хочу поделиться новостью из мира C++. Я смог в 15 лет собрать Clang, LLD, LLDB, clang-extra-tools нативно в Windows, и оно работает. Но начнем мы издалека: как я вообще выбрал C++; почему не остался на MSVC, G++; как я собрал LLVM; почему не скачал уже готовые сборки от Мартина Сторшё.

Дисклеймер

Эта статья — прежде всего история моего пути, борьбы с ошибками и выбора инструментов. Если вас интересуют только технические детали, скрипты сборки и мой fix LLDB переходите на GitHub там все описано — клик

Доказательство что LLVM работает
Доказательство что LLVM работает

С чего всё началось?

Мой путь в IT начался с «железа». В 2020 году на старом отцовском ПК отвалился чип видеокарты. Денег на новую не было, и я три года копил со школьных обедов на новый конфиг. К 13 годам, цель была достигнута, но со временем мне стало не интересно просто играть — захотелось создавать свое.

Первым делом я пошел по советам из интернета в Python. Всё было отлично, пока я не начал писать код, от которого падал интерпретатор, а ИИ того времени (начало 2023) не мог внятно объяснить почему. Попробовал Java, но быстро устал от многословности и бесконечных абстракций.

В итоге я пришел к C++. Мне понравилось то что на нем пишут всё: от операционных систем до AAA-игр. Установил MSVC и начал разбираться.

Почему не остался на MSVC/GCC?

В какой-то момент я задумался: MSVC крут, но весит 20+ ГБ, он закрытый, и я вечно боялся найти в лицензии какой-нибудь пункт мелким шрифтом о том, что я стану должен Microsoft, если сделаю что-то серьезное.

Начал искать замену. Сначала был GCC от WinLibs. Вроде всё ок, но чем больше я копал, тем больше бесила топорность GDB и страшные ошибки G++, которые приходилось постоянно гуглить. А потом я попробовал Clang — и это был кайф! Удобно, как в MSVC, но при этом лицензия даже свободнее, чем у GCC.

Но была проблема: в готовых сборках WinLibs версия LLVM отставала. У меня стояла 19-я, а в мире была 21-я. Я ждал но понял что дальше не будет и решил что соберу свежайший LLVM сам. Так я скачал MSYS2 и начал свои первые попытки.

Как я собрал Clang?

Как я уже написал, я начал гуглить и спрашивать у ИИ, как собрать LLVM. Мой первый конфиг был очень простой и наивный: я думал, что LLVM просто и быстро заработает. К моему удивлению, оно заработало с первой попытки, но конфиг был очень примитивный: я включил только clang и lld, так как больше ничего не хотел.

Со временем я понял, что хочу собрать LLVM Runtimes и уйти от GNU Runtimes, и вот тут начались проблемы. Самая первая и бесячая моя ошибка - LLD не мог импортировать символы. Я очень долго разбирался, почему же так происходит. Пробовал модифицировать конфиги очень по-разному, но это не помогало. И в один момент я просто случайно нашел решение: оказалось, что нельзя линковать статичные и динамичные либы вместе. На это я потратил от 1 до 2 месяцев. Я уже думал сдаться на этом моменте, но решил: либо я LLVM, либо я LLVM - и продолжил работу.

Через время я смог сделать LLVM Runtimes, но появилась новая ошибка, которую я не мог распознать. Со временем до меня дошло, что C++ использует C Runtimes, а locale.h - это часть Lib C. Я начал гуглить и искать, наткнулся на статью, где говорилось, что MSCRT старое и использовать его не надо, а вот UCRT — новое, и надо использовать именно его. Я начал искать MinGW UCRT, и да, я был прав — оно есть и даже работает прекрасно без «танцев с бубном».

Позже я захотел LLDBи ClangD. Будь я нормальным человеком, я бы просто скачал ClangD, но нет — я решил его собрать. На удивление, clang‑extra‑tools (частью которого является ClangD) работает прекрасно. А вот с LLDB была проблема: он падал на MainLoopWindows.cpp. Я спросил у ИИ, хотя был настроен скептично и думал, что придется разбираться и руками модифицировать код. НО он с первой попытки выдал полностью рабочий код!

Я удивился «Странно, обычно ИИ дает что-то не то, а тут даже докопаться нельзя». Я хотел уже выдать себя за гения, который портировал LLDB на MinGW-UCRT, но чувствовал что-то не то. Мне казалось, что ИИ украл откуда-то этот код, потому что не бывает таких идеальных совпадений. И знаете что? Я был прав! Он взял этот код из LLVM 22 (на 22.12.2025 это экспериментальная ветка).

У меня были смешанные эмоции. С одной стороны — я был прав, с другой — если я опубликую этот код как свой, то это — карма на всю жизнь. И я решил удалить любые упоминания, что код мой. Но пока я удалял упоминания, заметил, что можно добавить std::mutex, и подумал: с одной стороны — там работают умные люди и они бы не упустили такое, с другой — они же тоже люди и могли не заметить или не подумать.

В итоге я решил прогнать тесты и сборку. Результаты тестов ninja check-lldb вы можете посмотреть на фото ниже.

PowerShell - ninja check-lldb
PowerShell - ninja check-lldb
PowerShell - ninja check-all
PowerShell - ninja check-all
MSYS2 - ninja check-lldb
MSYS2 - ninja check-lldb
MSYS2 - ninja check-all
MSYS2 - ninja check-all

Но я подумал: а если тесты слишком «сухие» и на реальной работе это скажется? Я попросил ИИ сделать какой-нибудь супернавороченный код с Atomic, Threads, Vector, и LLDB с этим тоже справился. На мое удивление, даже не было ничего страшного, потому я оставил мой вариант кода (кто шарит - можете проверить и написать, я, как и говорил, новичок, поэтому буду рад экспертному мнению).

Почему не готовые варианты?

Пока я гуглил, как собрать, не раз натыкался на сборки Мартина Сторшё, известного в мире как mstorsjö. Я смотрел на его сборки, но проблема в том, что он очень сильно модифицирует исходники и собирает их из‑под Linux (могу ошибаться, но сайты, которые я смотрел, говорили про Linux). Любой, кто использует его сборки, может сказать, что они отлично работают, и вообще — какая разница, меняет он код или нет?

На что я отвечаю: допустим, он гений программирования, но он один. А в LLVM — 50 хороших программистов (условно). Пока он один будет сам себя проверять и сам писать, команда LLVM будет писать 50 разных частей, потому что каждый пишет свое. Плюс каждый сможет оценить работу своего коллеги и заметить ошибку, о которой знал только он. И что немаловажно: проект mstorsjö популярен в кругах MinGW, а не глобально. Инженеру на Linux/MacOS вообще все равно на MinGW, а в глобальном проекте огромная посещаемость и шанс, что кто‑то что‑то заметит, куда выше.

Заключение

Начал я свою работу 1 сентября 2025 года и надеялся, что максимум это займет пару дней. Но в итоге это переросло в нечто большее, на что я потратил около 3.8 месяца. Собралось оно у меня ровно так, как я обещал в самом начале статьи, только к 19 декабря 2025 года. Работал я по 3-5 часов (как я писал, я шк��льник, поэтому работал, когда мог, и предпочитал не играть, а работать).

Надеюсь, вам понравилось и вы оцените мой труд. Кому интересно — вот ссылка на репозиторий.

-----------------------------------------------------------------------------------------------------------------------------------
Список правок (Как я упоминал я новичок и потому учусь на ходу)
Правка 1 - Сократил вступление (Биографию, Почему именно Clang выбрал);Добавил дисклеймер; уточнил что скрин с тестом из MSYS2 может быть не правильным
Правка 2 - Изменены скриншоты с ninja check (Объяснение - MSYS2 не правильно вызывал ninja check)