sql >> Base de Datos >  >> RDS >> PostgreSQL

Desarrollando PostgreSQL para Windows, Parte 1

Como desarrollador de PostgreSQL, ocasionalmente necesito hacer que mi código funcione en Windows. Como normalmente no uso Windows y no tengo una instalación permanente de Windows, esto siempre ha sido un poco engorroso. He desarrollado algunas técnicas para hacer esto más fácil, y creo que vale la pena compartirlas. Y en realidad este texto se volvió bastante largo, por lo que será una serie de varias publicaciones de blog.

Lo primero que es útil comprender son las diferentes variantes de objetivos de compilación de Windows y en qué se parecen y en qué se diferencian.

Podría decirse que la forma principal de compilar para Windows es usar Microsoft Visual Studio. paquete de compiladores. Esto es lo que se podría considerar como el entorno más nativo. La mayoría, si no todas, las distribuciones binarias de PostgreSQL para Windows usan esta compilación. Esta compilación no usa los makefiles normales de Unix, sino un sistema de compilación separado bajo src/tools/msvc/ . Esto analiza los archivos MAKE y tiene una lógica personalizada y crea archivos de "proyecto" específicos para esta cadena de herramientas, que luego puede ejecutar para compilar el código. Llamemos a esto la construcción de MSVC aquí. Esta compilación es propensa a romperse de dos maneras:una, si el código no se compila o ejecuta en realidad en Windows, y dos, si cambia algo en el sistema de compilación normal (basado en makefiles) que hace que esos scripts ad-hoc se ejecuten. romper. Así que siempre es muy divertido tratar con esto.

La segunda forma es usar MinGW . Esto utiliza la cadena de herramientas GNU (GCC, GNU binutils, GNU ld, etc.) para crear código nativo en Windows. Puede pensar en él como "GCC en Windows", pero en realidad contiene cuñas y pegamento adicionales para interactuar con las bibliotecas del sistema de Windows. Esto usa el sistema de compilación normal de Unix-ish usando configure y makefiles, pero el código que produce es código nativo de Windows, en principio equivalente a la salida de la compilación MSVC. Esto también significa que si el código no se compila ni se ejecuta con la compilación de MSVC, tampoco se compilará ni ejecutará aquí. Pero el sistema de compilación es el mismo que para Linux, etc., por lo que será más difícil romperlo accidentalmente.

La tercera forma es Cygwin . Cygwin es un subsistema que presenta un entorno similar a POSIX en Windows. Por ejemplo, Cygwin agrega usuarios, grupos, fork() , memoria compartida SysV y otras funciones que no existen en Windows nativo pero que son estándar en, por ejemplo, Linux. La idea es que podría tomar el código fuente destinado a Linux o BSD y construirlo bajo Cygwin sin cambios (o al menos con solo cambios que estarían dentro del rango típico de cambios de portabilidad entre sistemas similares a Unix). Por esta razón, existió un puerto Cygwin de PostgreSQL mucho antes que el puerto nativo de Windows, porque era un esfuerzo mucho menor. En la práctica, la abstracción falla en algunas áreas, especialmente en el código de red y en torno a la denominación y el acceso a los archivos, pero en general, la compilación de Cygwin rara vez se rompe en comparación con los otros objetivos.

Solía ​​haber otra forma de construir en Windows. Había win32.mak archivos que podría usar directamente con nmake en Windows, y también hubo soporte para los compiladores de Borland en algún momento. Estas fueron básicamente medidas provisionales para construir solo libpq de forma nativa en Windows antes de que llegara el puerto nativo completo. Ahora se han eliminado.

Hay otro término que aparece en este contexto:MSYS . La razón de esto es que MinGW por sí mismo no suele ser útil. Es solo una cadena de herramientas de compilación. Pero para construir software típico de Unix, necesita herramientas adicionales como bash, make, sed, grep y todas esas cosas que normalmente se usan desde un script de configuración o un archivo MAKE. No todas estas herramientas existen como puertos nativos de Windows. Pero puede ejecutarlos sobre el subsistema Cygwin. Entonces, una forma de usar MinGW es desde dentro de Cygwin. Otro es MSYS, que significa "sistema mínimo", que en términos generales es un subconjunto personalizado de Cygwin y algunos paquetes específicamente para usar MinGW para crear software. El MSYS original ahora está abandonado hasta donde yo sé, pero hay una nueva alternativa popular MSYS2. Más sobre esto en una publicación de blog posterior. Por ahora, comprenda la relación entre todos estos diferentes paquetes de software.

