При использовании MinGW легко нарваться на DLL-ад, то есть ваша программа не запускается, потому что она либо не находит необходимые библиотеки DLL, либо находит их несовместимые версии.
Это может проявляться как:
Как это исправить?
(This is intended as a canonical duplicate on this topic.)





Для запуска вашей программы требуется несколько .dll («общих библиотек»). Это либо части стандартной библиотеки (поставляемой вместе с вашим компилятором), либо сторонние библиотеки, которые вы используете.
«выполнение не может быть продолжено, поскольку __.dll не найден» — необходимый .dll не найден ни в одном из нескольких предопределенных путей поиска (см. ниже).
«Точка входа в процедуру… не найдена…» — найдена необходимая .dll, но не правильная ее версия.
Имя файла в сообщении об ошибке может быть отвлекающим маневром, но это не обязательно библиотека-нарушитель.
Приложение не запускается без ошибок — ошибка может не отображаться при запуске с консоли или из IDE. Дважды щелкните файл .exe в проводнике, чтобы увидеть полное сообщение об ошибке, которое будет одним из приведенных выше. (Под «проводником» я имею в виду приложение Windows «Файлы», а не, например, вкладку VSC с тем же именем.)
Вы можете обратиться к руководству, но краткое описание таково: (поиск происходит в таком порядке)
Каталог, в котором находится ваш .exe.
C:\Windows и некоторые его подкаталоги. (⚠️ Никогда не изменяйте и не копируйте там ничего!)
Каталоги в PATH в том порядке, в котором они перечислены. (PATH — это «переменная среды» (системная настройка), содержащая список каталогов, в которых, помимо прочего, осуществляется поиск DLL).
Существует две настройки PATH: общесистемная и для каждого пользователя, первая ищется первой.
Есть несколько вариантов, от самого простого до самого сложного, выбирайте один.
Статическая связь
Добавьте -static к флагам компоновщика. Это делает вашу программу не зависимой от DLL, встраивая их содержимое в исполняемый файл.
Почему это нехорошо?
Ваши пользователи не смогут легко обновить библиотеки до более новых версий, если им это необходимо.
Некоторые библиотеки лицензируются таким образом, что это препятствует. (Например, при использовании лицензии LGPL статическая ссылка требует открытия исходного кода вашего программного обеспечения.)
Запуск из терминала MSYS2 (если вы используете MSYS2)
Терминал MSYS2 автоматически настраивает свой собственный PATH, чтобы в первую очередь была установлена установка компилятора (который включает в себя библиотеки DLL стандартной библиотеки, с которыми у вас, вероятно, есть проблемы).
В меню «Пуск» есть несколько ярлыков MSYS2, и вы ДОЛЖНЫ выбрать правильный (обычно UCRT64 или MINGW64, но прочитайте Что такое среды MSYS2? Как мне выбрать одну?, чтобы знать наверняка).
Хотя это решит вашу проблему, вы не можете ожидать, что ваши пользователи установят MSYS2, поэтому вам следует рассмотреть другие решения в долгосрочной перспективе.
Если это не помогло, вероятно, вы использовали неправильный ярлык MSYS2. Вы также можете ознакомиться с разделом «Чего не следует делать» ниже, в разделе о мусоре в C:\Windows.
Исправьте свой ПУТЬ
Измените свой PATH, чтобы включить каталог с DLL. Обычно это каталог установки компилятора (поскольку там находится его стандартная библиотека), например C:\path\to\MinGW\bin (подставьте свой путь). Если вы используете MSYS2, это будет C:\msys64\ucrt64\bin или C:\msys64\mingw64\bin (читайте Что такое среды MSYS2? Как мне выбрать одну?, чтобы узнать, какой каталог выбрать).
(This only makes sense for the standard library DLLs. For third-party libraries, always copy them next to the executable as explained in (4) below.)
Этот каталог должен быть первым в PATH. В противном случае вы рискуете получить несовместимые версии одних и тех же DLL из предыдущих каталогов.
Существует две настройки PATH: общесистемная и индивидуальная для пользователя. Первый имеет приоритет, поэтому используйте общесистемный PATH.
Хотя это решит вашу проблему, вы не можете ожидать, что ваши пользователи установят MinGW, поэтому вам следует рассмотреть другие решения в долгосрочной перспективе.
Как мне установить PATH?
В настройках введите «env» в поле поиска, нажмите Edit the system environment variables, нажмите Environment Variables... внизу, затем во втором списке под названием System variables дважды щелкните Path, введите свой путь (например, C:\path\to\MinGW\bin) в пустую ячейку внизу, нажмите Move Up несколько раз, чтобы сделать это первой записью, затем нажмите OK во всех открытых диалогах.
Не забудьте перезапустить консоль/IDE после изменения PATH!
Если это не сработало и вы уверены, что все сделали правильно, обратитесь к разделу «Чего не следует делать» ниже, часть о мусоре в C:\Windows.
Скопируйте необходимые библиотеки DLL рядом с исполняемым файлом.
Копирование DLL — лучшее долгосрочное решение. Вам все равно придется это сделать, чтобы распространять свое приложение среди других (это или статическая ссылка, см. выше). В следующем разделе объясняется, как это сделать.
Требуемые библиотеки DLL могут быть упомянуты в сообщении об ошибке, но:
Существуют инструменты, которые сообщат вам список DLL, от которых зависит ваше приложение, например. нтлдд. Оно устарело, но выполняет свою работу.
Примечание. Для этого вам необходимо правильно настроить PATH (см. выше; или запустить его в терминале MSYS2, как описано выше), чтобы вы уже могли запускать свое приложение. И нельзя использовать -static.
Пользователи MSYS2 могут установить ntldd с помощью pacman -S ...-ntldd (например, mingw-w64-ucrt-x86_64-ntldd или mingw-w64-x86_64-ntldd, проконсультируйтесь Что такое среды MSYS2? Как мне выбрать одну?). Если вы не используете MSYS2, загрузите его по ссылке GitHub выше.
Беги ntldd -R my_program.exe. Вы увидите длинный список. Игнорируйте все, что не находится в каталоге вашего компилятора (и не является сторонней библиотекой, установленной вами отдельно). В терминале MSYS2 вы можете запустить ntldd -R my_program.exe | grep 'C:\\msys64' для автоматической фильтрации.
В итоге у меня получились libstdc++-6.dll, libgcc_s_seh-1.dll, libwinpthread-1.dll, но ваш список может отличаться в зависимости от типа MinGW, который вы используете.
Скопируйте эти DLL рядом с вашим исполняемым файлом, и все готово. Написание сценария для автоматизации этого процесса остается для читателя в качестве упражнения.
Не копируйте сторонние библиотеки в свою установку компилятора.
Вы можете потерять след того, что скопировали.
Если вы используете MSYS2, ваши пользовательские библиотеки могут конфликтовать с тем, что устанавливает менеджер пакетов.
Вместо этого храните их в отдельном каталоге (используйте -I и -L, чтобы сообщить компилятору, где они находятся) и скопируйте библиотеки DLL рядом с исполняемым файлом.
Ничего не копируйте в C:\Windows.
Некоторые пользователи (или даже установщики) в своей бесконечной мудрости могут скопировать DLL в C:\Windows. Это вызовет проблемы, поскольку этот каталог имеет приоритет над содержимым PATH.
В общем, если вы видите одну и ту же DLL как в установке компилятора, так и в C:\Windows, это может означать, что последней там не место и ее следует удалить. Но руководствуйтесь здравым смыслом: вы обязаны не сломать свою систему.
@Rainb ntldd уже рекурсивен с флагом -R. Но да, это не должно быть сложно, вам просто нужно отклонить библиотеки в C:\Windows и, возможно, в некоторых других.
Интересно, почему никто никогда не создавал сценарий под названием «пакет», который просто рекурсивно использует ntldd и помещает все в выбранный вами каталог. Я думаю, что чатгпт справится с этим за 1 час.