Both sides previous revisionPrevious revisionNext revision | Previous revisionLast revisionBoth sides next revision |
msys2_mingw [2022/03/28 22:23] – [Компилятор и его запуск] admin | msys2_mingw [2024/03/14 12:38] – [Компилятор и его запуск] admin |
---|
<html><h1>Установка и использование MSYS2 и Mingw-w64 под Windows</h1></html> | <html><h1>Установка и использование MSYS2 и Mingw-w64 под Windows</h1></html> |
Текст был первоналаьно сделан для сайта "[[https://www.phantom.sannata.org/viewtopic.php?p=500339#p500339|Железные призраки прошлого]]", но затем невозбранно перенесен на эту Wiki и теперь живет тут. | Текст был первоначально написан для сайта "[[https://www.phantom.sannata.org/viewtopic.php?p=500339#p500339|Железные призраки прошлого]]", но затем невозбранно перенесен на эту Wiki и теперь живет тут. |
| |
==== Введение ==== | ==== Введение ==== |
| |
В целях ретрокомпьютинга иногда возникает желание "что-нибудь скомпилировать под 32-битный Windows". Ага, ага. Вот и у меня однажды возникала | В целях ретрокомпьютинга иногда возникает необходимость "что-нибудь скомпилировать под 32-битный Windows" с минимальными затратами. Ага, ага. Вот и у меня однажды возникала |
такая же ситуация. Когда-то раньше мне довелось пользоваться компилятором **[[https://ru.wikipedia.org/wiki/MinGW|Mingw]]** и оболочкой **MSYS**, так что я попробовал их найти и установить. Оказалось, что там "всё не так, как раньше". | такая же ситуация. Когда-то давно я пользовался компилятором **[[https://ru.wikipedia.org/wiki/MinGW|Mingw]]** и оболочкой **MSYS**, так что я попробовал снова их найти и установить. Оказалось, что там "всё не так, как раньше". Вобщем, сейчас ситуация такая: "простой" MinGW и "классический" MSYS обновляться перестали и они зачахли где-то в районе 2015 года. |
Вобщем, сейчас ситуация такая: "простой" MinGW и "классический" MSYS обновляться перестали | |
и они зачахли где-то в районе 2015 года. | |
| |
**ПРИМЕЧАНИЕ:** Надеюсь, читатели понимают разницу между **[[https://ru.wikipedia.org/wiki/Cygwin|Cygwin]]** и **[[https://ru.wikipedia.org/wiki/MinGW|Mingw]]**. Кратко: **Cygwin** пытается воссоздать наиболее полную "среду" UNIX/POSIX на Windows, со всеми её фишками, типа //fork()//, особенностей файловой системы, сигналами, псевдотерминалами и т.д. в то время как **Mingw** - это (изначально) просто перенос компилятора **GCC** на Windows, без вот этого всего. А **MSYS** - это набор утилит для сборки, главные из которых - пожалуй ''make'' и ''bash''. [[https://www.msys2.org/wiki/How-does-MSYS2-differ-from-Cygwin/|Подробности]]. | Дак вот, оказывается, нынче текущая версия **MSYS** - это **[[https://www.msys2.org/|MSYS2]]**. Это такой странный гибрид |
| из **Cygwin** и старого **MSYS**. Что там нового ? Подобно **Cygwin** он делает замену путей в стиле UNIX, маскирует расширение *.exe, |
Оказывается, нынче текущая версия **MSYS** - это **[[https://www.msys2.org/|MSYS2]]**. Это такой странный гибрид | поддерживает псевдотерминалы, UNIX-сигналы и еще много чего. Это, с одной стороны, облегчает процесс сборки |
из **Cygwin** и старого **MSYS**. | всяких нетривиальных UNIX программ, а с другой стороны, теперь все MSYS2-программы, в отличии от старого **MSYS** тянут за собой |
Подобно **Cygwin** он делает замену путей в стиле UNIX, маскирует расширение *.exe, | |
поддерживает псевдотерминалы, UNIX-сигналы и еще много чего. Это, с одной стороны, облегчает перенос и build-инг | |
всяких нетривиальных UNIX программ, а с другой стороны, все msys-программы, в отличии от старого **MSYS** теперь тянут за собой | |
DLL-ку: ''msys-2.0.dll'' . | DLL-ку: ''msys-2.0.dll'' . |
| |
Вы еще не запутались ? Держитесь, это только начало... :) | Вы еще не запутались ? Держитесь, это только начало... :) |
| |
**MSYS2** теперь поддерживает два вида терминалов (т.е. программ для отрисовки "текстового" экрана) - один новомодный **[[https://en.wikipedia.org/wiki/Mintty|Mintty]]**, | **MSYS2** теперь поддерживает несколько видов терминалов (т.е. программ для отрисовки "текстового" экрана) - один новомодный **[[https://en.wikipedia.org/wiki/Mintty|Mintty]]**, |
утащенный с того же **Cygwin**, который типа лучше поддерживает механизмы терминала UNIX, но опять | утащенный с того же **Cygwin**, который типа лучше поддерживает механизмы терминала UNIX, но опять |
же, тянет за собой всякое... Другой - почти классическая Windows консоль почти без обвеса (**[[https://ru.wikipedia.org/wiki/ConEmu|ConEmu]]**) | же, тянет за собой всякое... Другой - почти классическая Windows-консоль почти без обвеса (**[[https://ru.wikipedia.org/wiki/ConEmu|ConEmu]]**) |
но зато с закладками (Tabs). На самом деле, есть еще третий вид терминала (defterm), но он не совсем поддерживается... | но зато с закладками (Tabs). На самом деле, есть еще третий вид терминала (defterm), но он не совсем поддерживается... |
[[https://www.msys2.org/wiki/Terminals/|Подробности]]. | [[https://www.msys2.org/wiki/Terminals/|Подробности]]. |
ключиком. По-умолчанию запускается **Mintty**. | ключиком. По-умолчанию запускается **Mintty**. |
| |
Да, сама **MSYS2** тоже бывает 32-битная и 64-битная. К счастью на сайте **MSYS2** [[https://repo.msys2.org/distrib/|есть]] нужный инсталлятор, | **ПРИМЕЧАНИЕ:** Надеюсь, читатели понимают разницу между **[[https://ru.wikipedia.org/wiki/Cygwin|Cygwin]]** и **[[https://ru.wikipedia.org/wiki/MinGW|Mingw]]**. Кратко: **Cygwin** пытается воссоздать наиболее полную "среду" UNIX/POSIX на Windows, со всеми её фишками, типа //fork()//, особенностями файловой системы, сигналами, псевдотерминалами и т.д. в то время как **Mingw** - это (изначально) просто перенос компилятора **GCC** на Windows, без вот этого всего. А **MSYS** - это "оболочка", то есть набор утилит __для сборки__, главные из которых - пожалуй ''make'' и ''bash''. [[https://www.msys2.org/wiki/How-does-MSYS2-differ-from-Cygwin/|Подробности]]. Надо добавить, что вся эта магия имеется только в среде **MSYS2**, а полученная программа билдится с MSVCRT.DLL и большинство этих фишек не поддерживает. |
| |
| Да, надо дабавить, что сама по себе **MSYS2** тоже бывает 64-битная и 32-битная (была). К счастью на сайте **MSYS2** [[https://repo.msys2.org/distrib/|есть]] нужный инсталлятор, |
(''msys2-x86_64'' или ''msys2-i686'') - это такой огромный файл .EXE, у которого внутри целый архив соответствующих программ. | (''msys2-x86_64'' или ''msys2-i686'') - это такой огромный файл .EXE, у которого внутри целый архив соответствующих программ. |
**MSYS2** 64-битная по умолчанию ставится в ''C:\msys64'', а 32-битная - в ''C:\msys32''. Можете попробовать поменять каталог, | **MSYS2** 64-битная по умолчанию ставится в ''C:\msys64'', а 32-битная - в ''C:\msys32''. Можете попробовать поменять каталог, |
но тогда никто ничего не гарантирует... Но вот беда - инсталлятор старый и первое, что нужно сделать - | но тогда никто ничего не гарантирует... Но вот беда - инсталлятор старый и первое, что нужно сделать - это обновиться командой: ''pacman -Syuu'' |
это обновиться: ''pacman -Syuu'' | |
Этот ''pacman'' первым делом обновит сам себя, так что ОБЯЗАТЕЛЬНО надо прибить всё окно! НЕ выходя!!! | Этот ''pacman'' первым делом обновит сам себя, так что ОБЯЗАТЕЛЬНО надо прибить всё окно! НЕ выходя!!! |
И запустить ''pacman -Syuu'' еще раз. | И запустить ''pacman -Syuu'' еще раз. |
Вы еще тут ? Я еще держусь, но с трудом... :) | Вы еще тут ? Я еще держусь, но с трудом... :) |
| |
**ПРИМЕЧАНИЕ:** С мая 2020 32-битную **MSYS2** стали [[https://www.msys2.org/news/#2020-05-17-32-bit-msys2-no-longer-actively-supported|потихоньку сворачивать]]. Она еще поддерживается, но пакеты для нее выходят крайне редко, а начальный инсталлятор для 32-битной версии **MSYS2** убрали с главной стравницы [[http://repo.msys2.org/distrib/i686/|сюда]]. Следите за [[https://www.msys2.org/news/|новостями]]. Таким образом, для инструментальной машины лучше использовать 64-битную ОС и 64-битную ''MSYS2''. Увы. | **ПРИМЕЧАНИЕ:** С мая 2020 32-битную **MSYS2** стали [[https://www.msys2.org/news/#2020-05-17-32-bit-msys2-no-longer-actively-supported|потихоньку сворачивать]]. Она еще поддерживается, но пакеты для нее выходят крайне редко, а начальный инсталлятор для 32-битной версии **MSYS2** убрали с главной стравницы [[http://repo.msys2.org/distrib/i686/|сюда]]. Следите за [[https://www.msys2.org/news/|новостями]]. Таким образом, даже для сборки 32-битных приложений нужно использовать 64-битную ОС и 64-битную ''MSYS2''. Этакая кросс-система. Увы. |
| |
| [[https://www.msys2.org/news/#2022-04-06-windows-7-8-support-will-be-dropped-late-2022-or-early-2023|2022-04-06 - Windows 7 / 8 support will be dropped late 2022 or early 2023]] |
| |
| [[https://www.msys2.org/news/#2023-01-15-dropping-support-for-windows-7-and-80|2023-01-15 - Dropping support for Windows 7 and 8.0]] |
| |
==== Компилятор и его запуск ==== | ==== Компилятор и его запуск ==== |
| |
Ну вот например поставили мы **MSYS2** (без разницы, 64-битную или 32-битную) и обновились. Давайте попробуем, наконец, скомпилить HelloWorld | Ну вот например поставили мы **MSYS2** (без разницы, 64-битную или 32-битную) и обновились. Давайте попробуем, наконец, скомпилить HelloWorld |
под Windows консоль. А вот хрен вам! Оказывается, теперь есть НЕ ОДИН компилятор, точнее не одна build-система, а несколько. | под Windows-консоль. А вот хрен вам! Оказывается, теперь есть НЕ ОДИН компилятор, точнее не одна build-система (среда, namespace e.t.c.), а несколько. |
Из них первая - для компиляции программ под __САМУ__ **MSYS2** (вы же помните, что она тащит за собой теперь как | Из них первая - для компиляции программ под __САМУ__ **MSYS2** (вы же помните, что она тащит за собой теперь как |
минимум DLL ''msys-2.0.dll'' и работает с UNIX-путями), а вторая build-система - для обычных "голых" Windows программ, | минимум DLL ''msys-2.0.dll'' и работает с UNIX-путями?), а остальные build-системы - для обычных "голых" Windows программ, |
как в старом добром **Mingw**. Компилятор и там и там - **Mingw-w64**, но по-разному настроенный. Да, | как в старом добром **Mingw**. Компилятор и там и там - знакомый **Mingw-w64**, но по-разному настроенный. Да, |
не забываем что всё это может существовать в 32-бит, 64-бит и все комбинации между ними! | не забываем что всё это может существовать в 32-бит, 64-бит и все комбинации между ними! |
Так что на самом деле у нас бывает (как минимум!) __ТРИ__ build системы: ''msys2'', ''mingw32'' и ''mingw64''. | Так что на самом деле у нас бывает (как минимум!) __ТРИ__ build системы: ''msys2'', ''mingw32'' и ''mingw64''. |
Все три ставить не обязательно. Например, если нам надо только собирать "чистые" 32-битные программы | Все три ставить не обязательно. Например, если нам надо только собирать "чистые" 32-битные программы |
на 32-битной винде то можно поставить 32-битную **MSYS2** без её собственных компиляторов и build-систему ''mingw32''. | на 64-битной винде то можно поставить 64-битную **MSYS2** __без__ её собственных компиляторов и build-систему ''mingw32''. |
(как понимаете, на самом деле это будет 32-битный компилятор по имени **Mingw-w64** работающий под 32-битной **MSYS2** и который умеет | (как понимаете, на самом деле это будет 64-битный компилятор по имени **Mingw-w64** работающий под 64-битной **MSYS2** и который умеет |
делать 32-битные "чистые" программы под Windows. Надеюсь крыша у вас еще не поехала...) | делать 32-битные "чистые" программы под Windows. Надеюсь крыша у вас еще не поехала...) |
| |
Итак, давайте сначала установим тулзы для сборки: ''pacman -S base-devel'' | Итак, давайте сначала установим тулзы для сборки: ''pacman %%--%%needed -S base-devel'' |
Это установит всякие полезные для сборки утилиты в нашу **MSYS2** (любой битности). | Это установит всякие полезные для сборки утилиты в нашу **MSYS2** (любой битности). |
Установщик ''pacman'' знает про себя, 32-бита он или 64, берёт правильные пакеты и ставит | Установщик ''pacman'' знает про себя, 32-бита он или 64, берёт правильные пакеты и ставит |
надо установить группу ''mingw-w64-i686-toolchain''. То есть компилятор называется **Mingw-w64** | надо установить группу ''mingw-w64-i686-toolchain''. То есть компилятор называется **Mingw-w64** |
(помним, что это просто название такое). Ставится он на нашу текущую **MSYS2** и будет | (помним, что это просто название такое). Ставится он на нашу текущую **MSYS2** и будет |
генерить 32-битные программы (хвостик ''-i686''). Делаем сначала ''pacman -S --needed base-devel'', а потом ''pacman -S --needed mingw-w64-i686-toolchain''. | генерить 32-битные программы (хвостик ''-i686''). Делаем ''pacman -S %%--%%needed mingw-w64-i686-toolchain''. |
Пакеты компилятора скачаются (из репозитория ''mingw32'') и будут установлены. | Пакеты компилятора скачаются (из репозитория ''mingw32'') и будут установлены. |
Вот только никакого компилятора не появится! | Вот только никакого компилятора не появится! |
Чтобы воспользоваться нужным компилятором, надо __запустить__ нашу **MSYS2** особым образом. | Чтобы воспользоваться нужным компилятором, надо __запустить__ нашу **MSYS2** особым образом. |
Если вы откроете кнопку Пуск --> Все программы --> "MSYS2 32bit" то увидите __три__ разных "среды": | Если вы откроете кнопку Пуск --> Все программы --> "MSYS2 32bit" то увидите __три__ разных "среды": |
"MSYS2 MinGW 32bit", "MSYS2 MinGW 64bit" и "MSYS2 MSYS" (а в новых добавились еще clang и ucrt). По крайней мере, на Windows7 так. | "MSYS2 MSYS", "MSYS2 MinGW 32bit" и "MSYS2 MinGW 64bit" (а в новых добавились еще clang и [[https://learn.microsoft.com/en-us/cpp/porting/upgrade-your-code-to-the-universal-crt/|ucrt]]). По крайней мере, на Windows7 так. |
На Windows10 эти программы расположены в главном меню под буквой "M". Вот эти три разные режима запуска и делают всю магию. | На Windows10 эти программы расположены в главном меню под буквой "M". Вот эти __три разные режима запуска__ и делают всю магию. |
Альтернативный путь - запускать напрямую программы из папки ''C:\msys32\......exe'' или скрипт ''C:\msys32\msys2_shell.cmd'' с ключами ''-mingw32'', ''-mingw64'' | Альтернативный путь - запускать напрямую программы из папки ''C:\msys64\......exe'' или скрипт ''C:\msys64\msys2_shell.cmd'' с ключами ''-mingw32'', ''-mingw64'' |
или ''-msys2''. Это точно то же самое. | или ''-msys2''. Это точно то же самое. |
| |
Давайте запустим "MSYS2 MinGW 32bit". Теперь у нас доступен компилятор **gcc**, причем он полностью | [[https://www.msys2.org/docs/environments/| Табличка с "окружениями"]] |
| |
| Давайте запустим "MSYS2 MinGW 32bit". Вот теперь у нас доступен нужный компилятор **gcc**, причем он полностью |
настроен, с указанием папки ''include'', линкера и пути к библиотекам. Ура! | настроен, с указанием папки ''include'', линкера и пути к библиотекам. Ура! |
| |
откомпилим его: | откомпилим его: |
$ gcc -o hello hello.c | $ gcc -o hello hello.c |
и запустим ПРЯМО ИЗ CMD.EXE (то есть из другого окна CMD, не из MSYS2): | и запустим ИЗ CMD.EXE (то есть из __другого__ окна CMD, а не из оболочки MSYS2) или из PowerShell: |
C:\TEMP\TEST>hello | C:\TEMP\TEST>hello |
Hello, World! | Hello, World! |
Есть и недостатки - полученный EXE-шник имеет размер почти 300Kb! Воспользуемся командой | Есть и недостатки - полученный EXE-шник имеет размер почти 300Kb! Воспользуемся командой |
''strip'' и удалим из него все лишнее. Получится EXE-шник около 16К, что гораздо лучше. | ''strip'' и удалим из него все лишнее. Получится EXE-шник около 16К, что гораздо лучше. |
Посмотрим, что у нас получилось (Windows 7): | Посмотрим, что у нас получилось (пример из Windows 7): |
$ file hello.exe | $ file hello.exe |
hello.exe: PE32 executable (console) Intel 80386, for MS Windows | hello.exe: PE32 executable (console) Intel 80386, for MS Windows |
Как и требовалось, это "чистое" автономное 32-битное консольное Win32 приложение, которое использует только | Как и требовалось, это "чистое" автономное 32-битное консольное Win32 приложение, которое использует только |
стандартные библиотеки 32-битного Windows (можно поспорить насчет стандартности | стандартные библиотеки 32-битного Windows (можно поспорить насчет стандартности |
MSVCRT.DLL, в котором и располагается //printf(//)), но по факту, она есть практически везде. На 64-битном Windows вывод ldd будет несколько другой, поскольку там другая архитектура запуска 32-битных программ WindowsOnWindows (WoW). Скорее всего, эта программа будет | MSVCRT.DLL, в котором и располагается //printf(//)), но по факту, она есть практически везде. На 64-битном Windows вывод ''ldd'' будет несколько другой, поскольку там другая архитектура запуска 32-битных программ WindowsOnWindows (WoW). Скорее всего, эта программа будет |
работать даже в Windows 95, поскольку формат PE-файла не изменился (не пробовал). | работать даже в Windows 95, поскольку формат PE-файла не изменился (не пробовал). |
| |
то даже ''-mwindows'' указывать не обязательно, компилятор сам понимает, но на всякий случай укажем. | то даже ''-mwindows'' указывать не обязательно, компилятор сам понимает, но на всякий случай укажем. |
| |
**ПРИМЕЧАНИЕ1:** Не стоит ждать многого от штатной библиотеки MSVCRT.DLL . Это далеко не полная реализация ''libc''. | **ПРИМЕЧАНИЕ1:** Обратите внимание, что наша программа собирается со штатной библиотекой MSVCRT.DLL. Не стоит ждать многого от нее. В MSVCRT.DLL реализован далеко не полный набор функций ''libc''. |
Кроме явного отсутствия "юниксовых" возможностей типа //fork()// и т.д. расхождения могут быть совсем неожиданные (и в разных Windows - разные). | Кроме явного отсутствия "юниксовых" возможностей типа //fork()//, вида слешей в путях к файлам и т.д. расхождения могут быть совсем неожиданные (и в разных версиях Windows - разные). |
Напаример, //printf()// не поддерживает формат ''%zd'' для типа ''size_t'' и другие неожиданные вещи. Компилятор | Например, //printf()// не поддерживает формат ''%zd'' для типа ''size_t'', поддержка UTF-8 довольно странная и другие неожиданные вещи. Компилятор |
**Mingw-w64** знает много таких особенностей и по мере возможностей дает предупреждения. [[https://www.msys2.org/wiki/Porting/|Подробности]]. | **Mingw-w64** знает много таких особенностей и по мере возможностей дает предупреждения. [[https://www.msys2.org/wiki/Porting/|Подробности]]. Несколько больше возможностей предоставляет новомодная [[https://learn.microsoft.com/en-us/cpp/porting/upgrade-your-code-to-the-universal-crt?view=msvc-170|UCRT]]. Если же нужны юниксовые фишки и не пугает зависимости от DLL - всегда можно собрать программу под оболочку **MSYS2**. |
| |
**ПРИМЕЧАНИЕ2:** Компиляторы **gcc**, а особенно **g++** иногда создают код, который зависит от библиотек | **ПРИМЕЧАНИЕ2:** Компиляторы **gcc**, а особенно **g++** иногда создают код, который зависит от библиотек |
''libgcc'' и ''libstdc++''. Чтобы полученное приложение не требовало соответствующих DLL, в командную | ''libgcc'' и ''libstdc++''. Чтобы полученное приложение не требовало соответствующих DLL, в командную |
строку можно добавить опции ''-static-libgcc'' и ''-static-libstdc++''. Библиотеки же, которые являются "стандартными" | строку можно добавить опции ''-static-libgcc'' и ''-static-libstdc++''. Библиотеки же, которые являются "стандартными" |
для Windows, **Mingw-w64** всегда делает динамическими, даже несмотря на присутствие опции ''-static'' | для Windows, умный **Mingw-w64** всегда делает динамическими, даже несмотря на присутствие опции ''-static'' |
в опциях компилятора. | в опциях компилятора. |
| |
==== Консольные полноэкранные приложения ==== | ==== Консольные полноэкранные/CLI приложения ==== |
| |
При портировании UNIX-приложений на **MSYS2** часто возникают сложности с работой "полноэкранных" текстовых приложений, т.е. требущих управления экраном. | **TODO**. Параграф не дописан! Имеются проблемы со сборкой pdcurses! |
| |
Тут надо немного углубиться в теорию. С точки зрения UNIX мы имеем две абстракции: | При портировании UNIX-приложений на **MSYS2** часто возникают сложности с работой "полноэкранных" текстовых приложений, TUI (Text User Interface) т.е. требущих управления экраном и управления курсором в консоли Windows. |
- [[https://ru.wikipedia.org/wiki/Стандартные потоки|Стандартные потоки]] STDIN/STDOUT/STDERR. Это псевдо-файлы, которые передаются при старте UNIX программы, с номерами файловых десткрапторов 0,1, и 2. Довольно часто, это не терминал, а вывод из предыдущей программы (pipe) или реальный файл. | |
- Терминал TTY. У терминала в UNIX имеется множество функций и атрибутов. Например, имеется API управления дисциплиной линии (всякие RTS/CTS), различные режимы ввода (с эхо или без) termio/termios, возможность переключения raw/cooked режимов, специальные функции управления заданиями (job control, например обработка CTRL-C, CTRL-Z) и т.д. Кроме того, у каждой разновидности терминала имеется база, описывающая его систему команд, в основном через ESC-последовательности (termcap/terminfo). | |
| |
На Windows совершенно другая идеология управления консолью (WinAPI Console). Поэтому и возникает необходимость в эмуляторе терминала и промежуточной библиотеке типа ''msys-2.0.dll'' или ''cygwin.dll'', которая имитирует (с разной степенью успешности) поведение UNIX системы. Тем или иным способом в оболочках типа **MSYS2** и **CYGWIN** эта проблема решена. Но с "автономными" консольными Windows приложениями неколько сложнее. На это накладывается взаимодействие c ''MSVCRT.DLL'', которая имитирует файловые потоки STDIN/STDOUT/STDERR и также вносит свои особенности. | Тут надо сначала немного углубиться в теорию. С точки зрения UNIX мы имеем две сложно-взаимодействующих абстракции: |
| - [[https://ru.wikipedia.org/wiki/Стандартные потоки|Стандартные потоки]] STDIN/STDOUT/STDERR. Это заранее открытые псевдо-файлы, которые передаются при старте UNIX программы, с номерами файловых десткрипторов 0,1, и 2. Довольно часто, это не терминал, а вывод из предыдущей программы (pipe) или реальный файл. |
| - Терминал TTY. У терминала в UNIX имеется множество функций и атрибутов. Например, имеется API управления дисциплиной линии (всякие RTS/CTS), различные режимы ввода (с эхо или без) [[https://man7.org/linux/man-pages/man3/termios.3.html|termio/termios]], возможность переключения raw/cooked режимов, а также специальные функции управления заданиями (job control, например обработка CTRL-C, CTRL-Z) и т.д. Кроме того, у каждой разновидности терминала имеется база, описывающая его систему команд, в основном через ESC-последовательности (termcap/terminfo). |
| |
[[https://eax.me/winapi-console-app/|Пишем простое консольное приложение на чистом WinAPI]] | На Windows - совершенно другая идеология управления консолью (WinAPI Console). (Пример: [[https://eax.me/winapi-console-app/|Пишем простое консольное приложение на чистом WinAPI]]). Поэтому и возникает необходимость в эмуляторе терминала и промежуточной библиотеке типа ''msys-2.0.dll'' или ''cygwin.dll'', которая имитирует (с разной степенью успешности) поведение UNIX системы. Тем или иным способом в оболочках типа **MSYS2** и **CYGWIN** эта проблема решена. Но с "автономными" консольными Windows приложениями неколько сложнее. На это накладывается взаимодействие программы через ''MSVCRT.DLL'', которая имитирует файловые потоки STDIN/STDOUT/STDERR и также вносит свои особенности. |
| |
Как же быть ? | Как же быть ? |
| |
Можно предложить такое неожиденное решение. Как правило, управление терминалом в UNIX-программах редко делают напрямую, на нижнем уровне через API терминала termio/termios. Как правило, используют готовые библиотеки, например [[https://ru.wikipedia.org/wiki/Termcap|Termcap]] или [[https://ru.wikipedia.org/wiki/Curses|Curses]]. Такую UNIX программу намного легче портировать в консольное "автономное" Windows приложение. | Можно предложить такое неожиданное решение. Как правило, управление терминалом в UNIX-программах редко делают напрямую, на нижнем уровне через API терминала termio/termios. Как правило, используют готовые библиотеки, например [[https://ru.wikipedia.org/wiki/Termcap|Termcap]] или [[https://ru.wikipedia.org/wiki/Curses|Curses]]. Такую UNIX программу намного легче портировать в консольное "автономное" Windows приложение. Доверимся авторам **MSYS2** в надежде, что они корректно перенесли на Windows и отладили эти библиотеки. |
| |
TODO | Надо сказать, что современных реализаций библиотеки curses есть целых две. Одна из них - ncurses, другая - pdcurses. Давайте установим ncurses для нашей 32-битной сборки: ''pacman -S mingw-w64-i686-ncurses''. |
| |
Одна из популярных библиотек, требующих прямого управления консолью - [[https://ru.wikipedia.org/wiki/GNU_Readline|readline]]. Библиотека GNU Readline используеся довольно широко. Самый известный пример - ''bash''. | **ПРИМЕЧАНИЕ**: Как было написано выше, управление консолью в Windows устроено совсем иначе, чем в UNIX, так что не обходится без глюков. Библиотека ncurses реализована таким образом, что она "чувствует", под какой консолью она работает и включает "магию". Если мы запускаем одну и ту же прогрмамму под UNIX-подобной консолью, она начинает управлять экраном через ESC-последовательности, а если из CMD или PowerShell - через API Windows Console. Но фокус в том, что для ESC-последовательностей нужна база терминалов, а она не всегда доступна. Это дает неприятный результат: программа на ncurses неадекватно работает из "оболочки" **MSYS2 Mingw64** в которой мы ее только что откомпилировали. А из обычных CMD или PowerShell работает нормально. Как это обойти ? Если нужна программа для среды **MSYS2** - скомпилируйте ее в оболочке **MSYS2 MSYS** с ее библиотеками, а если "чистая виндовая" - в среде **MSYS2 Mingw64**. |
| |
''pacman -S libreadline-devel'' | Давайте создадим простую ncurses программу для Windows (конечно же статическую): |
| |
''pacman -S mingw-w64-i686-ncurses'' | #include <curses.h> |
| |
| int main() |
| { |
| initscr(); /* Start curses mode */ |
| printw("Hello World !!!"); /* Print Hello World */ |
| refresh(); /* Print it on to the real screen */ |
| getch(); /* Wait for user input */ |
| endwin(); /* End curses mode */ |
| |
| return 0; |
| } |
| |
| |
| $ gcc -static -o curses.exe curses.c -I /usr/include/ncurses -l ncurses -DNCURSES_STATIC |
| |
| Обратите внимание, на ''#include'' - тут подключается заголовочный файл ''curses.h'', в стиле UNIX SYSVr4. Там компилятор обычно ищет ''curses.h'' прямо в ///usr/include// . В нашем случае это не работает, потому что у наc ДВЕ реализации curses и их заголовочные файлы лежат в разных каталогах. Так что нужно добавить ключ -I компилятору для поиска. |
| |
| При запуске этой программы в CMD или PowerShell (или кликом из Проводника) все работает как надо - пишет "Hello World !!!" в верхнем левом углу, а при запуске из **MSYS2 Mingw64 X86** программа вылетает (как и предупреждали): |
| |
| [USER@HOST test]$ uname |
| MINGW32_NT-10.0-17134 |
| [USER@HOST test]$ ./curses.exe |
| Error opening terminal: xterm. |
| |
| Для дальнейшего погружения в ncurses есть неплохое [[https://tldp.org/HOWTO/NCURSES-Programming-HOWTO/|NCURSES Programming HOWTO]]. Также большое количество документации и примеров содержится в [[https://invisible-island.net/archives/ncurses/|исходниках ncurses]]. |
| |
| Другая реализация curses - [[https://pdcurses.org/|pdcurses]] сделана еще более интересно. Она может выводить текстовый TUI интерфейс с поддержкой текстовых окошек не только в текстовую консоль, но даже в окно X11, в окно SDL, использовать графику и т.д. Имеется даже [[https://github.com/Bill-Gray/PDCursesMod|форк pdcurses]], который может отрисовывать текст с управлением терминалом в других оконных системах, от Windows GDI до OpenGL. |
| |
| /не дописано т.к. имеются проблемы с pdcurses/ |
| |
| Еще одна популярная библиотека, требующих прямого управления консолью - [[https://ru.wikipedia.org/wiki/GNU_Readline|readline]]. Библиотека GNU Readline очень удобна для ввода и используеся довольно широко. Самый известные примеры - ''bash'' и ''gdb''. Давайте установим: ''pacman -S mingw-w64-i686-readline''. |
| |
| В поставке readline идет несколько примеров. Лежат они (для нашей среды) в ///mingw32/share/readline/// . Можно собрать простейший пример rlbasic.c |
| |
| $ cp /mingw32/share/readline/rlbasic.c . |
| $ gcc -static -o rlbasic.exe rlbasic.c -l readline -l ncurses -DNCURSES_STATIC |
| |
| Опять же, при запуске полученной программы из среды **MSYS2** программа работает странно (трижды выводит всю строку и редактирование не работает), а при запуске из CMD или PowerShell - нормально (позволяет редактировать строку и ловит команду "exit"). Библиотека GNU readline подерживает множество функций, например историю ввода, которая в этом примере не обрабатывается. |
| |
| Полная документация по [[https://web.mit.edu/gnu/doc/html/rlman_toc.html|GNU Readline Library]]. |
| |
| Библиотекой readline можно управлять с помощью файла''.inputrc'' (под Windows ??) |
| |
| Конец недописанного параграфа. |
| |
| |
| |
По **SDL** в сети гуляет просто огромное число примеров, туториалов, введений и т.д. **SDL** рисует, | По **SDL** в сети гуляет просто огромное число примеров, туториалов, введений и т.д. **SDL** рисует, |
поёт, поддерживает джойстик и сеть, может быть даже варит кофе... Текущая версия: **SDL2**. | играет музыку, поддерживает джойстик и сеть, может быть даже варит кофе... ;-) Текущая версия: **SDL2**. |
Давайте поставим себе **SDL2** вместе со всеми её запчастями :\\ | Давайте поставим себе **SDL2** вместе со всеми её запчастями :\\ |
''pacman -S mingw-w64-i686-SDL2 mingw-w64-i686-SDL2_gfx mingw-w64-i686-SDL2_image | ''pacman -S mingw-w64-i686-SDL2 mingw-w64-i686-SDL2_gfx mingw-w64-i686-SDL2_image |
обратного апострофа: **`** . Читается как "Использовать ВЫВОД команды". Подробности в ''man bash'' секция "Command Substitution" ) | обратного апострофа: **`** . Читается как "Использовать ВЫВОД команды". Подробности в ''man bash'' секция "Command Substitution" ) |
$ gcc -o hellosdl hellosdl.c `sdl2-config --cflags --libs` | $ gcc -o hellosdl hellosdl.c `sdl2-config --cflags --libs` |
Все откомпилировалось. НО! Если мы попытаемся теперь запустить эту программу из CMD.EXE (просто из Windows), мы получим ошибку:\\ | Все откомпилировалось. НО! Если мы попытаемся теперь запустить эту программу из CMD.EXE (или просто кликнуть из проводника Windows), мы получим ошибку:\\ |
"Запуск программы невозможен, так как на компьютере отсутствует SDL2.dll .\\ | "Запуск программы невозможен, так как на компьютере отсутствует SDL2.dll .\\ |
Попробуйте переустановить программу."\\ | Попробуйте переустановить программу."\\ |
Это неудивительно, так как полученная программа требует для своей работы ''SDL2.DLL'', | Это неудивительно, так как полученная программа требует для своей работы ''SDL2.DLL'', |
а она пока доступна только "изнутри" среды **MSYS2**. Можно пойти двумя путями: первый - установить | а она пока доступна только "изнутри" среды **MSYS2**. Можно пойти двумя путями: первый - установить |
''SDL2.DLL'' "в систему", второй: просто положить ''SDL2.DLL'' в каталог с программой. Тогда за | ''SDL2.DLL'' "в систему" (в C:\Windows\System32), второй: просто положить ''SDL2.DLL'' в каталог с программой. Тогда за |
счет известной особенности Windows "use local DLL" программа при запуске найдет нужную | счет известной особенности Windows "use local DLL" программа при запуске найдет нужную |
DLL и подключит. Скачаем нужный runtime (например 32-битный) на сайте | DLL и подключит. Скачаем нужный runtime (например 32-битный) на сайте |
будут только от "стандартных" DLL имеющихся в Windows. | будут только от "стандартных" DLL имеющихся в Windows. |
| |
==== OpenGL через SDL ==== | ==== OpenGL через SD2L ==== |
| |
Наконец, существует возможность - использовать уже знакомую нам SDL для "склейки" операционной | Наконец, существует возможность - использовать уже знакомую нам SDL2 для "склейки" операционной |
системы и OpenGL. Это намного удобнее т.к. в SDL имеются функции ввода, управления | системы и OpenGL вместо GLU или GLUT. Это намного удобнее т.к. в SDL2 имеются функции ввода, управления |
манипуляторами, звуком, сетью и т.д. и самое главное - обе библиотеки кросс-платформенные. | манипуляторами, звуком, сетью и т.д. и самое главное - обе библиотеки кросс-платформенные. |
| |
<to be continued...> | <to be continued...> |
| |
| https://ps-group.github.io/opengl/ |
| |
| https://ps-group.github.io/opengl/lesson_1 |
| |
| ==== Интеграция MSYS2 и VSCode ==== |
| |
| Для удобства программирования будет полезным использовать новомодную "оболочку" [[https://code.visualstudio.com/|VSCode]]. |
| |
| VSCode для Windows поставляется как минимум двух разновидностей: "системная" и "юзеровская". Ставьте системную (скачайте "System Installer" на [[https://code.visualstudio.com/download|странице загрузки]]). Она пропишет себя в путь PATH и т.д. Чтобы **MSYS2** брала системые пути из PATH, нужно в соотвествующем .ini файле (например C:\msys64\mingw32.ini) раскомментировать параметр ''MSYS2_PATH_TYPE=inherit'' |
| |
| Для работы надо запускать VSCode **из MSYS2** а точнее, прямо из командной строки той среды, под которую мы собираем (например "MSYS2 MinGW 32bit"). Это даст VSCode возможность правильно найти пути к нужным компиляторам и библиотекам. |
| |
| Запускать VSCode надо прямо из папки (workspace), в которой мы ведем разработку, то есть "''cd myproject ; Code . &''" (обратите внимание на точку ''.'' что означает: взять текущий каталог как workspace. Знак ''&'' применяется для запуска VSCode в фоне и "отсоединения" консоли). При первом запуске будет создан подкаталог ".vscode" в котором будут лежать файлы .json конфигурации проекта. |
| |
| Для среды **MSYS2 MinGW 32bit** и т.д. VSCode во встроенном терминале будет использоваться PowerShell в качестве оболочки вместо ''sh'', поскольку мы собираем виндовую, независимую от **MSYS2** программу. (Если мы будем собирать под среду **MSYS2 MSYS** то будет использоваться родной ''sh''). |
| |
| [[https://code.visualstudio.com/docs/cpp/config-mingw|Get Started with C++ and MinGW-w64 and Visual Studio Code]] |
==== Дополнительное чтение ==== | ==== Дополнительное чтение ==== |
| |