PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Desenvolvendo PostgreSQL para Windows, Parte 1


Como desenvolvedor PostgreSQL, ocasionalmente preciso fazer meu código funcionar no Windows. Como normalmente não uso o Windows e não tenho uma instalação permanente do Windows, isso sempre foi um pouco complicado. Eu desenvolvi algumas técnicas para tornar isso mais fácil, e acho que vale a pena compartilhar. E na verdade esse texto ficou bem longo, então essa será uma série de vários posts no blog.

A primeira coisa que é útil entender são os diferentes alvos de compilação do Windows variantes e como eles são semelhantes e diferentes.

A principal maneira de compilar para Windows é usar o Microsoft Visual Studio pacote do compilador. Este é o que você poderia pensar como o ambiente mais nativo. A maioria, senão todas as distribuições binárias do PostgreSQL para Windows, usam essa compilação. Esta compilação não usa os makefiles normais do Unix, mas um sistema de compilação separado em src/tools/msvc/ . Isso analisa os makefiles e tem alguma lógica personalizada e cria arquivos de “projeto” específicos para essa cadeia de ferramentas, que você pode executar para compilar o código. Vamos chamar isso de compilação MSVC aqui. Esta compilação é propensa a quebrar de duas maneiras:uma, se o código não for realmente compilado ou executado no Windows, e dois, se você alterar algo no sistema de compilação normal (baseado em makefiles) que faz com que esses scripts ad-hoc pausa. Então é sempre muito divertido lidar com isso.

A segunda maneira é usar o MinGW . Isso usa a cadeia de ferramentas GNU (GCC, GNU binutils, GNU ld, etc.) para construir código nativo no Windows. Você pode pensar nisso como “GCC no Windows”, mas na realidade ele contém calços e cola adicionais para fazer a interface com as bibliotecas do sistema Windows. Isso usa o sistema de compilação normal do Unix usando configure e makefiles, mas o código que produz é o código nativo do Windows, em princípio equivalente à saída da compilação MSVC. Isso também significa que, se o código não for compilado ou executado com a compilação MSVC, ele também não será compilado ou executado aqui. Mas o sistema de compilação é o mesmo do Linux etc., então será mais difícil quebrar acidentalmente.

A terceira maneira é Cygwin . Cygwin é um subsistema que apresenta um ambiente semelhante ao POSIX no Windows. Por exemplo, Cygwin adiciona usuários, grupos, fork() , memória compartilhada SysV e outros recursos que não existem no Windows nativo, mas são padrão no, digamos, Linux. A ideia é que você possa pegar o código-fonte destinado ao Linux ou BSD e construí-lo no Cygwin sem alterações (ou pelo menos com apenas alterações que estariam dentro do intervalo típico de alterações de portabilidade entre sistemas semelhantes ao Unix). Por esta razão, uma porta Cygwin do PostgreSQL existia muito antes da porta nativa do Windows, porque era um esforço muito menor. Na prática, a abstração falha em algumas áreas, especialmente no código de rede e em torno da nomeação e acesso a arquivos, mas em geral a compilação do Cygwin quebra muito raramente em comparação com os outros alvos.

Costumava haver outra maneira de construir no Windows. Havia win32.mak arquivos que você poderia usar diretamente com nmake no Windows, e também havia suporte para compiladores Borland em algum momento. Essas eram basicamente medidas provisórias para construir apenas libpq nativamente no Windows antes que a porta nativa completa chegasse. Estes já foram removidos.

Há outro termo que aparece neste contexto:MSYS . A razão para isso é que o MinGW por si só não costuma ser útil. É apenas uma cadeia de ferramentas do compilador. Mas para construir um software Unix típico, você precisa de ferramentas adicionais como bash, make, sed, grep e todas aquelas coisas que são normalmente usadas em um script de configuração ou um makefile. Essas ferramentas não existem como portas nativas do Windows. Mas você pode executá-los no subsistema Cygwin. Portanto, uma maneira de usar o MinGW é de dentro do Cygwin. Outro é o MSYS, que significa “sistema mínimo”, que é, grosso modo, um subconjunto personalizado do Cygwin e alguns pacotes especificamente para usar o MinGW para a construção de software. O MSYS original está abandonado até onde eu sei, mas existe uma nova alternativa popular MSYS2. Mais sobre isso em uma postagem de blog subsequente. Por enquanto, apenas entenda a relação entre todos esses diferentes pacotes de software.

