受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

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 规则。

设定下列三个变量中的一个,以指定要构建的内容:

MODULES #

要从同名源文件构建的共享库对象列表(列表中不要包含库后缀)

MODULE_big #

要从多个源文件构建的共享库(在 OBJS 中列出对象 文件)

PROGRAM #

要构建的可执行程序(在 OBJS 中列出对象文件)

还可以设置以下变量:

EXTENSION #

扩展名称;对于每个名称,你都必须提供一个 extension.control 文 件,它将安装到 prefix/share/extension

MODULEDIR #

prefix/share 下的子目录, 用于安装 DATA 和 DOCS 文件(若未设置,则在设置了 EXTENSION 时默认为 extension,否则默认为 contrib

DATA #

要安装到 prefix/share/$MODULEDIR 的任意文件

DATA_built #

要安装到 prefix/share/$MODULEDIR 的任意文件,但它们需要先被构建

DATA_TSEARCH #

要安装到 prefix/share/tsearch_data 下的任意文件

DOCS #

要安装到 prefix/doc/$MODULEDIR 下的任意文件

HEADERS
HEADERS_built #

要(可选地先构建并)安装到 prefix/include/server/$MODULEDIR/$MODULE_big 下的文件。

DATA_built 不同, HEADERS_built 中的文件不会被 clean 目标删除;如果你希望删除它们,也应把它们 加入 EXTRA_CLEAN,或者自行添加规则来完成删除。

HEADERS_$MODULE
HEADERS_built_$MODULE #

要安装的文件(如果指定了则先构建),安装位置为 prefix/include/server/$MODULEDIR/$MODULE, 其中 $MODULE 必须是 MODULESMODULE_big 中使 用的某个模块名。

DATA_built 不同, HEADERS_built_$MODULE 中的文件不会被 clean 目标删除;如果你希望删除它们,也应把它们 加入 EXTRA_CLEAN,或者自行添加规则来完成删除。

对同一个模块同时使用这两个变量,或以任意方式组合使用,都是合法的; 但如果你在 MODULES 列表中有两个模块名只相差一 个前缀 built_,就会产生歧义。在这种情况(希望不 太可能发生)下,你应只使用 HEADERS_built_$MODULE 变量。

SCRIPTS #

要安装到 prefix/bin 的脚本文件(不是二进制文件)

SCRIPTS_built #

要安装到 prefix/bin 的脚本文件(不是二进制文件),但它们需要先被构建

REGRESS #

回归测试用例列表(不带后缀),详见下文

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 的链接命令行

将被加入 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 install 时,通过设置 make 变量 prefix 来选择一个独立 的目录前缀,以安装扩展文件,例如:

make install prefix=/usr/local/postgresql

这样会把扩展控制文件和 SQL 文件安装到 /usr/local/postgresql/share,把共享模块安装到 /usr/local/postgresql/lib。如果该前缀不包含 postgrespgsql 字符串,例如:

make install prefix=/usr/local/extras

那么 postgresql 会被附加到目录名中,从而把控制文件 和 SQL 文件安装到 /usr/local/extras/share/postgresql/extension, 把共享模块安装到 /usr/local/extras/lib/postgresql。无论哪种情况, 你都需要设置 extension_control_pathdynamic_library_path,以便 PostgreSQL 服务器能找到这些文件:

extension_control_path = '/usr/local/extras/share/postgresql:$system'
dynamic_library_path = '/usr/local/extras/lib/postgresql:$libdir'

如果你想保持构建目录与源代码目录分离,也可以在扩展源代码树之外的目录 中运行 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/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .outmake installcheck 会用 psql 执行每个测试脚本,并把得到的输出与对应的期望文件比较。任何差异都会以 diff -c 格式写入 regression.diffs 文件。注意,如果尝试运行一个缺少 期望文件的测试,将被报告为 trouble,所以请确保所有期望 文件都已准备好。

ISOLATION 变量中列出的脚本用于测试你的模块在并 发会话下的行为,也可以在执行完 make install 之后, 通过 make installcheck 来运行。要让它工作,你同样 必须有一个正在运行的 PostgreSQL 服务器。列 在 ISOLATION 中的脚本文件必须位于扩展目录下名为 specs/ 的子目录中。这些文件必须具有 .spec 扩展名,而该扩展名不应出现在 makefile 的 ISOLATION 列表中。对于每个测试,还应在名为 expected/ 的子目录中有一个包含期望输出的文件,其主 干名相同,扩展名为 .outmake installcheck 会执行每个测试脚本,并把结果输出 与对应的期望文件比较。任何差异都会以 diff -c 格式 写入 output_iso/regression.diffs 文件。注意,如果 尝试运行一个缺少期望文件的测试,将被报告为 trouble,所 以请确保所有期望文件都已准备好。

TAP_TESTS 可启用 TAP 测试。每次运行的数据都会放在 名为 tmp_check/ 的子目录中。更多细节参见 Section 31.4

Tip

创建期望文件最简单的方法是先建立空文件,然后运行一次测试(当然这会报 告差异)。检查 results/ 目录中的实际结果文件(对应 REGRESS 测试),或者 output_iso/results/ 目录中的实际结果文件(对应 ISOLATION 测试);如果它们与你对测试的预期一致,就 把它们复制到 expected/ 中。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。