Build PostgresML

There are some extra settings to build PostgresML on EL8 and EL9.

It’s quite tricky to build PostgresML on EL8 and EL9, here is the tutorial.

First of all, configure the RPM build environment, install rust and pgrx according to the instructions.


Python3

Install Python and setup alternatives:

sudo yum install python3.11 python3.11-devel python3-virtualenv openssl openssl-devel cmake pkg-config libomp libomp-devel openblas* llvm llvm-devel lld openblas*
sudo alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1
sudo alternatives --set python3 /usr/bin/python3.11
sudo alternatives --set python /usr/bin/python3.11

Clone Repo

Clone pgml with git then checkout to the latest release:

cd ~; git clone --recursive git@github.com:postgresml/postgresml.git; 
cd ~/postgresml && git checkout v2.9.3
cd ~/postgresml/pgml-extension

EL8 Ad hoc

This part is only for EL8, EL9 is not affected.

sudo dnf install gcc-toolset-13
source /opt/rh/gcc-toolset-13/enable
source /opt/rh/gcc-toolset-13/enable
export CC=/opt/rh/gcc-toolset-13/root/usr/bin/gcc
export CXX=/opt/rh/gcc-toolset-13/root/usr/bin/g++
export LD_LIBRARY_PATH=/opt/rh/gcc-toolset-13/root/usr/lib64:$LD_LIBRARY_PATH

You have to change build.rs, add stdc++fs and gcc-toolset-13:

println!("cargo:rustc-link-lib=static=stdc++fs");
println!("cargo:rustc-link-search=native=/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13");

The whole file should be like this:

fn main() {
    #[cfg(target_os = "macos")]
    {
        println!("cargo:rustc-link-search=/opt/homebrew/opt/openblas/lib");
        println!("cargo:rustc-link-search=/opt/homebrew/opt/libomp/lib");
    }

    // PostgreSQL is using dlopen(RTLD_GLOBAL). this will parse some
    // of symbols into the previous opened .so file, but the others will use a
    // relative offset in pgml.so, and will cause a null-pointer crash.
    //
    // hide all symbol to avoid symbol conflicts.
    //
    // append mode (link-args) only works with clang ld (lld)
    println!(
        "cargo:link-args=-Wl,--version-script={}/ld.map",
        std::env::current_dir().unwrap().to_string_lossy(),
    );

    println!("cargo:rustc-link-lib=static=stdc++fs");
    println!("cargo:rustc-link-search=native=/opt/rh/gcc-toolset-13/root/usr/lib/gcc/x86_64-redhat-linux/13");

    vergen::EmitBuilder::builder().all_git().emit().unwrap();
}

Then change the Cargo.toml

Add cc = "1.0" to the [build-dependencies] section:

[build-dependencies]
+++ cc = "1.0"

Building

To build PostgresML against PostgreSQL 16, 15, 14:

cd ~/postgresml/pgml-extension; pg16 build; pg15 build; pg14 build;

The rpm package will be placed in ~/rpmbuild/RPMS/x86_64/ directory.

rm -rf ~/rpmbuild/SOURCES/pgml_16; cp -r ~/postgresml/pgml-extension/target/release/pgml-pg16 ~/rpmbuild/SOURCES/pgml_16;
rm -rf ~/rpmbuild/SOURCES/pgml_15; cp -r ~/postgresml/pgml-extension/target/release/pgml-pg15 ~/rpmbuild/SOURCES/pgml_15;
rm -rf ~/rpmbuild/SOURCES/pgml_14; cp -r ~/postgresml/pgml-extension/target/release/pgml-pg14 ~/rpmbuild/SOURCES/pgml_14;
cd ~/rpmbuild/SPECS && make pgml

# 或手工进行构建:
rm -rf ~/rpmbuild/RPMS/x86_64/pgml*.rpm;
rpmbuild --without debuginfo --define "pgmajorversion 16" -ba ~/rpmbuild/SPECS/pgml.spec
rpmbuild --without debuginfo --define "pgmajorversion 15" -ba ~/rpmbuild/SPECS/pgml.spec
rpmbuild --without debuginfo --define "pgmajorversion 14" -ba ~/rpmbuild/SPECS/pgml.spec