PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Entwickeln von PostgreSQL für Windows, Teil 1

Als PostgreSQL-Entwickler muss ich gelegentlich meinen Code unter Windows zum Laufen bringen. Da ich normalerweise kein Windows nutze und auch keine permanente Windows-Installation in der Nähe habe, war das immer etwas umständlich. Ich habe ein paar Techniken entwickelt, um dies zu vereinfachen, und ich denke, sie sind es wert, geteilt zu werden. Und tatsächlich ist dieser Text ziemlich lang geworden, also wird dies eine Reihe von mehreren Blogposts.

Das erste, was nützlich ist, um zu verstehen, sind die verschiedenen Varianten von Windows-Build-Zielen und wie sie ähnlich und unterschiedlich sind.

Die wohl wichtigste Art, für Windows zu erstellen, ist die Verwendung von Microsoft Visual Studio Compiler-Suite. Dies könnte man sich als die ursprünglichste Umgebung vorstellen. Die meisten, wenn nicht alle binären Distributionen von PostgreSQL für Windows verwenden diesen Build. Dieser Build verwendet nicht die normalen Unix-Makefiles, sondern ein separates Build-System unter src/tools/msvc/ . Dies parst die Makefiles und verfügt über eine benutzerdefinierte Logik und erstellt „Projekt“-Dateien, die für diese Toolkette spezifisch sind, die Sie dann ausführen können, um den Code zu erstellen. Nennen wir dies hier den MSVC-Build. Dieser Build kann auf zwei Arten kaputt gehen:Erstens, wenn der Code nicht wirklich unter Windows erstellt oder ausgeführt wird, und zweitens, wenn Sie etwas im normalen (auf Makefiles basierenden) Build-System ändern, das diese Ad-hoc-Skripte dazu veranlasst brechen. Es macht also immer viel Spaß damit umzugehen.

Die zweite Möglichkeit ist die Verwendung von MinGW . Dies verwendet die GNU-Toolchain (GCC, GNU binutils, GNU ld usw.), um nativen Code unter Windows zu erstellen. Sie können es sich als „GCC unter Windows“ vorstellen, aber in Wirklichkeit enthält es zusätzliche Unterlegscheiben und Kleber, um eine Schnittstelle zu den Windows-Systembibliotheken herzustellen. Dies verwendet das normale Unix-artige Build-System unter Verwendung von configure und Makefiles, aber der erzeugte Code ist nativer Windows-Code, der im Prinzip der Ausgabe des MSVC-Builds entspricht. Dies bedeutet auch, dass Code, der nicht mit dem MSVC-Build erstellt oder ausgeführt wird, auch hier nicht erstellt oder ausgeführt wird. Aber das Build-System ist das gleiche wie für Linux etc., also wird es schwieriger sein, versehentlich zu brechen.

Der dritte Weg ist Cygwin . Cygwin ist ein Subsystem, das eine POSIX-ähnliche Umgebung unter Windows darstellt. Zum Beispiel fügt Cygwin Benutzer, Gruppen, fork() hinzu , SysV Shared Memory und andere Einrichtungen, die unter nativem Windows nicht vorhanden sind, aber beispielsweise unter Linux Standard sind. Die Idee ist, dass Sie den Quellcode, der für Linux oder BSD gedacht ist, nehmen und ihn ohne Änderungen unter Cygwin erstellen könnten (oder zumindest nur mit Änderungen, die im typischen Bereich der Portierung von Änderungen zwischen Unix-ähnlichen Systemen liegen würden). Aus diesem Grund gab es schon lange vor der nativen Windows-Portierung eine Cygwin-Portierung von PostgreSQL, weil es ein viel geringerer Aufwand war. In der Praxis bricht die Abstraktion in einigen Bereichen zusammen, insbesondere im Netzwerkcode und in der Nähe von Dateibenennung und -zugriff, aber im Allgemeinen bricht der Cygwin-Build im Vergleich zu den anderen Zielen sehr selten zusammen.

Früher gab es eine andere Möglichkeit, auf Windows aufzubauen. Es gab win32.mak Dateien, die Sie direkt mit nmake unter Windows verwenden konnten, und irgendwann gab es auch Unterstützung für Borland-Compiler. Dies waren im Grunde Notlösungen, um nur libpq nativ auf Windows zu bauen, bevor die vollständige native Portierung eingetroffen war. Diese wurden nun entfernt.

In diesem Zusammenhang taucht noch ein weiterer Begriff auf:MSYS . Der Grund dafür ist, dass MinGW selbst oft nicht nützlich ist. Es ist nur eine Compiler-Toolkette. Aber um typische Unix-Software zu bauen, brauchen Sie zusätzliche Werkzeuge wie bash, make, sed, grep und all die Dinge, die normalerweise von einem Konfigurationsskript oder einem Makefile verwendet werden. Diese Tools existieren nicht alle als native Windows-Ports. Sie können sie jedoch auf dem Cygwin-Subsystem ausführen. Eine Möglichkeit, MinGW zu verwenden, ist also von Cygwin aus. Ein weiteres ist MSYS, das für „Minimalsystem“ steht, was grob gesagt eine maßgeschneiderte Teilmenge von Cygwin und einige Pakete speziell für die Verwendung von MinGW zum Erstellen von Software ist. Soweit ich weiß, wird das ursprüngliche MSYS jetzt aufgegeben, aber es gibt eine beliebte neue Alternative MSYS2. Mehr dazu in einem späteren Blogbeitrag. Verstehe vorerst nur die Beziehung zwischen all diesen verschiedenen Softwarepaketen.

