Unter dem Gesichtspunkt der Portierung eines C-Programms können Sie dies am besten anhand eines Beispiels verstehen:
#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;
}
Wenn wir ändern stat
zu_stat
können wir dieses Programm mit Microsoft Visual C kompilieren. Wir können dieses Programm auch mit MinGW und mit Cygwin kompilieren.
Unter Microsoft Visual C wird das Programm mit einer MSVC-umverteilbaren Laufzeitbibliothek verknüpft: mxvcrtnn.dll
Hier nn
befindet sich ein Versionssuffix. Um dieses Programm zu versenden, müssen wir diese DLL einschließen. Das DLL stellt _stat
, system
undprintf
. (Wir haben auch die Möglichkeit, die Laufzeit statisch zu verknüpfen.)
Unter MinGW wird das Programm mit msvcrt.dll
einer internen, nicht dokumentierten, nicht versionierten Bibliothek verknüpft , die Teil von Windows ist und für die Verwendung durch Anwendungen nicht zulässig ist. Diese Bibliothek ist im Wesentlichen ein Zweig der weiterverteilbaren Laufzeitbibliothek von MS Visual C zur Verwendung durch Windows.
In beiden Fällen weist das Programm ein ähnliches Verhalten auf:
- Die
stat
Funktion gibt nur sehr begrenzte Informationen zurück, z. B. keine nützlichen Berechtigungen oder Inode-Nummern.
- Der Pfad
c:file.txt
wird gemäß dem aktuellen Arbeitsverzeichnis aufgelöst, das dem Laufwerk zugeordnet ist c:
.
system
wird cmd.exe /c
zum Ausführen des externen Befehls verwendet.
Wir können das Programm auch unter Cygwin kompilieren. Ähnlich wie die von MS Visual C verwendete umverteilbare Laufzeit wird das Cygwin-Programm mit den Laufzeitbibliotheken von Cygwin verknüpft: cygwin1.dll
(Cygwin selbst) und cyggcc_s-1.dll
(GCC-Laufzeitunterstützung). Da Cygwin jetzt unter der LGPL steht, können wir mit unserem Programm verpacken, auch wenn es keine GPL-kompatible freie Software ist, und das Programm ausliefern.
Unter Cygwin verhalten sich die Bibliotheksfunktionen anders:
- Die
stat
Funktion verfügt über umfangreiche Funktionen und gibt in den meisten Feldern aussagekräftige Werte zurück.
- Der Pfad
c:file.txt
enthält überhaupt keine Laufwerksbuchstabenreferenz, da c:
kein Schrägstrich folgt. Der Doppelpunkt wird als Teil des Namens betrachtet und irgendwie verstümmelt. In Cygwin gibt es kein Konzept für einen relativen Pfad für ein Volume oder Laufwerk, kein Konzept für "aktuell protokolliertes Laufwerk" und kein aktuelles Arbeitsverzeichnis pro Laufwerk.
- Die
system
Funktion versucht, den /bin/sh -c
Interpreter zu verwenden. Cygwin löst den /
Pfad entsprechend dem Speicherort Ihrer ausführbaren Datei auf und erwartet, dass sich ein sh.exe
Programm zusammen mit Ihrer ausführbaren Datei befindet.
Sowohl Cygwin als auch MinGW ermöglichen die Verwendung von Win32-Funktionen. Wenn Sie anrufen möchten MessageBox
oder CreateProcess
, können Sie dies tun. Sie können gcc -mwindows
unter MinGW und Cygwin auch problemlos ein Programm erstellen, für das kein Konsolenfenster erforderlich ist .
Cygwin ist nicht ausschließlich POSIX. Zusätzlich zum Zugriff auf die Windows-API bietet es auch eigene Implementierungen einiger Microsoft C-Funktionen (Dinge, die in msvcrt.dll
oder die wiederverteilbaren msvcrtnn.dll
Laufzeiten enthalten sind). Ein Beispiel hierfür sind die spawn*
Funktionsfamilien wie spawnvp
. Diese sind eine gute Idee anstelle von fork
und exec
auf Cygwin, da sie besser auf das Windows-Modell zur Prozesserstellung abgebildet werden, für das es kein Konzept gibt fork
.
Somit:
Cygwin-Programme sind nicht weniger "nativ" als MS Visual C-Programme, da sie die Begleitung von Bibliotheken erfordern. Von Programmiersprachenimplementierungen unter Windows wird erwartet, dass sie ihre eigene Laufzeit bereitstellen, sogar C-Sprachimplementierungen. Unter Windows gibt es keine "libc" für den öffentlichen Gebrauch.
Die Tatsache, dass MinGW keine DLL von Drittanbietern benötigt, ist tatsächlich ein Nachteil. Dies hängt von einem undokumentierten, Windows-internen Zweig der Visual C-Laufzeit ab. MinGW tut dies, weil die GPL-Systembibliotheksausnahme für gilt msvcrt.dll
, was bedeutet, dass GPL-ed-Programme mit MinGW kompiliert und neu verteilt werden können.
Aufgrund seiner viel breiteren und tieferen Unterstützung für POSIX im Vergleich zu msvcrt.dll
ist Cygwin bei weitem die überlegene Umgebung für die Portierung von POSIX-Programmen. Da es jetzt unter der LGPL steht, können Anwendungen mit allen Arten von Lizenzen, Open oder Closed Source, neu verteilt werden. Cygwin enthält sogar VT100-Emulation und termios
, die mit der Microsoft-Konsole funktionieren! Eine POSIX-Anwendung, die den Raw-Modus mit tcsetattr
VT100-Codes einrichtet und zur Steuerung des Cursors verwendet, funktioniert direkt im cmd.exe
Fenster. Für den Endbenutzer handelt es sich um eine native Konsolen-App, die Win32-Aufrufe zur Steuerung der Konsole ausführt.
Jedoch:
- Als natives Windows-Entwicklungstool weist Cygwin einige Besonderheiten auf, z. B. die für Windows fremde Pfadbehandlung, die Abhängigkeit von einigen fest codierten Pfaden wie
/bin/sh
und andere Probleme. Diese Unterschiede machen Cygwin-Programme "nicht nativ". Wenn ein Programm einen Pfad als Argument verwendet oder über ein Dialogfeld eingibt, erwarten Windows-Benutzer, dass dieser Pfad genauso funktioniert wie in anderen Windows-Programmen. Wenn es so nicht funktioniert, ist das ein Problem.
Plug: Kurz nach der LGPL-Ankündigung habe ich das Cygnal- Projekt (Cygwin Native Application Library) gestartet, um einen Zweig der Cygwin-DLL bereitzustellen, mit dem diese Probleme behoben werden sollen . Programme können unter Cygwin entwickelt und dann mit der Cygnal-Version von cygwin1.dll
ohne erneutes Kompilieren bereitgestellt werden . Wenn sich diese Bibliothek verbessert, wird MinGW nach und nach überflüssig.
Wenn Cygnal das Problem der Pfadbehandlung löst, kann eine einzelne ausführbare Datei entwickelt werden, die mit Windows-Pfaden funktioniert, wenn sie als Windows-Anwendung mit Cygnal ausgeliefert wird, und nahtlos mit Cygwin-Pfaden funktioniert, wenn sie /usr/bin
unter Cygwin installiert ist . Unter Cygwin arbeitet die ausführbare Datei transparent mit einem Pfad wie /cygdrive/c/Users/bob
. In der nativen Bereitstellung, in der eine Verknüpfung mit der Cygnal-Version von hergestellt wird cygwin1.dll
, ist dieser Pfad nicht sinnvoll, während er verstanden wird c:foo.txt
.