2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1

36.18. 扩展构建基础设施 #

如果您正在考虑分发您的 PostgreSQL 扩展模块,为它们设置一个可移植的构建系统可能会相当困难。因此,PostgreSQL 安装提供了一个用于扩展的构建基础设施,称为PGXS,这样简单的扩展模块就可以针对已安装的服务器进行简单构建。PGXS主要用于包含 C 代码的扩展,尽管它也可以用于纯 SQL 扩展。请注意,PGXS并非旨在成为一个通用的构建系统框架,可用于构建任何与 PostgreSQL 接口的软件;它只是自动化了简单的服务器扩展模块的常见构建规则。对于更复杂的包,您可能需要编写自己的构建系统。

要使用PGXS基础设施来构建您的扩展,您必须编写一个简单的 Makefile。在 Makefile 中,您需要设置一些变量并包含全局PGXSMakefile。下面是一个例子,它构建了一个名为 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 #

将 DATA 和 DOCS 文件安装到 prefix/share 的子目录中(如果未设置,则默认为 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 #

pg_config 程序的路径,用于构建 PostgreSQL 安装(通常只需 pg_config,以便使用 PATH 中的第一个)。

将此 Makefile 放在扩展所在的目录中,文件名为 Makefile。然后,您可以运行 make 进行编译,然后运行 make install 来安装您的模块。默认情况下,扩展会为 PATH 中找到的第一个 pg_config 程序对应的 PostgreSQL 安装进行编译和安装。您可以通过在 Makefile 中或在 make 命令行的 PG_CONFIG 中设置 PG_CONFIG 来指向其 pg_config 程序,从而使用不同的安装。

您可以通过在执行 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/ 子目录中,具有相同的基名和 .out 扩展名。make installcheck 使用 psql 执行每个测试脚本,并将结果输出与匹配的预期文件进行比较。任何差异都将写入 regression.diffs 文件,格式为 diff -c。请注意,尝试运行缺少预期文件的测试将被报告为“trouble”(麻烦),因此请确保您拥有所有预期文件。

ISOLATION 变量中列出的脚本用于测试与您的模块并发会话的行为,可以在执行 make install 后通过 make installcheck 调用。要使其工作,您必须有一个正在运行的 PostgreSQL 服务器。在 ISOLATION 中列出的脚本文件必须出现在扩展目录下的 specs/ 子目录中。这些文件必须具有 .spec 扩展名,该扩展名不得包含在 Makefile 的 ISOLATION 列表中。对于每个测试,还应该有一个包含预期输出的文件,位于 expected/ 子目录中,具有相同的基名和 .out 扩展名。make installcheck 执行每个测试脚本,并将结果输出与匹配的预期文件进行比较。任何差异都将写入 output_iso/regression.diffs 文件,格式为 diff -c。请注意,尝试运行缺少预期文件的测试将被报告为“trouble”(麻烦),因此请确保您拥有所有预期文件。

TAP_TESTS 启用了 TAP 测试的使用。每次运行的数据将包含在名为 tmp_check/ 的子目录中。有关更多详细信息,请参阅 31.4 节

提示

创建预期文件的最简单方法是创建空文件,然后运行测试(这当然会报告差异)。检查在 results/ 目录(用于 REGRESS 中的测试)或 output_iso/results/ 目录(用于 ISOLATION 中的测试)中找到的实际结果文件,然后如果它们与您对测试的预期相符,则将它们复制到 expected/

提交更正

如果您在文档中看到任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。