Se estiver pensando em distribuir seus próprios módulos de extensão do PostgreSQL, configurar um sistema de construção portável para eles poderá ser bastante difícil. Por isso, a instalação do PostgreSQL fornece uma infra-estrutura de construção para extensões, chamada PGXS, para que módulos de extensão simples possam ser construídos em um servidor já instalado. O PGXS destina-se principalmente a extensões que incluem código C, embora também possa ser usado para extensões que consistem exclusivamente em código SQL. Deve-se observar que o PGXS não pretende ser uma estrutura de sistema de construção universal, que pode ser usada para construir qualquer interface de software para o PostgreSQL; o PGXS simplesmente automatiza regras de construção comuns para módulos de extensão simples. Para pacotes mais complexos, pode ser necessário escrever seu próprio sistema de construção.
Para usar a infra-estrutura PGXS para a extensão,
deve ser escrito um arquivo de construção
Makefile simples.
No arquivo de construção, é necessário definir algumas variáveis, e
incluir o arquivo de construção global PGXS.
A seguir está um exemplo que constrói um módulo de extensão chamado
isbn_issn, consistindo em uma biblioteca
compartilhada contendo algum código C, um arquivo
de controle de extensão, um script SQL, um arquivo
de inclusão (necessário apenas se outros módulos precisarem acessar
as funções da extensão sem passar pelo SQL),
e um arquivo texto de documentação:
MODULES = isbn_issn EXTENSION = isbn_issn DATA = isbn_issn--1.0.sql DOCS = README.isbn_issn HEADERS_isbn_issn = isbn_issn.h PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS)
As últimas três linhas devem ser sempre as mesmas. No início do arquivo, são atribuídos valores às variáveis, ou adicionadas regras personalizadas ao make.
Deve ser definida uma dessas três variáveis para especificar o que será construído:
MODULES #lista de objetos de biblioteca compartilhada a serem construídos a partir de arquivos-fonte no mesmo tronco (não são incluídos sufixos de biblioteca nessa lista)
MODULE_big #
uma biblioteca compartilhada a ser construída a partir de vários
arquivos-fonte
(arquivos objeto listados em OBJS)
PROGRAM #
um programa executável a ser construído
(arquivos objeto listados em OBJS)
Também podem ser definidas as seguintes variáveis:
EXTENSION #
nome(s) da(s) extensão(ões); para cada nome deve ser fornecido
um arquivo ,
que será instalado em
extensão.controlprefixo/share/extensão
MODULEDIR #
subdiretório de
onde os arquivos DATA e DOCS devem ser instalados
(se não for definido, o padrão é prefixo/shareextensão,
se EXTENSION for definido,
ou contrib, se não for)
DATA #
arquivos aleatórios para instalar em
prefixo/share/$MODULEDIR
DATA_built #
arquivos aleatórios para instalar em
,
que precisam ser construídos primeiro
prefixo/share/$MODULEDIR
DATA_TSEARCH #
arquivos aleatórios para instalar sob
prefixo/share/tsearch_data
DOCS #
arquivos aleatórios para instalar sob
prefixo/doc/$MODULEDIR
HEADERSHEADERS_built #
Arquivos para (opcionalmente construir e) instalar sob
.
prefixo/include/server/$MODULEDIR/$MODULE_big
Ao contrário de DATA_built, os arquivos em
HEADERS_built não são removidos pelo destino
clean; se for desejado removê-los, devem ser
adicionados também a EXTRA_CLEAN, ou
adicionadas suas próprias regras para fazer isso.
HEADERS_$MODULEHEADERS_built_$MODULE #
Arquivos para instalar (após a construção, se especificado) sob
,
onde prefixo/include/server/$MODULEDIR/$MODULE$MODULE deve ser um nome de módulo usado
em MODULES ou MODULE_big.
Ao contrário de DATA_built, os arquivos em
HEADERS_built_$MODULE não são removidos pelo
destino clean; se for desejado removê-los,
devem ser adicionados também a EXTRA_CLEAN,
ou adicionadas suas próprias regras para fazer isso.
É legal usar as duas variáveis para o mesmo módulo, ou qualquer
combinação, a menos que se tenha dois nomes de módulo na lista
MODULES que diferem apenas pela presença de
um prefixo built_, o que causaria ambiguidade.
Nesse caso (espera-se que improvável), devem ser usadas apenas
as variáveis HEADERS_built_$MODULE.
SCRIPTS #
arquivos de script (não binários) para instalar em
prefixo/bin
SCRIPTS_built #
arquivos de script (não binários) para instalar em
,
que precisam ser construídos primeiro
prefixo/bin
REGRESS #lista de casos de teste de regressão (sem sufixo), veja abaixo
REGRESS_OPTS #chaves adicionais para passar para pg_regress
ISOLATION #lista de casos de teste de isolamento, veja abaixo para obter mais informações
ISOLATION_OPTS #chaves adicionais para passar para pg_isolation_regress
TAP_TESTS #chave definindo se os testes TAP precisam ser executados, veja abaixo
NO_INSTALL #
não definir um destino install, útil para
módulos de teste que não precisam que seus produtos de
construção sejam instalados
NO_INSTALLCHECK #
não definir um destino installcheck,
útil por exemplo, se os testes exigirem configuração especial,
ou não usar pg_regress
EXTRA_CLEAN #
arquivos extras para remover em make clean
PG_CPPFLAGS #
será anexado a CPPFLAGS
PG_CFLAGS #
será anexado a CFLAGS
PG_CXXFLAGS #
será anexado a CXXFLAGS
PG_LDFLAGS #
será acrescentado antes de LDFLAGS
PG_LIBS #
será adicionado à linha de ligação de PROGRAM
SHLIB_LINK #
será adicionado à linha de ligação de MODULE_big
PG_CONFIG #
caminho para o programa pg_config
da instalação do PostgreSQL, para
construir a biblioteca ou o executável
(normalmente apenas pg_config, para ser usado
o primeiro encontrado em seu PATH)
Esse arquivo de construção deve ser colocado como
Makefile no diretório que contém a extensão.
Então poderá ser executado make para construir,
e depois make install para instalar o módulo.
Por padrão, a extensão é construída e instalada na instalação do
PostgreSQL que corresponde ao primeiro
programa pg_config encontrado em
PATH.
Pode ser usada uma instalação diferente definindo
PG_CONFIG para apontar para outro programa
pg_config, dentro do arquivo de construção,
ou na linha de comando do make.
Pode ser escolhido um prefixo de diretório diferente para instalar
os arquivos da extensão definindo a variável prefix
do comando make ao executar
make install, como:
make install prefix=/usr/local/postgresql
Esse comando irá instalar o controle de extensão e os arquivos
SQL no diretório
/usr/local/postgresql/share
e os módulos compartilhados em
/usr/local/postgresql/lib.
Se o prefixo não incluir as cadeias de caracteres
postgres ou pgsql como,
por exemplo
make install prefix=/usr/local/extras
então será acrescentado postgresql aos nomes
dos diretórios, instalando os arquivos de controle e
SQL em
/usr/local/extras/share/postgresql/extension
e os módulos compartilhados em
/usr/local/extras/lib/postgresql.
De qualquer maneira, será necessário definir
extension_control_path e
dynamic_library_path para permitir que o
servidor PostgreSQL encontre os arquivos:
extension_control_path = '/usr/local/extras/share/postgresql:$system' dynamic_library_path = '/usr/local/extras/lib/postgresql:$libdir'
Também pode ser executado o make em um diretório
fora da árvore de fontes da extensão, se for desejado manter o
diretório de compilação separado.
Esse procedimento também é chamado de construção
VPATH.
Abaixo é mostrado como fazer isso:
mkdir build_dir cd build_dir make -f /path/to/extension/source/tree/Makefile make -f /path/to/extension/source/tree/Makefile install
Como alternativa, pode ser configurado um diretório para uma
construção VPATH de maneira semelhante à forma
como é feito para o código principal.
Uma maneira de fazer isso é usando o script principal
config/prep_buildtree.
Feito isso, pode-se construir definindo a variável
make VPATH assim:
make VPATH=/path/to/extension/source/tree make VPATH=/path/to/extension/source/tree install
Esse procedimento pode funcionar com uma variedade maior de modelos de diretório.
Os scripts listados na variável REGRESS são
usados para teste de regressão do módulo, que pode ser chamado por
make installcheck após executar
make install.
Para isso funcionar, deve haver um servidor
PostgreSQL em execução.
Os arquivos de script listados em REGRESS devem
estar em um subdiretório denominado sql/ no
diretório da extensão.
Esses arquivos devem ter extensão .sql, que não
deve ser incluída na lista REGRESS no
Makefile.
Para cada teste também deve haver um arquivo contendo a saída
esperada em um subdiretório chamado expected/,
com o mesmo tronco e extensão .out.
O comando make installcheck executa cada script
de teste usando o psql, e compara a saída
resultante com o arquivo correspondente esperado.
Quaisquer diferenças são escritas no arquivo
regression.diffs, no formato
diff -c.
Note que tentar executar um teste que não possui o arquivo
esperado será relatado como “problema”, portanto,
certifique-se de existirem todos os arquivos esperados.
Os scripts listados na variável ISOLATION são
usados para testar o comportamento sob pressão de sessão concorrente
com o módulo, que pode ser chamado executando
make installcheck após executar
make install.
Para isso funcionar, deve haver um servidor
PostgreSQL em execução.
Os arquivos de script listados em ISOLATION devem
estar em um subdiretório denominado specs/
no diretório da extensão.
Esses arquivos devem ter a extensão .spec,
que não deve ser incluída na lista ISOLATION
no Makefile.
Para cada teste também deve haver um arquivo contendo a saída
esperada em um subdiretório chamado expected/,
com o mesmo tronco e extensão .out.
O comando make installcheck executa cada script
de teste e compara a saída resultante com o arquivo esperado
correspondente.
Quaisquer diferenças encontradas serão escritas no arquivo
output_iso/regression.diffs no formato
diff -c.
Note que tentar executar um teste que não possui o arquivo de
saída esperado será relatado como “problema”, portanto,
certifique-se de ter todos os arquivos esperados.
TAP_TESTS ativa o uso de testes TAP
(Test Anything Protocol).
Os dados de cada execução estão presentes em um subdiretório chamado
tmp_check/.
Veja também a Seção 31.4 para obter mais detalhes.
A maneira mais fácil de criar os arquivos esperados é criar
arquivos vazios e, em seguida, executar um teste
(que, é claro, irá relatar as diferenças).
Inspecione os arquivos de resultados reais encontrados no diretório
results/
(para os testes em REGRESS),
ou no diretório output_iso/results/
(para os testes em ISOLATION), em seguida,
copie-os para expected/ se corresponderem
ao que se espera do teste.