{ "index": 371, "slug": "компиляция-64-x-разрядных-программ-на-dmd-по", "title": "DMD под Windows x64: как проверить архитектуру сборки и зависимости", "excerpt": "Сборка D-программы с флагом -m64 не заканчивается на успешном сообщении компилятора. Разберём, как проверить DMD, linker, PE-заголовок и DLL, чтобы не искать ошибку в коде, когда проблема находится в toolchain.", "contentHtml": "

Команда dmd -m64 main.d завершается без ошибки, но приложение не запускается на другой Windows-машине. Иногда linker сообщает о несовместимой библиотеке. Иногда Windows показывает, что DLL не найдена. Размер .exe при этом выглядит убедительно, а исходный код не менялся. Ошибка стоит времени на повторные сборки, ручное копирование DLL и отладку не того слоя.

\n

Тезис простой: 64-битный результат задаёт не только флаг -m64. Важны версия DMD, выбранный linker, архитектура объектных и библиотечных файлов, окружение командной строки и набор DLL, который увидит целевая система. Проверять нужно готовый PE-файл, а не предположение по команде сборки.

\n
\"Проверка
Граница проверки проходит от команды DMD до PE-заголовка и DLL, которые нужны готовому приложению.
\n

Что именно меняет -m64

\n

Флаг -m64 просит DMD собрать 64-битную программу. Он не превращает 32-битную внешнюю библиотеку в 64-битную. Он также не исправляет PATH, не устанавливает linker и не добавляет отсутствующую DLL. Каждый слой отвечает за свою часть результата.

\n

На старых установках DMD под Windows настройки могли лежать в sc.ini. Там указывались linker и пути к SDK. Если 64-битная секция ссылалась на старую 32-битную утилиту или на каталог библиотек другой платформы, исходники компилировались, а линковка падала. В ранних сценариях отдельно встречалась граница между OMF и COFF: объектный файл или .lib одного формата нельзя безусловно подключить к другому.

\n

Современный официальный установщик обычно закрывает базовую настройку сам. Это не отменяет проверки. На машине могут остаться несколько DMD, Visual Studio Build Tools могут быть установлены без нужного набора C++, а DUB может использовать другую конфигурацию, чем ручная команда. Поэтому сначала фиксируем фактические версии и пути.

\n

Минимальная проверка на учебном проекте

\n

Ниже приведён учебный пример для Windows. Он не показывает production-совместимость и не доказывает, что любая библиотека проекта поддерживает x64. Создайте отдельный каталог с одним исходным файлом, чтобы отделить проблему toolchain от проблемы приложения.

\n
@echo off\nwhere dmd\ndmd --version\nwhere dub\ndub --version\n\nif not exist bin mkdir bin\ndmd -m64 -of=bin\\hello.exe source\\hello.d\nif errorlevel 1 exit /b 1\n\ndumpbin /headers bin\\hello.exe | findstr /i \"machine\"\ndumpbin /dependents bin\\hello.exe
\n

Файл source\\hello.d может содержать только import std.stdio; void main() { writeln(\"Hello, x64\"); }. Это проверяет учебный путь от DMD до исполняемого файла. Строка с PE-заголовком должна показывать признак x64, а /DEPENDENTS выводит импортируемые DLL. Конкретный текст вывода зависит от версии Visual Studio и установленного набора инструментов.

\n

Запускайте dumpbin из Developer Command Prompt или из x64 Native Tools Command Prompt. Если команда не найдена, это проблема окружения, а не повод копировать случайный dumpbin.exe в каталог проекта. Найдите установленный набор Visual Studio и откройте его командную строку.

\n

Симптом → причина → проверка → действие

\n
СимптомПричинаПроверкаДействие
Линковка сообщает о machine type conflictОбъект или .lib собран для другой архитектурыПроверить PE-заголовки и происхождение каждого бинарного файлаПересобрать зависимость под x64 или выбрать совместимый пакет
dmd найден, но linker не найденPATH указывает не на то окружениеwhere dmd, версия DMD, команда linkerОткрыть Developer Command Prompt и повторить проверку
Сборка проходит, запуск сообщает о пропавшей DLLЗависимость не установлена или не попала в поставкуdumpbin /dependents и запуск в чистой средеДобавить разрешённую DLL в поставку или убрать зависимость
Ручная правка sc.ini не помогаетИсправлен не тот раздел или используется другой DMDСверить путь из where dmd с каталогом sc.iniСначала выбрать один toolchain; затем изменить только нужную настройку
Debug работает, release нетКонфигурации используют разные linker или runtimeСравнить команды, PATH и список DLL двух сборокЗафиксировать release-окружение и проверить его отдельно
\n

Порядок действий

\n
  1. Запишите целевую платформу, версию Windows, версию DMD и способ запуска сборки.
  2. Выполните where dmd, dmd --version и, если используется DUB, dub --version. Убедитесь, что команда запускает ожидаемый toolchain.
  3. Откройте Developer Command Prompt с Visual C++ tools. Не смешивайте linker из одного окружения с библиотеками из другого без проверки.
  4. Соберите минимальный учебный проект командой dmd -m64. Сохраните полный вывод и код возврата.
  5. Проверьте PE-заголовок готового файла через dumpbin /headers. Не используйте размер файла как признак архитектуры.
  6. Проверьте импортируемые DLL через dumpbin /dependents. Отдельно проверьте запуск release-бинарника в изолированной среде без случайных DLL из PATH.
  7. Если ошибка остаётся, заменяйте по одному слою: сначала внешний .lib, затем linker, затем конфигурацию DUB. После каждого изменения повторяйте проверку PE и зависимостей.
\n

Если проверка не проходит

\n

Не начинайте с переписывания D-кода. Сначала сохраните сообщение linker, список команд и пути, которые вывел where. Затем определите файл, на котором появилась ошибка. Для внешней библиотеки проверьте, кто её собрал и для какой архитектуры. Если поставщик даёт только 32-битный бинарник, флаг -m64 не решит проблему.

\n

Не копируйте DLL из каталога Windows или Visual Studio в папку приложения наугад. Такая копия может скрыть настоящую зависимость и создать другой результат на машине пользователя. Сначала выясните, какая библиотека импортируется и разрешена ли её поставка. Для системной DLL учитывайте версию Windows и установленный runtime.

\n

Если используется старая DMD, ручная правка sc.ini может быть необходима. Меняйте только секцию, соответствующую 64-битной сборке, и делайте резервную копию файла. После изменения снова выведите путь к DMD и повторите учебную сборку. Если результат не изменился, вероятно, команда читает другой sc.ini или linker берётся из PATH.

\n

Ограничения

\n

Эта проверка устанавливает архитектуру учебного бинарника и показывает его прямые импорты. Она не гарантирует работу графического интерфейса, COM, драйверов, установщика или всех динамических загрузок через LoadLibrary. Она также не заменяет тестирование конкретных внешних библиотек и не подтверждает поддержку каждой версии Windows.

\n

Команды с dumpbin зависят от наличия Visual Studio tools. На машине без них нужен другой проверенный PE-анализатор, но критерий остаётся тем же: инструмент должен прочитать архитектуру файла и список зависимостей. Не делайте вывод о x64 по имени каталога, флагу в скрипте или размеру .exe.

\n

Учебные имена hello.exe, пути и версия toolchain здесь демонстрационные. Для реального проекта зафиксируйте свои версии, конфигурацию DUB, linker и перечень поставляемых DLL.

\n

Критерий готовности

\n

Сборка готова к следующему этапу, когда сохранённая команда завершается успешно, PE-заголовок явно указывает x64, все внешние библиотеки имеют ту же архитектуру, а release-бинарник запускается в целевой изолированной среде с ожидаемыми DLL. Рядом с артефактом должны лежать версии DMD и linker, команда сборки и вывод проверок. Если хотя бы один пункт неизвестен, результат считается непроверенным, даже если приложение запустилось на машине разработчика.

\n

Проверяемые источники

\n" }