Betrachten wir nun, wie der Quellcode diese verschiedenen Build-Umgebungen sieht.

Ein nativer Build mit MSVC oder MinGW definiert _WIN32 . (Seltsamerweise ist dies sowohl bei 32-Bit- als auch bei 64-Bit-Builds der Fall. Ein 64-Bit-Build definiert auch _WIN64 , wird aber selten verwendet.) Der PostgreSQL-Quellcode verwendet WIN32 stattdessen, aber das ist spezifisch für PostgreSQL und wird nicht vom Compiler erledigt.

MSVC definiert auch _MSC_VER zu irgendeiner Versionsnummer. Dies ist manchmal nützlich, um Probleme mit einer bestimmten Compiler-Version zu umgehen (häufig würden Unix-Builds dazu neigen, configure zu verwenden). Beachten Sie, dass MinGW _MSC_VER nicht definiert , also muss der Code sorgfältig geschrieben werden, um auch damit umzugehen. Es gab einige kleinere Fehler, weil Code wie #if _MSC_VER < NNNN Um vielleicht ein Problem mit einem älteren Compiler zu umgehen, würde dies auch auf MinGW auslösen, was möglicherweise nicht beabsichtigt war. (Richtiger wäre #if defined(_MSC_VER) && _MSC_VER < NNNN und natürlich in #ifdef WIN32 umbrechen .) MinGW definiert __MINGW32__ und __MINGW64__ , aber diese werden sehr selten verwendet. Außerdem definiert MinGW natürlich __GNUC__ Da es sich um GCC handelt, kann auch GCC-spezifischer Bedingungscode oder eine GCC-Version verwendet werden. Da MinGW im Allgemeinen Autoconf verwendet, sollten diese Dinge normalerweise in configure überprüft werden statt im Code.

Cygwin definiert __CYGWIN__ . Insbesondere definiert Cygwin _WIN32 nicht , oder WIN32 , und so weiter – weil es sich selbst nicht als natives Windows betrachtet. Aus diesem Grund sehen Sie in einigen Codebereichen, in denen Windows durch die Cygwin-Abstraktion späht, viel Code mit #if defined(WIN32) ||
defined(__CYGWIN__)
um beide Fälle zu behandeln.

(Es gibt einige verstaubte Ecken im Code, die all diese Präprozessordefinitionen nicht immer vernünftig und konsistent handhaben. In einigen Fällen ist dies beabsichtigt, weil die Realität seltsam ist, in anderen Fällen ist es fauler und falscher Code, der sein muss aufgeräumt.)

Jedes dieser Targets existiert prinzipiell als 32-Bit- und als 64-Bit-Variante. Eine 64-Bit-Windows-Betriebssysteminstallation, die die normale moderne Installation ist, kann sowohl 32-Bit- als auch 64-Bit-Software ausführen, sodass Sie beide Varianten auf einem solchen System installieren und ausführen können. Eine Produktionsinstallation sollte wahrscheinlich einen 64-Bit-Build verwenden, und Sie könnten sich daher dafür entscheiden, sich nicht mit der 32-Bit-Umgebung zu beschäftigen. Tatsächlich scheint die 32-Bit-Variante von Cygwin ziemlich tot zu sein, und Sie können sie möglicherweise überhaupt nicht zum Laufen bringen. Ein Problem ist jedoch, dass 64-Bit-MinGW einige obskure Fehler aufweist. Wenn Sie also MinGW verwenden, ist es manchmal besser, die 32-Bit-Umgebung zu verwenden, es sei denn, Sie möchten Betriebssystem- oder Toolchain-Fehler bekämpfen. 32-Bit-Computing ist jedoch im Allgemeinen offensichtlich größtenteils auf dem Weg nach draußen, daher ist dies keine zukunftssichere Option.

Nun stellt sich vielleicht die Frage, welche dieser Umgebungen „die beste“ ist. Was die Entwicklung betrifft, spielt es keine Rolle, da der gesamte Code auf allen funktionieren muss. Wie oben erwähnt, wird der MSVC-Build für die meisten Produktionsbereitstellungen von Windows verwendet. Die MinGW- (oder eher MSYS2-) Umgebung ist angenehmer zum Entwickeln, wenn Sie an eine Unix-ähnliche Umgebung gewöhnt sind, aber insbesondere die 64-Bit-MinGW-Umgebung scheint etwas fehlerhaft zu sein, daher ist es schwierig, dies für die Produktion zu empfehlen. Cygwin könnte an dieser Stelle von einigen als historische Kuriosität angesehen werden. Das Betreiben eines Produktionsservers unter Cygwin wird nicht empfohlen, da die Leistung ziemlich schlecht ist. Aber Cygwin ist in einigen Situationen tatsächlich nützlich. Zum Beispiel funktioniert Readline auf keinem der nativen Windows-Builds, aber auf Cygwin. Wenn Sie also ein psql-Benutzer sind, ist es besser, dafür einen Cygwin-Build zu verwenden. Außerdem ist Cygwin in der Situation nützlich, die das Gegenteil dieses Blogbeitrags ist:Sie sind hauptsächlich Windows-Entwickler und möchten sicherstellen, dass Ihr Code größtenteils mit Unix kompatibel ist. Alle drei dieser Umgebungen haben also ihren Wert und sind es wert, zu diesem Zeitpunkt gepflegt zu werden.

Im nächsten Teil dieser Serie bespreche ich einige Techniken zum Testen von Codeänderungen unter und für Windows, wenn dies nicht Ihre primäre Entwicklungsumgebung ist.