Содержание статьи
В общем-то, даже в Microsoft уже признали проблему и сделали WSL (Windows Subsystem for Linux), чтобы запускать те приложения, у которых нативных версий под Windows нет. Однако если ты хочешь сделать свою программу доступной для широкой аудитории, то WSL вовсе не панацея, поскольку у среднего пользователя эта система вряд ли установлена и у нативных приложений возможностей для интеграции с Windows все равно больше.
Во многих случаях камень преткновения — не сам код программы, а система сборки. Если ты используешь кросс-платформенные библиотеки и не вызываешь специфичные функции POSIX, портирование может вообще не требоваться. Главное — собрать исполняемые файлы.
Сборка-то обычно и зависит от окружения POSIX. Если ты используешь GNU autotools, то скрипт ./configure
у тебя на Bourne shell. CMake и ряд других систем сборки умеют генерировать скрипты под целевую ОС, но остается последняя «маленькая» проблема — нужна проприетарная и не бесплатная ОС. Есть вариант переложить задачу ее развертывания и лицензирования на кого-то другого и обратиться к сервису вроде Appveyor... Но можно вместо этого воспользоваться способностью GCC к кросс-компиляции и собирать программы на хосте с Linux (или macOS).
GNU и Windows
Для сборки программ с помощью GNU toolchain на Windows часто используют два проекта: Cygwin и MinGW + MSYS. У них схожие цели, но разные детали реализации. Давай разбираться.
Cygwin
Cygwin — самая полная реализация окружения GNU для Windows. Он предоставляет большую часть POSIX API в виде библиотеки, что позволяет собирать программы из UNIX без портирования, если только им не требуется семантика UNIX. Яркий пример — демоны, им нужен fork()
и сигналы, которых нет в Windows, да и службы Windows устроены совсем иначе.
Кроме библиотеки, дистрибутив содержит набор классических команд UNIX и терминал. Реализации команд используют эту библиотеку и поддерживают некоторые возможности UNIX, такие как регистрозависимые имена файлов.
Целевой способ использования: если нет желания или возможности портировать программу на Windows или использовать только платформенно независимые API, ее можно собрать «под Cygwin», ценой зависимости от cygwin1.dll
и относительной изоляции от всей остальной системы.
Многие люди ставили и продолжают ставить окружение Cygwin, чтобы иметь возможность использовать классические команды UNIX на Windows. Некоторые разработчики также включают Cygwin в инструкции для сборки своих программ под Windows, хотя сама программа не связывается с cygwin1.dll
. Для этой цели может быть более правильно использовать MSYS.
MinGW и MSYS
Если цель Cygwin — сделать возможной сборку немодифицированных приложений на Windows ценой внешней зависимости, то цель MinGW + MSYS — производить приложения без внешних зависимостей.
MinGW и MSYS — это независимые пакеты, но их часто путают и смешивают друг с другом (а часто путают и с Cygwin). Можно сказать, что MinGW — это эквивалент GCC и binutils, а MSYS — расширенный эквивалент coreutils.
Начнем с MSYS. MSYS — это более «нативная» и легковесная альтернатива Cygwin. Этот пакет включает библиотеку с реализациями функций POSIX, но она предназначена для внутреннего пользования, и авторы категорически не рекомендуют связывать с ней свои приложения.
Библиотека MSYS не реализует UNIX поверх Windows, а следует соглашениям Windows — к примеру, сознательно не учитывает регистр букв в путях к файлам. Главная цель MSYS — предоставить нужные для скриптов сборки программы вроде Bourne shell, make и прочее, что обычно требуется для autotools.
MinGW содержит версии GCC и binutils (ассемблер as, компоновщик ld и так далее), которые производят исполняемые файлы для Windows в формате PE/COFF. Здесь мы и подходим к ключевому моменту: MinGW, как и все остальные части GNU toolchain, такой же платформенно независимый проект.
Кросс-компиляция в GNU toolchain уже давно обычное дело, и в GCC целевая платформа и хост независимы друг от друга. Можно запускать GCC на Linux для x86 и собирать программы для Linux на ARM, или наоборот. Совпадать не обязаны не только рабочая и целевая архитектуры процессора. Точно так же не обязаны совпадать даже ОС и формат исполняемого файла.
Ставим MinGW
Авторы многих дистрибутивов GNU/Linux уже постарались за нас, так что многие кросс-версии GCC, включая MinGW, можно поставить из репозиториев.
Например, в Fedora:
$ sudo dnf install mingw32-gcc
$ sudo dnf install mingw64-gcc
Или в Debian:
$ sudo apt-get install gcc-mingw-w64-i686
$ sudo apt-get install gcc-mingw-w64-x86-64
Если ты используешь macOS, то MinGW можно поставить из Homebrew: brew install mingw-w64
.
INFO
MinGW-w64, несмотря на название, поддерживает и Win32, и Win64. Это форк MinGW, который создали в первую очередь для реализации недостающей в оригинальном проекте поддержки Win64, отсюда и название.
В Fedora также присутствует ряд готовых кросс-версий популярных библиотек, например mingw32-qt
.
Hello World
Для демонстрации соберем традиционный hello world. У кросс-версий GCC всегда есть префикс, для MinGW используются префиксы i686-w64-mingw32
и x86_64-w64-mingw32
.
$ cat ./hello.c
#include <stdio.h>
int main(void){
printf("hello world\n");
}
$ i686-w64-mingw32-gcc -o hello32 ./hello.c
$ file ./hello32.exe
./hello32.exe: PE32 executable (console) Intel 80386, for MS Windows
Тестирование кросс-компилированных программ для других архитектур — непростая задача, но, поскольку наша целевая платформа — Windows на x86, мы легко можем протестировать их в Wine:
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»