Ahora, consideremos cómo el código fuente ve estos diferentes entornos de compilación.

Una compilación nativa que usa MSVC o MinGW define _WIN32 . (Curiosamente, este es el caso de las compilaciones de 32 y 64 bits. Una compilación de 64 bits también define _WIN64 , pero rara vez se usa). El código fuente de PostgreSQL usa WIN32 en cambio, pero eso es específico de PostgreSQL, no lo hace el compilador.

MSVC también define _MSC_VER a algún número de versión. Esto a veces es útil para solucionar problemas con una versión particular del compilador (a menudo el tipo de cosas para las que las compilaciones de Unix tienden a usar configure). Tenga en cuenta que MinGW no define _MSC_VER , por lo que el código debe escribirse con cuidado para manejar eso también. Ha habido algunos errores menores en torno a esto porque código como #if _MSC_VER < NNNN quizás solucionar un problema con un compilador más antiguo también se activaría en MinGW, lo que podría no haber sido intencionado. (Más correcto sería #if defined(_MSC_VER) && _MSC_VER < NNNN y por supuesto envolver en #ifdef WIN32 .) MinGW define __MINGW32__ y __MINGW64__ , pero estos se utilizan muy raramente. Además, MinGW, por supuesto, define __GNUC__ dado que es GCC, también se puede usar el código condicional específico de GCC o una versión de GCC. En general, dado que MinGW usa Autoconf, esas cosas generalmente deben verificarse en configure en lugar de en el código.

Cygwin define __CYGWIN__ . En particular, Cygwin no define _WIN32 o WIN32 , etc., porque no se considera Windows nativo. Es por eso que en algunas áreas de código donde Windows se asoma a través de la abstracción de Cygwin, se ve mucho código con #if defined(WIN32) ||
defined(__CYGWIN__)
para manejar ambos casos.

(Hay algunos rincones polvorientos en el código que no siempre manejan todas estas definiciones de preprocesador de una manera sensata y consistente. En algunos casos, esto es intencional porque la realidad es rara, en otros casos es un código podrido e incorrecto que necesita ser limpiado.)

Cada uno de estos objetivos existe en principio como variante de 32 bits y de 64 bits. Una instalación del sistema operativo Windows de 64 bits, que es la instalación moderna normal, puede ejecutar software de 32 y 64 bits, por lo que puede instalar y ejecutar ambas variantes en dicho sistema. Una instalación de producción probablemente debería usar una compilación de 64 bits, por lo que puede optar por no molestarse con el entorno de 32 bits. De hecho, la variante de 32 bits de Cygwin parece estar bastante muerta y es posible que no pueda hacer que funcione en absoluto. Sin embargo, un problema es que MinGW de 64 bits tiene algunos errores oscuros, por lo que, especialmente cuando se usa MinGW, a veces es mejor usar el entorno de 32 bits, a menos que desee combatir los errores del sistema operativo o de la cadena de herramientas. Sin embargo, la computación de 32 bits obviamente está en su mayoría a punto de desaparecer en general, por lo que esta no es una opción preparada para el futuro.

Ahora la pregunta es quizás cuál de estos entornos es “el mejor”. En lo que respecta al desarrollo, realmente no importa porque todo el código debe funcionar en todos ellos. Como mencioné anteriormente, la compilación de MSVC se usa para la mayoría de las implementaciones de producción de Windows. El entorno MinGW (o más bien MSYS2) es más agradable de desarrollar si está acostumbrado a un entorno similar a Unix, pero especialmente el entorno MinGW de 64 bits parece tener algunos errores, por lo que es difícil recomendarlo para producción. Cygwin podría ser considerado por algunos como una curiosidad histórica en este momento. No se recomienda ejecutar un servidor de producción bajo Cygwin porque el rendimiento es bastante malo. Pero Cygwin es realmente útil en algunas situaciones. Por ejemplo, Readline no funciona en ninguna de las compilaciones nativas de Windows, pero sí en Cygwin, por lo que si es un usuario de psql, es mejor usar una compilación de Cygwin para eso. Además, Cygwin es útil en la situación inversa de esta publicación de blog:usted es un desarrollador principalmente de Windows y desea asegurarse de que su código sea compatible en su mayoría con Unix. Por lo tanto, estos tres entornos tienen su valor y vale la pena mantenerlos en este momento.

En la siguiente parte de esta serie, analizaré algunas técnicas para probar los cambios de código en y para Windows si no es su entorno de desarrollo principal.