如何在MSYS2上编译PostgreSQL
如何在MSYS2上编译PostgreSQL
Section titled “如何在MSYS2上编译PostgreSQL”虽然PostgreSQL官方确实也提供了基于EDB制作的PostgreSQL for Windows,但一方面整体比较庞大,不太适合作为软件的一部分被集成;另一方面相关特性也不能被自定义,插件的安装都是问题。因此,我们还是需要自己重新编译PostgreSQL。
二、环境准备和编译
Section titled “二、环境准备和编译”2.1 准备MSYS2环境
Section titled “2.1 准备MSYS2环境”MSYS2提供了一套基于Mingw-w64 的编译构建环境,非常好用。具体配置参考:在Windows上使用MSYS2准备构建环境
2.2 编译PostgreSQL
Section titled “2.2 编译PostgreSQL”CFLAGS="-D WINVER=0x0600 -D _WIN32_WINNT=0x0600" LIBS="-ladvapi32" ./configure --host=x86_64-w64-mingw32 --prefix=/d/PostgreSQL/ --enable-thread-safetymakemake install其中:
CFLAGS="-D WINVER=0x0600 -D _WIN32_WINNT=0x0600"是为了解决在Windows7上运行时的一个问题,具体参考:Clean build MINGW64 CreateProcessAsUserA could not be located。如果不支持Windows7,这个不加也没事。
2.3 简单验证
Section titled “2.3 简单验证”# 创建数据库目录initdb.exe -d d:\testdb
# 启动pg_ctl.exe -D d:\testdb -l logfile start
# 停止pg_ctl.exe -D d:\testdb -l logfile stop
# 创建用户createuser.exe postgres
# 登录psql -d postgres
# 修改密码ALTER USER postgres WITH PASSWORD '123456';# 创建数据库CREATE DATABASE postgres;# 授权grant all privileges on database postgres to postgres;# 授权给超级用户ALTER USER postgres WITH SUPERUSER;三、开启相关特性
Section titled “三、开启相关特性”3.1 Python3扩展
Section titled “3.1 Python3扩展”3.1.1 修改源码并编译
Section titled “3.1.1 修改源码并编译”在我的场景中,因为需要支持Windows7,Python版本中3.9版本就不支持Windows7了,但与此同时,目前最新版本的MSYS2上的Python已经更新到了3.11了,因此只能找之前的包,我找到的是:https://ftp.opencpu.org/rtools/mingw64/mingw-w64-x86_64-python-3.8.6-6-any.pkg.tar.xz。
并且因为我不想替换当前的Python 3.11,因此我干脆就把mingw-w64-x86_64-python-3.8.6-6-any.pkg.tar.xz解压后另存其他目录。
然后再上述configure的基础上,新增类似:--with-python PYTHON=<path>/mingw-w64-x86_64-python-3.8.6-6/bin/python.exe,比如:
CFLAGS="-D WINVER=0x0600 -D _WIN32_WINNT=0x0600" LIBS="-ladvapi32" ./configure --host=x86_64-w64-mingw32 --prefix=/e/PostgreSQL/ --enable-thread-safety --with-python PYTHON=/e/mingw-w64-x86_64-python-3.8.6-6/bin/python.exe但PostgreSQL的configure其实有一点bug(我认为它是BUG,没有考虑完全),其实得修改一下configure:
(1)首先在python_ldlibrary=的这样增加一个python_bindir的定义:
python_bindir=`${PYTHON} -c "import distutils.sysconfig; print(' '.join(filter(None,distutils.sysconfig.get_config_vars('BINDIR'))))"`(2)然后对这块代码做一个修改:
if test "$found_shlib" != 1 -a \( "$PORTNAME" = win32 -o "$PORTNAME" = cygwin \); then for d in "${python_libdir}" "${python_configdir}" c:/Windows/System32 /usr/bin do echo "$d/lib${ldlibrary}.dll" "$d/${ldlibrary}.dll" for f in "$d/lib${ldlibrary}.dll" "$d/${ldlibrary}.dll" ; do if test -e "$f"; then python_libdir="$d" found_shlib=1 break 2 fi done donefi修改为:
if test "$found_shlib" != 1 -a \( "$PORTNAME" = win32 -o "$PORTNAME" = cygwin \); then for d in "${python_libdir}" "${python_configdir}" c:/Windows/System32 /usr/bin ${python_bindir} do echo "$d/lib${ldlibrary}.dll" "$d/${ldlibrary}.dll" for f in "$d/lib${ldlibrary}.dll" "$d/${ldlibrary}.dll" ; do if test -e "$f"; then python_libdir="$d" found_shlib=1 break 2 fi done donefi其实就是寻找Python动态库的路径增加bin目录(因为和Linux不一样,Windows的exe文件和dll文件通常得同一个目录下),因此针对mingw-w64的Python,dll需要从bin目录寻找。
(3)然后因为我们在后续编译Python扩展时还需要链接这个DLL,因此需要将python_bindir输出,修改ac_subst_vars的定义,新增:python_bindir。
(4)修改src/Makefile.global.in,添加对python_bindir的输出:
python_bindir = @python_bindir@(5)修改src/pl/plpython/Makefile,将原始内容:
ifeq ($(PORTNAME), win32)
pytverstr=$(subst .,,${python_version})PYTHONDLL=$(subst \,/,$(WINDIR))/system32/python${pytverstr}.dllPYTHONDLL=${python_bindir}/libpython${python_version}.dll
OBJS += libpython${pytverstr}.a
libpython${pytverstr}.a: python${pytverstr}.def dlltool --dllname python${pytverstr}.dll --def python${pytverstr}.def --output-lib libpython${pytverstr}.a
python${pytverstr}.def: pexports $(PYTHONDLL) > $@
endif # win32修改为:
ifeq ($(PORTNAME), win32)OBJS += ${python_bindir}/libpython${python_version}.dllendif # win32上面添加的python_bindir也就是在这里会用上。
src/pl/plpython/Makefile中的clean和distclean任务也得修改一下,不然把${python_bindir}/libpython${python_version}.dll会被误删:
CLEAN_OBJS := $(filter-out ${python_bindir}/libpython${python_version}.dll, $(OBJS))clean distclean: clean-lib rm -f $(CLEAN_OBJS) rm -rf $(pg_regress_clean_files)另外,还有一点,在启动需要指定刚才的Python路径,类似:
PYTHONHOME=/e/mingw-w64-x86_64-python-3.8.6-6 PATH=/e/mingw-w64-x86_64-python-3.8.6-6/bin/:$PATH ./bin/pg_ctl.exe -D /e/testdb/ -l logfile start3.1.2 验证
Section titled “3.1.2 验证”创建 PL/Python3u 扩展:
CREATE EXTENSION plpython3u;验证扩展安装是否成功:
SELECT lanname FROM pg_language;一个简单验证的SQL:
CREATE OR REPLACE FUNCTION upper_case(text) RETURNS text AS $$return args[0].upper()$$ LANGUAGE plpython3u;
SELECT upper_case('hello, world!');