Si estás pensando en distribuir tus módulos de extensión de PostgreSQL, configurar un sistema de compilación portátil para ellos puede ser bastante difícil. Por lo tanto, la instalación de PostgreSQL proporciona una infraestructura de compilación para extensiones, llamada PGXS, para que los módulos de extensión simples se puedan compilar simplemente contra un servidor ya instalado. PGXS está destinado principalmente a extensiones que incluyen código en C, aunque también se puede utilizar para extensiones de solo SQL. Ten en cuenta que PGXS no está diseñado para ser un marco de sistema de compilación universal que se pueda utilizar para compilar cualquier software que interactúe con PostgreSQL; simplemente automatiza las reglas de compilación comunes para módulos de extensión de servidor simples. Para paquetes más complicados, es posible que necesites escribir tu propio sistema de compilación.
Para utilizar la infraestructura PGXS para tu extensión, debes escribir un makefile simple. En el makefile,
necesitas establecer algunas variables e incluir el archivo makefile global de PGXS. Aquí hay un ejemplo
que compila un módulo de extensión llamado isbn_issn, que consiste en una biblioteca compartida que contiene
código en C, un archivo de control de extensión, un script SQL, un archivo de cabecera (solo necesario si otros módulos pudieran
necesitar acceder a las funciones de la extensión sin pasar por SQL) y un archivo de texto de documentación:
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)
Las últimas tres líneas siempre deben ser las mismas. Anteriormente en el archivo, asignas variables o añades reglas de make personalizadas.
Establece una de estas tres variables para especificar qué se compila:
MODULES #lista de objetos de biblioteca compartida a compilar a partir de archivos fuente con el mismo nombre base (no incluyas sufijos de biblioteca en esta lista)
MODULE_big #
una biblioteca compartida para compilar a partir de múltiples archivos fuente (lista los archivos objeto en
OBJS)
PROGRAM #
un programa ejecutable a compilar (lista los archivos objeto en OBJS)
También se pueden configurar las siguientes variables:
EXTENSION #
nombre(s) de la(s) extensión(es); para cada nombre debes proporcionar un archivo
, que se instalará en
extension.controlprefix/share/extension
MODULEDIR #
subdirectorio de en el cual se deben instalar los archivos
DATA y DOCS (si no está configurado, el valor por defecto es prefix/shareextension si EXTENSION
está configurado, o contrib si no lo está)
DATA #
archivos arbitrarios a instalar en prefix/share/$MODULEDIR
DATA_built #
archivos arbitrarios a instalar en , los cuales
deben ser compilados primero
prefix/share/$MODULEDIR
DATA_TSEARCH #
archivos arbitrarios a instalar bajo prefix/share/tsearch_data
DOCS #
archivos arbitrarios a instalar bajo prefix/doc/$MODULEDIR
HEADERSHEADERS_built #
Archivos a (compilar y opcionalmente) instalar bajo
.
prefix/include/server/$MODULEDIR/$MODULE_big
A diferencia de DATA_built, los archivos en HEADERS_built no son eliminados
por el objetivo clean; si deseas que sean eliminados, añádelos también a EXTRA_CLEAN
o añade tus propias reglas para hacerlo.
HEADERS_$MODULEHEADERS_built_$MODULE #
Archivos a instalar (después de compilar si se especifica) bajo
, donde prefix/include/server/$MODULEDIR/$MODULE$MODULE
debe ser un nombre de módulo utilizado en MODULES o MODULE_big.
A diferencia de DATA_built, los archivos en HEADERS_built_$MODULE no son eliminados
por el objetivo clean; si deseas que sean eliminados, añádelos también a EXTRA_CLEAN
o añade tus propias reglas para hacerlo.
Es legal utilizar ambas variables para el mismo módulo, o cualquier combinación, a menos que tengas dos nombres de
módulos en la lista MODULES que difieran únicamente por la presencia del prefijo
built_, lo cual causaría ambigüedad. En ese caso (afortunadamente poco probable), debes utilizar
únicamente las variables HEADERS_built_$MODULE.
SCRIPTS #
archivos de script (no binarios) a instalar en prefix/bin
SCRIPTS_built #
archivos de script (no binarios) a instalar en , los cuales
deben ser compilados primero
prefix/bin
REGRESS #lista de casos de prueba de regresión (sin sufijo), ver más abajo
REGRESS_OPTS #opciones adicionales a pasar a pg_regress
ISOLATION #lista de casos de prueba de aislamiento, ver más abajo para obtener más detalles
ISOLATION_OPTS #opciones adicionales a pasar a pg_isolation_regress
TAP_TESTS #opción que define si las pruebas TAP necesitan ser ejecutadas, ver más abajo
NO_INSTALL #
no definir un objetivo install, útil para módulos de prueba que no necesitan que sus productos de
compilación sean instalados
NO_INSTALLCHECK #
no definir un objetivo installcheck, útil por ejemplo si las pruebas requieren una configuración
especial, o no utilizan pg_regress
EXTRA_CLEAN #
archivos adicionales a eliminar en make clean
PG_CPPFLAGS #
se antepondrá a CPPFLAGS
PG_CFLAGS #
se añadirá a CFLAGS
PG_CXXFLAGS #
se añadirá a CXXFLAGS
PG_LDFLAGS #
se antepondrá a LDFLAGS
PG_LIBS #
se añadirá a la línea de enlace de PROGRAM
SHLIB_LINK #
se añadirá a la línea de enlace de MODULE_big
PG_CONFIG #
ruta al programa pg_config para la instalación de PostgreSQL
contra la cual compilar (típicamente solo pg_config para utilizar el primero en tu
PATH)
Coloca este archivo makefile como Makefile en el directorio que contiene tu extensión. Luego puedes hacer
make para compilar, y luego make install para instalar tu módulo. Por defecto, la
extensión se compila e instala para la instalación de PostgreSQL que corresponde al primer
programa pg_config encontrado en tu PATH. Puedes utilizar una instalación diferente
configurando PG_CONFIG para que apunte a su programa pg_config, ya sea dentro del
makefile o en la línea de comandos de make.
Puedes seleccionar un prefijo de directorio independiente en el cual instalar los archivos de tu extensión, configurando
la variable de make prefix al ejecutar make install de esta manera:
make install prefix=/usr/local/postgresql
Esto instalará los archivos SQL y de control de la extensión en /usr/local/postgresql/share y los
módulos compartidos en /usr/local/postgresql/lib. Si el prefijo no incluye las cadenas
postgres o pgsql, como:
make install prefix=/usr/local/extras
entonces se añadirá postgresql a los nombres de los directorios, instalando los archivos SQL y de
control en /usr/local/extras/share/postgresql/extension y los módulos compartidos en
/usr/local/extras/lib/postgresql. En cualquier caso, necesitarás configurar
extension_control_path y dynamic_library_path para permitir que el servidor de
PostgreSQL encuentre los archivos:
extension_control_path = '/usr/local/extras/share/postgresql:$system' dynamic_library_path = '/usr/local/extras/lib/postgresql:$libdir'
También puedes ejecutar make en un directorio fuera del árbol de fuentes de tu extensión, si deseas
mantener el directorio de compilación separado. Este procedimiento también se llama compilación
VPATH. Así es cómo se hace:
mkdir build_dir cd build_dir make -f /path/to/extension/source/tree/Makefile make -f /path/to/extension/source/tree/Makefile install
Alternativamente, puedes configurar un directorio para una compilación VPATH de manera similar a cómo se hace para el
código principal. Una forma de hacerlo es utilizando el script del núcleo config/prep_buildtree.
Una vez hecho esto, puedes compilar configurando la variable de make VPATH de esta manera:
make VPATH=/path/to/extension/source/tree make VPATH=/path/to/extension/source/tree install
Este procedimiento puede funcionar con una mayor variedad de diseños de directorios.
Los scripts listados en la variable REGRESS se utilizan para las pruebas de regresión de tu módulo,
las cuales se pueden invocar mediante make installcheck después de hacer make install.
Para que esto funcione debes tener un servidor de PostgreSQL en ejecución. Los archivos de script
listados en REGRESS deben aparecer en un subdirectorio llamado sql/ en el directorio
de tu extensión. Estos archivos deben tener la extensión .sql, la cual no debe ser incluida en la lista
REGRESS en el makefile. Para cada prueba también debería haber un archivo que contenga la salida esperada
en un subdirectorio llamado expected/, con el mismo nombre base y la extensión .out.
make installcheck ejecuta cada script de prueba con psql y compara la salida
resultante con el archivo esperado coincidente. Cualquier diferencia se escribirá en el archivo
regression.diffs en formato diff -c. Ten en cuenta que intentar ejecutar una prueba
a la que le falte su archivo esperado se reportará como un “problema” (trouble), así que asegúrate de tener todos
los archivos esperados.
Los scripts listados en la variable ISOLATION se utilizan para pruebas que estresan el comportamiento de
sesiones concurrentes con tu módulo, las cuales se pueden invocar mediante make installcheck después
de hacer make install. Para que esto funcione debes tener un servidor de
PostgreSQL en ejecución. Los archivos de script listados en ISOLATION deben
aparecer en un subdirectorio llamado specs/ en el directorio de tu extensión. Estos archivos deben tener
la extensión .spec, la cual no debe ser incluida en la lista ISOLATION en el makefile.
Para cada prueba también debería haber un archivo que contenga la salida esperada en un subdirectorio llamado
expected/, con el mismo nombre base y la extensión .out.
make installcheck ejecuta cada script de prueba y compara la salida resultante con el archivo esperado
coincidente. Cualquier diferencia se escribirá en el archivo output_iso/regression.diffs en formato
diff -c. Ten en cuenta que intentar ejecutar una prueba a la que le falte su archivo esperado se
reportará como un “problema”, así que asegúrate de tener todos los archivos esperados.
TAP_TESTS habilita el uso de pruebas TAP. Los datos de cada ejecución están presentes en un subdirectorio
llamado tmp_check/. Consulta también la sección Section 31.4 para obtener más detalles.
La forma más fácil de crear los archivos esperados es crear archivos vacíos y luego realizar una ejecución de prueba
(la cual, por supuesto, reportará diferencias). Inspecciona los archivos de resultados reales encontrados en el directorio
results/ (para pruebas en REGRESS), o en el directorio
output_iso/results/ (para pruebas en ISOLATION), luego cópialos a
expected/ si coinciden con lo que esperas de la prueba.