Sebagai pengembang PostgreSQL, terkadang saya perlu membuat kode saya berfungsi di Windows. Karena saya biasanya tidak menggunakan Windows dan tidak memiliki instalasi Windows permanen, ini selalu agak merepotkan. Saya telah mengembangkan beberapa teknik untuk membuatnya lebih mudah, dan menurut saya itu layak untuk dibagikan. Dan sebenarnya teks ini menjadi cukup panjang, jadi ini akan menjadi rangkaian dari beberapa posting blog.
Hal pertama yang berguna untuk dipahami adalah berbagai varian target build Windows dan bagaimana mereka serupa dan berbeda.
Bisa dibilang, cara utama untuk membangun untuk Windows adalah menggunakan Microsoft Visual Studio paket kompiler. Inilah yang dapat Anda anggap sebagai lingkungan paling asli. Sebagian besar jika tidak semua distribusi biner PostgreSQL untuk Windows menggunakan build ini. Build ini tidak menggunakan makefile Unix normal tetapi sistem build terpisah di bawah src/tools/msvc/
. Ini mem-parsing makefile dan memiliki beberapa logika khusus dan membangun file "proyek" khusus untuk rantai alat ini, yang kemudian dapat Anda jalankan untuk membuat kode. Sebut saja ini build MSVC di sini. Build ini rentan rusak dalam dua cara:Pertama, jika kode tidak benar-benar dibuat atau dijalankan di Windows, dan kedua, jika Anda mengubah sesuatu dalam sistem build normal (berbasis makefile) yang menyebabkan skrip ad-hoc tersebut merusak. Jadi ini selalu menyenangkan untuk dihadapi.
Cara kedua adalah menggunakan MinGW . Ini menggunakan rantai alat GNU (GCC, GNU binutils, GNU ld, dll.) untuk membuat kode asli di Windows. Anda dapat menganggapnya sebagai "GCC di Windows", tetapi pada kenyataannya itu berisi shim dan lem tambahan untuk berinteraksi dengan perpustakaan sistem Windows. Ini menggunakan sistem build Unix-ish normal menggunakan configure dan makefiles, tetapi kode yang dihasilkannya adalah kode Windows asli, pada prinsipnya setara dengan output dari build MSVC. Ini juga berarti bahwa jika kode tidak dibuat atau dijalankan dengan build MSVC, kode tersebut juga tidak akan dibuat atau dijalankan di sini. Tetapi sistem pembuatannya sama seperti untuk Linux dll., jadi akan lebih sulit untuk rusak secara tidak sengaja.
Cara ketiga adalah Cygwin . Cygwin adalah subsistem yang menghadirkan lingkungan seperti POSIX di Windows. Misalnya, Cygwin menambahkan pengguna, grup, fork()
, memori bersama SysV, dan fasilitas lain yang tidak ada di Windows asli tetapi standar di, katakanlah, Linux. Idenya adalah bahwa Anda dapat mengambil kode sumber yang dimaksudkan untuk Linux atau BSD dan membangunnya di bawah Cygwin tanpa perubahan (atau setidaknya dengan hanya perubahan yang akan berada dalam kisaran khas perubahan port antara sistem mirip Unix). Untuk alasan ini, port Cygwin dari PostgreSQL ada jauh sebelum port Windows asli, karena upayanya jauh lebih kecil. Dalam praktiknya, abstraksi rusak di beberapa area, terutama dalam kode jaringan dan seputar penamaan dan akses file, tetapi secara umum build Cygwin sangat jarang rusak dibandingkan dengan target lainnya.
Dulu ada cara lain untuk membangun di Windows. Ada win32.mak
file yang dapat Anda gunakan langsung dengan nmake di Windows, dan ada juga dukungan untuk kompiler Borland di beberapa titik. Ini pada dasarnya adalah langkah-langkah sementara untuk membangun libpq secara asli di Windows sebelum port asli lengkap tiba. Ini sekarang telah dihapus.
Ada istilah lain yang muncul dalam konteks ini:MSYS . Alasan untuk ini adalah karena MinGW sendiri seringkali tidak berguna. Ini hanya rantai alat kompiler. Tetapi untuk membangun perangkat lunak khas Unix, Anda memerlukan alat tambahan seperti bash, make, sed, grep, dan semua hal yang biasanya digunakan dari skrip konfigurasi atau makefile. Alat-alat ini tidak semuanya ada sebagai port Windows asli. Tetapi Anda dapat menjalankannya di atas subsistem Cygwin. Jadi salah satu cara untuk menggunakan MinGW adalah dari dalam Cygwin. Lainnya adalah MSYS, yang merupakan singkatan dari "sistem minimal", yang secara kasar merupakan subset dari Cygwin yang dipesan lebih dahulu dan beberapa kemasan khusus untuk menggunakan MinGW untuk membangun perangkat lunak. MSYS asli sekarang ditinggalkan sejauh yang saya tahu, tetapi ada MSYS2 alternatif baru yang populer. Lebih lanjut tentang ini di posting blog berikutnya. Untuk saat ini, pahami saja hubungan antara semua paket perangkat lunak yang berbeda ini.
Sekarang mari kita pertimbangkan bagaimana kode sumber melihat lingkungan build yang berbeda ini.
Build asli menggunakan MSVC atau MinGW mendefinisikan _WIN32
. (Anehnya, ini berlaku untuk build 32-bit dan 64-bit. Build 64-bit juga mendefinisikan _WIN64
, tapi ini jarang digunakan.) Kode sumber PostgreSQL menggunakan WIN32
sebagai gantinya, tetapi itu khusus untuk PostgreSQL, tidak dilakukan oleh kompiler.
MSVC juga mendefinisikan _MSC_VER
ke beberapa nomor versi. Ini terkadang berguna untuk mengatasi masalah dengan versi kompiler tertentu (seringkali jenis hal yang dibangun oleh Unix cenderung menggunakan konfigurasi untuk). Perhatikan bahwa MinGW tidak mendefinisikan _MSC_VER
, jadi kode perlu ditulis dengan hati-hati untuk menanganinya juga. Ada beberapa bug kecil di sekitar ini karena kode seperti #if _MSC_VER < NNNN
untuk mungkin mengatasi masalah dengan kompiler yang lebih lama akan memicu pada MinGW juga, yang mungkin tidak dimaksudkan. (Lebih benar adalah #if defined(_MSC_VER) && _MSC_VER < NNNN
dan tentu saja bungkus menjadi #ifdef WIN32
.) MinGW mendefinisikan __MINGW32__
dan __MINGW64__
, tetapi ini sangat jarang digunakan. Juga, MinGW tentu saja mendefinisikan __GNUC__
karena ini adalah GCC, maka kode kondisional khusus untuk GCC atau versi GCC juga dapat digunakan. Secara umum, karena MinGW menggunakan Autoconf, hal-hal tersebut biasanya harus diperiksa di configure
alih-alih dalam kode.
Cygwin mendefinisikan __CYGWIN__
. Khususnya, Cygwin tidak mendefinisikan _WIN32
, atau WIN32
, dan seterusnya — karena tidak menganggap dirinya sebagai Windows asli. Itu sebabnya di beberapa area kode tempat Windows mengintip melalui abstraksi Cygwin Anda melihat banyak kode dengan #if defined(WIN32) ||
untuk menangani kedua kasus tersebut.
defined(__CYGWIN__)
(Ada beberapa sudut berdebu dalam kode yang tidak selalu menangani semua definisi praprosesor ini dengan cara yang masuk akal dan konsisten. Dalam beberapa kasus, ini disengaja karena kenyataannya aneh, dalam kasus lain kode busuk dan salah yang perlu dibersihkan.)
Masing-masing target ini pada prinsipnya ada sebagai varian 32-bit dan 64-bit. Instalasi sistem operasi Windows 64-bit, yang merupakan instalasi modern normal, dapat menjalankan perangkat lunak 32-bit dan 64-bit, sehingga Anda dapat menginstal dan menjalankan kedua varian pada sistem tersebut. Instalasi produksi mungkin harus menggunakan build 64-bit, jadi Anda mungkin memilih untuk tidak repot dengan lingkungan 32-bit. Faktanya, varian 32-bit Cygwin tampaknya sudah cukup mati, dan Anda mungkin tidak dapat membuatnya berfungsi sama sekali. Satu masalah, bagaimanapun, adalah bahwa 64-bit MinGW memiliki beberapa bug yang tidak jelas, jadi ketika menggunakan MinGW terutama terkadang lebih baik menggunakan lingkungan 32-bit, kecuali jika Anda ingin melawan bug sistem operasi atau rantai alat. Namun, komputasi 32-bit jelas sebagian besar sedang dalam perjalanan keluar secara umum, jadi ini bukan pilihan masa depan.
Sekarang pertanyaannya mungkin lingkungan mana yang "terbaik". Sejauh pengembangan berjalan, itu tidak terlalu penting karena semua kode perlu bekerja pada semuanya. Seperti yang saya sebutkan di atas, build MSVC digunakan untuk sebagian besar penyebaran produksi Windows. Lingkungan MinGW (atau lebih tepatnya MSYS2) lebih baik untuk dikembangkan jika Anda terbiasa dengan lingkungan seperti Unix, tetapi terutama lingkungan MinGW 64-bit tampaknya agak bermasalah, jadi sulit untuk merekomendasikan ini untuk produksi. Cygwin mungkin dianggap oleh beberapa orang sebagai keingintahuan bersejarah pada saat ini. Menjalankan server produksi di bawah Cygwin tidak disarankan karena kinerjanya cukup buruk. Tapi Cygwin sebenarnya berguna dalam beberapa situasi. Misalnya, Readline tidak berfungsi di salah satu build Windows asli, tetapi berfungsi di Cygwin, jadi jika Anda adalah pengguna psql, lebih baik menggunakan build Cygwin untuk itu. Juga, Cygwin berguna dalam situasi yang kebalikan dari posting blog ini:Anda adalah pengembang sebagian besar Windows dan ingin memastikan kode Anda sebagian besar kompatibel dengan Unix. Jadi ketiga lingkungan tersebut memiliki nilai dan layak dipertahankan saat ini.
Di bagian selanjutnya dari seri ini, saya akan membahas beberapa teknik untuk menguji perubahan kode pada dan untuk Windows jika itu bukan lingkungan pengembangan utama Anda.