36.18. 扩展构建基础设施 #
如果你打算分发自己的 PostgreSQL 扩展模块,那么为它们搭建一个可移植的构建系统可能相当困难。因此,PostgreSQL 安装提供了一套称为 PGXS 的扩展构建基础设施,使简单的扩展模块可以针对已安装好的服务器直接构建。PGXS 主要面向包含 C 代码的扩展,不过它也能用于纯 SQL 扩展。注意,PGXS 并不打算成为一个可以用来构建任意与 PostgreSQL 交互软件的通用构建系统框架;它只是把简单服务器扩展模块的常见构建规则自动化。对于更复杂的软件包,你可能还是需要自己编写构建系统。
要为你的扩展使用 PGXS 基础设施,你必须写一个简单的 makefile。在这个 makefile 中,需要设置一些变量并包含全局
PGXS makefile。下面是一个示例,它构建一个名为
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 规则。
设定下列三个变量中的一个,以指定要构建的内容:
还可以设置以下变量:
EXTENSION#扩展名称;对于每个名称,你都必须提供一个
文件,它将安装到extension.controlprefix/share/extensionMODULEDIR#下的子目录,用于安装 DATA 和 DOCS 文件(若未设置,则在设置了prefix/shareEXTENSION时默认为extension,否则默认为contrib)DATA#要安装到
的任意文件prefix/share/$MODULEDIRDATA_built#要安装到
的任意文件,但它们需要先被构建prefix/share/$MODULEDIRDATA_TSEARCH#要安装到
下的任意文件prefix/share/tsearch_dataDOCS#要安装到
下的任意文件prefix/doc/$MODULEDIRHEADERSHEADERS_built#要(可选地先构建并)安装到
下的文件。prefix/include/server/$MODULEDIR/$MODULE_big与
DATA_built不同,HEADERS_built中的文件不会被clean目标删除;如果你希望删除它们,也应把它们加入EXTRA_CLEAN,或者自行添加规则来完成删除。HEADERS_$MODULEHEADERS_built_$MODULE#要安装的文件(如果指定了则先构建),安装位置为
,其中prefix/include/server/$MODULEDIR/$MODULE$MODULE必须是MODULES或MODULE_big中使用的某个模块名。与
DATA_built不同,HEADERS_built_$MODULE中的文件不会被clean目标删除;如果你希望删除它们,也应把它们加入EXTRA_CLEAN,或者自行添加规则来完成删除。对同一个模块同时使用这两个变量,或以任意方式组合使用,都是合法的;但如果你在
MODULES列表中有两个模块名只相差一个前缀built_,就会产生歧义。在这种情况(希望不太可能发生)下,你应只使用HEADERS_built_$MODULE变量。SCRIPTS#要安装到
的脚本文件(不是二进制文件)prefix/binSCRIPTS_built#要安装到
的脚本文件(不是二进制文件),但它们需要先被构建prefix/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#要针对其进行构建的 PostgreSQL 安装所对应的 pg_config 程序路径(通常只写
pg_config,表示使用你PATH中找到的第一个)
把这个 makefile 命名为 Makefile,并放在保存扩展的目录中。然后你就可以执行 make 进行编译,再执行
make install 安装你的模块。默认情况下,该扩展会针对你 PATH 中找到的第一个
pg_config 所对应的
PostgreSQL 安装进行编译和安装。你也可以使用不同的安装,只需让 PG_CONFIG 指向它的
pg_config 程序,无论是在 makefile 中设置,还是在
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。准备好之后,就可以像下面这样通过设置 make 变量
VPATH 来构建:
make VPATH=/path/to/extension/source/tree make VPATH=/path/to/extension/source/tree install
这种方式适用于更多种目录布局。
在 REGRESS 变量中列出的脚本用于对模块做回归测试,可在执行完 make install 之后,通过
make installcheck 来运行。要让它工作,你必须有一个正在运行的 PostgreSQL 服务器。列在
REGRESS 中的脚本文件必须位于扩展目录下名为
sql/ 的子目录中。这些文件必须具有
.sql 扩展名,而该扩展名不能出现在 makefile 的
REGRESS 列表中。对于每个测试,还应在名为
expected/ 的子目录中有一个包含期望输出的文件,其主干名相同,扩展名为 .out。make installcheck 会用 psql
执行每个测试脚本,并把得到的输出与对应的期望文件比较。任何差异都会以
diff -c 格式写入
regression.diffs 文件。注意,如果尝试运行一个缺少期望文件的测试,将被报告为“trouble”,所以请确保所有期望文件都已准备好。
在 ISOLATION 变量中列出的脚本用于测试你的模块在并发会话下的行为,也可以在执行完 make install 之后,通过 make installcheck 来运行。要让它工作,你同样必须有一个正在运行的 PostgreSQL 服务器。列在 ISOLATION 中的脚本文件必须位于扩展目录下名为
specs/ 的子目录中。这些文件必须具有
.spec 扩展名,而该扩展名不能出现在 makefile 的
ISOLATION 列表中。对于每个测试,还应在名为
expected/ 的子目录中有一个包含期望输出的文件,其主干名相同,扩展名为 .out。make installcheck 会执行每个测试脚本,并把结果输出与对应的期望文件比较。任何差异都会以 diff -c 格式写入 output_iso/regression.diffs 文件。注意,如果尝试运行一个缺少期望文件的测试,将被报告为“trouble”,所以请确保所有期望文件都已准备好。
TAP_TESTS 可启用 TAP 测试。每次运行的数据都会放在名为 tmp_check/ 的子目录中。更多细节参见第 31.4 节。
提示
创建期望文件最简单的方法是先建立空文件,然后运行一次测试(当然这会报告差异)。检查 results/ 目录中的实际结果文件(对应
REGRESS 测试),或者
output_iso/results/ 目录中的实际结果文件(对应
ISOLATION 测试);如果它们与你对测试的预期一致,就把它们复制到 expected/ 中。
报告文档问题
阅读 上游文档. 通过 PostgreSQL 文档反馈表单.