40.18. Инфраструктура сборки расширений #
Если вы задумываетесь о распространении ваших модулей расширения Postgres Pro, знайте, что организовать для них портируемую систему сборки может быть довольно сложно. Поэтому инсталляция Postgres Pro включает инфраструктуру сборки расширений, названную PGXS, так что несложные модули расширений можно собрать просто в среде установленного сервера. PGXS предназначена в первую очередь для расширений, написанных на C, хотя её можно применять и для расширения на чистом SQL. Заметьте, что PGXS не претендует на роль универсальной инфраструктуры сборки, способной собрать любой программный объект, взаимодействующий с Postgres Pro; она просто автоматизирует общие правила для сборки простых модулей расширения сервера. Для более сложных пакетов вам придётся разработать собственную систему сборки.
Чтобы использовать инфраструктуру PGXS для вашего расширения, вы должны написать простой сборочный файл. В нём вы должны установить нужные переменные и подключить глобальный сборочный файл PGXS. Следующий пример собирает модуль расширения с именем isbn_issn
, который включает разделяемую библиотеку, написанную на C, управляющий файл расширения, SQL-скрипт, текстовый файл документации и заголовочный файл (он нужен, только если другие модули будут вызывать функции данного расширения напрямую, без использования SQL):
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)
Последние три строки всегда должны быть такими. Выше в файле вы определяете переменные или добавляете собственные правила для make.
Установите одну из этих трёх переменных, чтобы указать, что будет собрано:
MODULES
#список объектов разделяемых библиотек, которые должны быть собраны из исходных файлов с одной основой (суффиксы библиотек в этом списке не указываются)
MODULE_big
#разделяемая библиотека, которая должна быть собрана из нескольких исходных файлов (объектные файлы перечисляются в
OBJS
)PROGRAM
#исполняемая программа, которая должна быть собрана (объектные файлы перечисляются в
OBJS
)
Также можно установить следующие переменные:
EXTENSION
#имена расширений(я); для каждого имени вы должны предоставить файл
, который будет установлен врасширение
.controlпрефикс
/share/extensionMODULEDIR
#подкаталог в каталоге
, в который должны устанавливаться файлы DATA и DOCS (если не задан, подразумеваетсяпрефикс
/shareextension
, если установлена переменнаяEXTENSION
, илиcontrib
в противном случае)DATA
#произвольные файлы, которые должны быть установлены в
префикс
/share/$MODULEDIRDATA_built
#произвольные файлы, которые должны быть сначала собраны, а затем установлены в
префикс
/share/$MODULEDIRDATA_TSEARCH
#произвольные файлы, которые должны быть установлены в
префикс
/share/tsearch_dataDOCS
#произвольные файлы, которые должны быть установлены в
префикс
/doc/$MODULEDIRHEADERS
HEADERS_built
#Файлы, которые будут устанавливаться (и, возможно, собираться) в
.префикс
/include/server/$MODULEDIR/$MODULE_bigВ отличие от файлов
DATA_built
, файлы вHEADERS_built
не удаляются при выполнении целиclean
; если вы хотите удалять их, добавьте их вEXTRA_CLEAN
или напишите собственные правила для этого.HEADERS_$MODULE
HEADERS_built_$MODULE
#Файлы, которые будут устанавливаться (если требуется, после сборки) в
, где в качествепрефикс
/include/server/$MODULEDIR/$MODULE$MODULE
должно задаваться имя модуля, фигурирующее вMODULES
илиMODULE_big
.В отличие от файлов
DATA_built
, файлы вHEADERS_built_$MODULE
не удаляются при выполнении целиclean
; если вы хотите удалять их, добавьте их вEXTRA_CLEAN
или напишите собственные правила для этого.Для одного модуля вполне можно использовать обе переменные в любом сочетании, если только в вашем списке
MODULES
не присутствуют два имени, отличающиеся только префиксомbuilt_
, что приводит к неоднозначности. В этом (очень маловероятном) случае следует использовать только переменныеHEADERS_built_$MODULE
.SCRIPTS
#скрипты (не двоичные файлы), которые должны быть установлены в
префикс
/binSCRIPTS_built
#скрипты (не двоичные файлы), которые должны быть сначала собраны, а затем установлены в
префикс
/binREGRESS
#список тестов регрессий (без суффикса), см. ниже
REGRESS_OPTS
#дополнительные параметры, передаваемые pg_regress
ISOLATION
#список изоляционных тестов, см. ниже
ISOLATION_OPTS
#дополнительные параметры, передаваемые pg_isolation_regress
TAP_TESTS
#переключатель, определяющий, нужно ли запускать TAP-тесты; см. ниже
NO_INSTALL
#не определять цель
install
; это полезно для модулей тестирования, результаты сборки которых не нужно устанавливатьNO_INSTALLCHECK
#не определять цель
installcheck
; это полезно, если тестам требуется особая конфигурация или pg_regress не используетсяEXTRA_CLEAN
#дополнительные файлы, которые должны быть удалены при
make clean
PG_CPPFLAGS
#флаги, добавляемые перед другими в
CPPFLAGS
PG_CFLAGS
#флаги, добавляемые в
CFLAGS
PG_CXXFLAGS
#флаги, добавляемые в
CXXFLAGS
PG_LDFLAGS
#флаги, добавляемые перед другими в
LDFLAGS
PG_LIBS
#будет добавлено в строку компоновки
PROGRAM
SHLIB_LINK
#будет добавлено в строку компоновки
MODULE_big
PG_CONFIG
#путь к программе pg_config в инсталляции Postgres Pro, с которой будет выполняться сборка (обычно указывается просто
pg_config
, и используется первый экземпляр, найденный по пути вPATH
)
Поместите этот сборочный файл под именем Makefile
в каталог, где находится ваше расширение. После этого выполните make
, чтобы скомпилировать, а затем make install
, чтобы установить ваш модуль. По умолчанию расширение компилируется и устанавливается для той инсталляции Postgres Pro, которая соответствует экземпляру pg_config
, найденному первым при поиске по пути в PATH
. Чтобы использовать другую инсталляцию, вы можете задать в PG_CONFIG
путь к её экземпляру pg_config
либо внутри сборочного файла, либо в командном файле make
.
Вы также можете запустить make
в каталоге вне каталога исходного дерева вашего расширения, если хотите отделить каталог сборки. Эта процедура называется сборкой с VPATH и выполняется так:
mkdir build_dir cd build_dir make -f /path/to/extension/source/tree/Makefile make -f /path/to/extension/source/tree/Makefile install
Также вы можете подготовить каталог для сборки с VPATH таким же образом, как это делается в коде ядра сервера. Как один из вариантов, для этого можно воспользоваться скриптом ядра config/prep_buildtree
. Затем вы сможете выполнить сборку, установив переменную VPATH
для make
таким образом:
make VPATH=/path/to/extension/source/tree make VPATH=/path/to/extension/source/tree install
Эта процедура поддерживает самые разные расположения каталогов.
Скрипты, перечисленные в переменной REGRESS
, используются для регрессионного тестирования модуля, и вызвать их можно командой make installcheck
после make install
. Для проведения тестирования необходим работающий сервер Postgres Pro. Файлы скриптов, перечисленные в REGRESS
, должны размещаться в подкаталоге sql/
каталога расширения. Эти файлы должны иметь расширение .sql
, но указывать его в списке REGRESS
в сборочном файле не нужно. Для каждого теста также должен создаваться файл с ожидаемым выводом в подкаталоге expected/
, с тем же базовым именем и расширением .out
. Команда make installcheck
выполнит каждый тест в psql и сравнит полученный вывод с ожидаемым. Все выявленные различия будут записаны в файл regression.diffs
в формате команды diff -c
. Заметьте, что при попытке запустить тест без файла ожидаемого вывода этот тест будет отмечен как «проблемный», поэтому убедитесь, что все такие файлы присутствуют.
Скрипты, перечисленные в переменной ISOLATION
, используются для тестирования работы модуля при параллельной нагрузке, и вызвать их можно командой make installcheck
после make install
. Для проведения тестирования необходим работающий сервер Postgres Pro. Файлы скриптов, перечисленные в ISOLATION
, должны размещаться в подкаталоге specs/
каталога вашего расширения. Эти файлы должны иметь расширение .spec
, которое не должно включаться в список ISOLATION
в Makefile. Для каждого теста также должен создаваться файл с ожидаемым выводом в подкаталоге expected/
, с тем же базовым именем и расширением .out
. Команда make installcheck
выполнит каждый тест и сравнит полученный вывод с ожидаемым. Все выявленные различия будут записаны в файл output_iso/regression.diffs
в формате команды diff -c
. Заметьте, что при попытке запустить тест без файла ожидаемого вывода этот тест будет отмечен как «проблемный», поэтому убедитесь, что все такие файлы присутствуют.
Переменная TAP_TESTS
включает использование TAP-тестов. Данные, получаемые на каждом прогоне теста, помещаются в подкаталог tmp_check/
.
Подсказка
Проще всего для этого создать пустые файлы ожидаемого вывода, а затем выполнить тест (при этом, конечно, будут выявлены несоответствия). Изучите полученные файлы результатов, сохранённые в каталоге results/
(для тестов REGRESS
) или каталоге output_iso/results/
(для тестов в ISOLATION
), и, если они соответствуют вашим ожиданиям от теста, скопируйте их в expected/
.