8 lines
14 KiB
JSON
8 lines
14 KiB
JSON
{
|
||
"index": 371,
|
||
"slug": "компиляция-64-x-разрядных-программ-на-dmd-по",
|
||
"title": "DMD под Windows x64: как проверить архитектуру сборки и зависимости",
|
||
"excerpt": "Сборка D-программы с флагом -m64 не заканчивается на успешном сообщении компилятора. Разберём, как проверить DMD, linker, PE-заголовок и DLL, чтобы не искать ошибку в коде, когда проблема находится в toolchain.",
|
||
"contentHtml": "<p>Команда <code>dmd -m64 main.d</code> завершается без ошибки, но приложение не запускается на другой Windows-машине. Иногда linker сообщает о несовместимой библиотеке. Иногда Windows показывает, что DLL не найдена. Размер <code>.exe</code> при этом выглядит убедительно, а исходный код не менялся. Ошибка стоит времени на повторные сборки, ручное копирование DLL и отладку не того слоя.</p>\n<p>Тезис простой: 64-битный результат задаёт не только флаг <code>-m64</code>. Важны версия DMD, выбранный linker, архитектура объектных и библиотечных файлов, окружение командной строки и набор DLL, который увидит целевая система. Проверять нужно готовый PE-файл, а не предположение по команде сборки.</p>\n<figure><img src=\"/assets/illustrations/mascot-hero-2017-dmd-win64-wide-safe.png\" alt=\"Проверка сборки DMD для Windows x64\"/><figcaption>Граница проверки проходит от команды DMD до PE-заголовка и DLL, которые нужны готовому приложению.</figcaption></figure>\n<h2>Что именно меняет -m64</h2>\n<p>Флаг <code>-m64</code> просит DMD собрать 64-битную программу. Он не превращает 32-битную внешнюю библиотеку в 64-битную. Он также не исправляет PATH, не устанавливает linker и не добавляет отсутствующую DLL. Каждый слой отвечает за свою часть результата.</p>\n<p>На старых установках DMD под Windows настройки могли лежать в <code>sc.ini</code>. Там указывались linker и пути к SDK. Если 64-битная секция ссылалась на старую 32-битную утилиту или на каталог библиотек другой платформы, исходники компилировались, а линковка падала. В ранних сценариях отдельно встречалась граница между OMF и COFF: объектный файл или <code>.lib</code> одного формата нельзя безусловно подключить к другому.</p>\n<p>Современный официальный установщик обычно закрывает базовую настройку сам. Это не отменяет проверки. На машине могут остаться несколько DMD, Visual Studio Build Tools могут быть установлены без нужного набора C++, а DUB может использовать другую конфигурацию, чем ручная команда. Поэтому сначала фиксируем фактические версии и пути.</p>\n<h2>Минимальная проверка на учебном проекте</h2>\n<p>Ниже приведён учебный пример для Windows. Он не показывает production-совместимость и не доказывает, что любая библиотека проекта поддерживает x64. Создайте отдельный каталог с одним исходным файлом, чтобы отделить проблему toolchain от проблемы приложения.</p>\n<pre><code>@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</code></pre>\n<p>Файл <code>source\\hello.d</code> может содержать только <code>import std.stdio; void main() { writeln(\"Hello, x64\"); }</code>. Это проверяет учебный путь от DMD до исполняемого файла. Строка с PE-заголовком должна показывать признак x64, а <code>/DEPENDENTS</code> выводит импортируемые DLL. Конкретный текст вывода зависит от версии Visual Studio и установленного набора инструментов.</p>\n<p>Запускайте <code>dumpbin</code> из Developer Command Prompt или из x64 Native Tools Command Prompt. Если команда не найдена, это проблема окружения, а не повод копировать случайный <code>dumpbin.exe</code> в каталог проекта. Найдите установленный набор Visual Studio и откройте его командную строку.</p>\n<h2>Симптом → причина → проверка → действие</h2>\n<table><thead><tr><th>Симптом</th><th>Причина</th><th>Проверка</th><th>Действие</th></tr></thead><tbody><tr><td>Линковка сообщает о machine type conflict</td><td>Объект или <code>.lib</code> собран для другой архитектуры</td><td>Проверить PE-заголовки и происхождение каждого бинарного файла</td><td>Пересобрать зависимость под x64 или выбрать совместимый пакет</td></tr><tr><td><code>dmd</code> найден, но linker не найден</td><td>PATH указывает не на то окружение</td><td><code>where dmd</code>, версия DMD, команда linker</td><td>Открыть Developer Command Prompt и повторить проверку</td></tr><tr><td>Сборка проходит, запуск сообщает о пропавшей DLL</td><td>Зависимость не установлена или не попала в поставку</td><td><code>dumpbin /dependents</code> и запуск в чистой среде</td><td>Добавить разрешённую DLL в поставку или убрать зависимость</td></tr><tr><td>Ручная правка <code>sc.ini</code> не помогает</td><td>Исправлен не тот раздел или используется другой DMD</td><td>Сверить путь из <code>where dmd</code> с каталогом <code>sc.ini</code></td><td>Сначала выбрать один toolchain; затем изменить только нужную настройку</td></tr><tr><td>Debug работает, release нет</td><td>Конфигурации используют разные linker или runtime</td><td>Сравнить команды, PATH и список DLL двух сборок</td><td>Зафиксировать release-окружение и проверить его отдельно</td></tr></tbody></table>\n<h2>Порядок действий</h2>\n<ol><li>Запишите целевую платформу, версию Windows, версию DMD и способ запуска сборки.</li><li>Выполните <code>where dmd</code>, <code>dmd --version</code> и, если используется DUB, <code>dub --version</code>. Убедитесь, что команда запускает ожидаемый toolchain.</li><li>Откройте Developer Command Prompt с Visual C++ tools. Не смешивайте linker из одного окружения с библиотеками из другого без проверки.</li><li>Соберите минимальный учебный проект командой <code>dmd -m64</code>. Сохраните полный вывод и код возврата.</li><li>Проверьте PE-заголовок готового файла через <code>dumpbin /headers</code>. Не используйте размер файла как признак архитектуры.</li><li>Проверьте импортируемые DLL через <code>dumpbin /dependents</code>. Отдельно проверьте запуск release-бинарника в изолированной среде без случайных DLL из PATH.</li><li>Если ошибка остаётся, заменяйте по одному слою: сначала внешний <code>.lib</code>, затем linker, затем конфигурацию DUB. После каждого изменения повторяйте проверку PE и зависимостей.</li></ol>\n<h2>Если проверка не проходит</h2>\n<p>Не начинайте с переписывания D-кода. Сначала сохраните сообщение linker, список команд и пути, которые вывел <code>where</code>. Затем определите файл, на котором появилась ошибка. Для внешней библиотеки проверьте, кто её собрал и для какой архитектуры. Если поставщик даёт только 32-битный бинарник, флаг <code>-m64</code> не решит проблему.</p>\n<p>Не копируйте DLL из каталога Windows или Visual Studio в папку приложения наугад. Такая копия может скрыть настоящую зависимость и создать другой результат на машине пользователя. Сначала выясните, какая библиотека импортируется и разрешена ли её поставка. Для системной DLL учитывайте версию Windows и установленный runtime.</p>\n<p>Если используется старая DMD, ручная правка <code>sc.ini</code> может быть необходима. Меняйте только секцию, соответствующую 64-битной сборке, и делайте резервную копию файла. После изменения снова выведите путь к DMD и повторите учебную сборку. Если результат не изменился, вероятно, команда читает другой <code>sc.ini</code> или linker берётся из PATH.</p>\n<h2>Ограничения</h2>\n<p>Эта проверка устанавливает архитектуру учебного бинарника и показывает его прямые импорты. Она не гарантирует работу графического интерфейса, COM, драйверов, установщика или всех динамических загрузок через <code>LoadLibrary</code>. Она также не заменяет тестирование конкретных внешних библиотек и не подтверждает поддержку каждой версии Windows.</p>\n<p>Команды с <code>dumpbin</code> зависят от наличия Visual Studio tools. На машине без них нужен другой проверенный PE-анализатор, но критерий остаётся тем же: инструмент должен прочитать архитектуру файла и список зависимостей. Не делайте вывод о x64 по имени каталога, флагу в скрипте или размеру <code>.exe</code>.</p>\n<p>Учебные имена <code>hello.exe</code>, пути и версия toolchain здесь демонстрационные. Для реального проекта зафиксируйте свои версии, конфигурацию DUB, linker и перечень поставляемых DLL.</p>\n<h2>Критерий готовности</h2>\n<p>Сборка готова к следующему этапу, когда сохранённая команда завершается успешно, PE-заголовок явно указывает x64, все внешние библиотеки имеют ту же архитектуру, а release-бинарник запускается в целевой изолированной среде с ожидаемыми DLL. Рядом с артефактом должны лежать версии DMD и linker, команда сборки и вывод проверок. Если хотя бы один пункт неизвестен, результат считается непроверенным, даже если приложение запустилось на машине разработчика.</p>\n<h2>Проверяемые источники</h2>\n<ul><li><a href=\"https://dlang.org/dmd-windows.html\">DMD Compiler for Windows</a> — официальное описание установки, <code>-m64</code> и linker под Windows.</li><li><a href=\"https://learn.microsoft.com/en-us/cpp/build/reference/dumpbin-reference?view=msvc-170\">DUMPBIN Reference</a> — официальное описание анализа COFF, PE, executable и DLL.</li><li><a href=\"https://learn.microsoft.com/en-us/cpp/build/reference/dependents?view=msvc-170\">/DEPENDENTS (DUMPBIN)</a> — официальное описание вывода импортируемых DLL.</li></ul>"
|
||
}
|