Agora vamos considerar como o código-fonte vê esses diferentes ambientes de compilação.

Uma compilação nativa usando MSVC ou MinGW define _WIN32 . (Estranhamente, esse é o caso para compilações de 32 bits e 64 bits. Uma compilação de 64 bits também define _WIN64 , mas isso raramente é usado.) O código-fonte do PostgreSQL usa WIN32 em vez disso, mas isso é específico do PostgreSQL, não feito pelo compilador.

MSVC também define _MSC_VER para algum número de versão. Isso às vezes é útil para contornar problemas com uma versão específica do compilador (geralmente o tipo de coisa que as compilações do Unix tendem a usar o configure). Observe que o MinGW não define _MSC_VER , então o código precisa ser escrito com cuidado para lidar com isso também. Houve alguns pequenos bugs em torno disso porque códigos como #if _MSC_VER < NNNN talvez solucionar um problema com um compilador mais antigo também seria acionado no MinGW, o que pode não ter sido pretendido. (Mais correto seria #if defined(_MSC_VER) && _MSC_VER < NNNN e, claro, envolver em #ifdef WIN32 .) MinGW define __MINGW32__ e __MINGW64__ , mas estes são muito raramente usados. Além disso, é claro que o MinGW define __GNUC__ como é GCC, o código condicional específico para GCC ou uma versão do GCC também pode ser usado. Em geral, como o MinGW usa o Autoconf, essas coisas geralmente devem ser verificadas em configure em vez de no código.

Cygwin define __CYGWIN__ . Notavelmente, Cygwin não define _WIN32 , ou WIN32 , e assim por diante — porque não se considera Windows nativo. É por isso que em algumas áreas de código onde o Windows espia através da abstração Cygwin você vê muito código com #if defined(WIN32) ||
defined(__CYGWIN__)
para lidar com os dois casos.

(Existem alguns cantos empoeirados no código que nem sempre lidam com todas essas definições do pré-processador de maneira sensata e consistente. Em alguns casos, isso é intencional porque a realidade é estranha, em outros casos é um código podre e incorreto que precisa ser limpo.)

Cada um desses destinos existe em princípio como uma variante de 32 bits e de 64 bits. Uma instalação do sistema operacional Windows de 64 bits, que é a instalação moderna normal, pode executar software de 32 bits e 64 bits, para que você possa instalar e executar ambas as variantes em tal sistema. Uma instalação de produção provavelmente deve usar uma compilação de 64 bits e, portanto, você pode optar por não se preocupar com o ambiente de 32 bits. Na verdade, a variante de 32 bits do Cygwin parece estar bem morta e você pode não conseguir fazê-lo funcionar. Um problema, no entanto, é que o MinGW de 64 bits tem alguns bugs obscuros; portanto, ao usar o MinGW especialmente, às vezes é melhor usar o ambiente de 32 bits, a menos que você queira combater bugs do sistema operacional ou da cadeia de ferramentas. No entanto, a computação de 32 bits obviamente está saindo em geral, portanto, essa não é uma opção à prova de futuro.

Agora a questão talvez seja qual desses ambientes é “o melhor”. No que diz respeito ao desenvolvimento, isso realmente não importa, porque todo o código precisa funcionar em todos eles. Como mencionei acima, a compilação MSVC é usada para a maioria das implantações de produção do Windows. O ambiente MinGW (ou melhor, MSYS2) é melhor para desenvolver se você estiver acostumado a um ambiente semelhante ao Unix, mas especialmente o ambiente MinGW de 64 bits parece ser um pouco problemático, por isso é difícil recomendá-lo para produção. Cygwin pode ser considerado por alguns como uma curiosidade histórica neste momento. Executar um servidor de produção no Cygwin não é recomendado porque o desempenho é muito ruim. Mas o Cygwin é realmente útil em algumas situações. Por exemplo, Readline não funciona em nenhuma das compilações nativas do Windows, mas sim no Cygwin, portanto, se você for um usuário do psql, é melhor usar uma compilação Cygwin para isso. Além disso, o Cygwin é útil na situação inversa desta postagem de blog:você é um desenvolvedor principalmente do Windows e deseja garantir que seu código seja compatível principalmente com o Unix. Portanto, todos esses três ambientes têm seu valor e valem a pena serem mantidos neste momento.

Na próxima parte desta série, discutirei algumas técnicas para testar alterações de código no e para Windows se não for seu ambiente de desenvolvimento principal.