С точки зрения переноса программы на C, хороший способ понять это - взять пример:
#include <sys/stat.h>
#include <stdlib.h>
int main(void)
{
struct stat stbuf;
stat("c:foo.txt", &stbuf);
system("command");
printf("Hello, World\n");
return 0;
}
Если мы изменим stat
на _stat
, мы можем скомпилировать эту программу с помощью Microsoft Visual C. Мы также можем скомпилировать эту программу с MinGW и с Cygwin.
В Microsoft Visual C программа будет связана с распространяемой библиотекой времени выполнения MSVC: mxvcrtnn.dll
, где nn
- суффикс версии. Чтобы отправить эту программу, нам нужно будет включить эту DLL. Эта DLL предоставляет _stat
, system
и printf
.
В рамках MinGW программа будет связана с msvcrt.dll
, которая представляет собой внутреннюю недокументированную неверсированную библиотеку, которая является частью Windows и запрещена для использования в приложениях. Эта библиотека по сути является форком распространяемой библиотеки времени выполнения из MS Visual C для использования самой Windows.
В обоих случаях программа будет работать аналогично:
- функция
stat
будет возвращать очень ограниченную информацию - например, никаких полезных разрешений или номера inode.
- путь
c:file.txt
разрешается в соответствии с текущим рабочим каталогом, связанным с диском c:
.
system
использует cmd.exe /c
для запуска внешней команды.
Мы также можем скомпилировать программу под Cygwin. Аналогично распространяемой среде выполнения, используемой MS Visual C, программа Cygwin будет связана с библиотеками времени выполнения Cygwin: cygwin1.dll
(собственно Cygwin) и cyggcc_s-1.dll
(поддержка времени выполнения GCC). Поскольку Cygwin теперь находится под LGPL, мы можем упаковать нашу программу, даже если она не совместима с GPL, и отправить ее.
В Cygwin функции библиотеки будут работать по-разному:
- функция
stat
обладает широкими функциональными возможностями, возвращая значимые значения в большинстве полей.
- путь
c:file.txt
вообще не понимается как содержащий букву диска, так как c:
не сопровождается косой чертой. Двоеточие считается частью имени и каким-то образом искажено. В Cygwin отсутствует концепция относительного пути к тому или диску, отсутствует концепция «текущий зарегистрированный диск» и текущий рабочий каталог для каждого диска.
- функция
system
пытается использовать интерпретатор /bin/sh -c
. Cygwin разрешит путь /
в соответствии с расположением вашего исполняемого файла и ожидает, что программа sh.exe
будет совмещена с вашим исполняемым файлом.
Как Cygwin, так и MinGW позволяют вам использовать функции Win32. Если вы хотите позвонить MessageBox
или CreateProcess
, вы можете сделать это. Вы также можете легко создать программу, для которой не требуется консольное окно, используя gcc -mwindows
, под MinGW и Cygwin.
Cygwin не является строго POSIX. В дополнение к предоставлению доступа к API Windows, он также предоставляет свои собственные реализации некоторых функций Microsoft C (вещи, найденные в msvcrt.dll
или во время распространения msvcrtnn.dll
). Примером этого является семейство функций spawn*
, например spawnvp
. Это хорошая идея, чтобы использовать вместо fork
и exec
в Cygwin, поскольку они лучше соответствуют модели создания процессов Windows, которая не имеет понятия fork
.
Таким образом:
Программы Cygwin не менее "родные", чем программы MS Visual C, по причине необходимости сопровождения библиотек. Ожидается, что реализации на языке программирования в Windows будут иметь свои собственные реализации, даже на языке Си. В Windows нет общедоступного libc.
Тот факт, что MinGW не требует сторонних DLL, на самом деле является недостатком; это зависит от недокументированного внутреннего Windows-форка среды выполнения Visual C. MinGW делает это, потому что исключение системной библиотеки GPL применяется к msvcrt.dll
, что означает, что программы под редакцией GPL можно компилировать и распространять с помощью MinGW.
Благодаря более широкой и глубокой поддержке POSIX по сравнению с msvcrt.dll
, Cygwin на сегодняшний день является превосходной средой для переноса программ POSIX. Поскольку теперь он находится под лицензией LGPL, он позволяет распространять приложения со всеми видами лицензий с открытым или закрытым исходным кодом. Cygwin даже содержит эмуляцию VT100 и termios
, которые работают с консолью Microsoft! Приложение POSIX, которое устанавливает сырой режим с tcsetattr
и использует коды VT100 для управления курсором, будет работать прямо в окне cmd.exe
. Что касается конечного пользователя, то это собственное консольное приложение, которое выполняет вызовы Win32 для управления консолью.
Тем не менее:
- Как собственный инструмент разработки для Windows, у Cygwin есть некоторые особенности, такие как обработка путей, чуждая Windows, зависимость от некоторых жестко заданных путей, таких как
/bin/sh
, и другие проблемы. Именно эти различия делают программы Cygwin «неродными». Если программа принимает путь в качестве аргумента или ввод из диалогового окна, пользователи Windows ожидают, что этот путь будет работать так же, как и в других программах Windows. Если это не работает, это проблема.
Plug: Вскоре после анонса LGPL я запустил проект Cygnal (библиотека собственных приложений Cygwin), чтобы предоставить ветвь библиотеки Cygwin DLL, целью которой является решение этих проблем. Программы могут быть разработаны под Cygwin, а затем развернуты с версией Cygnal cygwin1.dll
без перекомпиляции. По мере улучшения этой библиотеки она постепенно устранит необходимость в MinGW.
Когда Cygnal решит проблему с обработкой путей, появится возможность разработать один исполняемый файл, который будет работать с путями Windows при поставке в виде приложения Windows с Cygnal и без проблем работать с путями Cygwin при установке в /usr/bin
под Cygwin. Под Cygwin исполняемый файл будет прозрачно работать с путем, подобным /cygdrive/c/Users/bob
. В нативном развертывании, где он ссылается на версию cygwin1.dll
Cygnal, этот путь не будет иметь смысла, тогда как он будет понимать c:foo.txt
.