Thread: Not able to compile PG16 with custom flags in freebsd 14.1 - Please Help

Not able to compile PG16 with custom flags in freebsd 14.1 - Please Help

From
Moksh Chadha
Date:
Hi I am trying to install Postgresql 16 on my freebsd 14.1 by compiling it hosted in an ec2 machine on AWS.

I am using GCC13 to compile the binaries and I keep on running into

gcc13: fatal error: cannot read spec file './specs': Is a directory 
Please Help

here is the code of my bash script I have also uploaded the same code in github gist :-


Code in the above mentioned gist 

 #!/bin/sh

# Configuration variables
POSTGRES_VERSION="16.3"
POSTGRES_PREFIX="/usr/local/pgsql"
DATA_DIR="$POSTGRES_PREFIX/data"
LOGFILE="$POSTGRES_PREFIX/logfile"
BUILD_DIR="/tmp/postgresql-build"
PYTHON3_PATH=$(which python3)

# Helper functions
error_exit() {    echo "Error: $1" >&2    cleanup    exit 1
}

warning_message() {    echo "Warning: $1" >&2
}

cleanup() {    echo "Cleaning up..."    [ -d "$BUILD_DIR" ] && rm -rf "$BUILD_DIR" || warning_message "Failed to remove build directory."
}

check_prerequisites() {    # Check for GCC 13    if ! command -v gcc13 >/dev/null 2>&1; then        echo "GCC 13 is not installed. Installing GCC 13..."        pkg install -y gcc13 || error_exit "Failed to install GCC 13. Please install it manually using 'pkg install gcc13'."    else        echo "GCC 13 is installed. Checking version and configuration..."        gcc13 --version        gcc13 -v 2>&1 | grep "Configured with"                # Check for specs file issue        GCC_LIBDIR="/usr/local/lib/gcc13"        SPECS_FILE="$GCC_LIBDIR/specs"                if [ ! -f "$SPECS_FILE" ]; then            echo "specs file not found. Attempting to create..."            if ! gcc13 -dumpspecs > "$SPECS_FILE" 2>/dev/null; then                error_exit "Failed to create specs file. Please check GCC 13 installation."            fi        fi                # Verify GCC functionality        if ! gcc13 -v >/dev/null 2>&1; then            error_exit "GCC 13 is not functioning correctly. Please check your GCC installation."        fi    fi
    # Check for GNU Make    if ! command -v gmake >/dev/null 2>&1; then        echo "GNU Make is not installed. Installing GNU Make..."        pkg install -y gmake || error_exit "Failed to install GNU Make. Please install it manually using 'pkg install gmake'."    fi        command -v fetch >/dev/null 2>&1 || error_exit "fetch is required but not installed. Please install it using 'pkg install fetch'."    command -v python3 >/dev/null 2>&1 || error_exit "Python3 is required but not installed. Please install it using 'pkg install python3'."    command -v openssl >/dev/null 2>&1 || error_exit "OpenSSL is required but not installed. Please install it using 'pkg install openssl'."        # Check for pkg-config    if ! command -v pkg-config >/dev/null 2>&1; then        echo "pkg-config is not installed. Installing pkg-config..."        pkg install -y pkgconf || error_exit "Failed to install pkg-config. Please install it manually using 'pkg install pkgconf'."    fi        # Check for LZ4    if ! pkg info -e liblz4 >/dev/null 2>&1; then        echo "LZ4 is not installed. Installing LZ4..."        pkg install -y liblz4 || error_exit "Failed to install LZ4. Please install it manually using 'pkg install liblz4'."    fi        # Verify LZ4 installation    if ! pkg-config --exists liblz4; then        error_exit "LZ4 library not found by pkg-config. Please check your LZ4 installation."    fi        # Check for ICU    if ! pkg info -e icu >/dev/null 2>&1; then        echo "ICU is not installed. Installing ICU..."        pkg install -y icu || error_exit "Failed to install ICU. Please install it manually using 'pkg install icu'."    fi        # Verify ICU installation    if [ -f /usr/local/lib/libicuuc.so ]; then        echo "ICU library found at /usr/local/lib/libicuuc.so"    else        error_exit "ICU library not found at expected location. Please check your ICU installation."    fi        # Print ICU version    echo "ICU version:"    pkg info icu | grep Version        # Print LZ4 version    echo "LZ4 version:"    pkg info liblz4 | grep Version
}

ensure_install_directory() {    if [ ! -d "$POSTGRES_PREFIX" ]; then        mkdir -p "$POSTGRES_PREFIX" || error_exit "Failed to create installation directory."    elif [ ! -w "$POSTGRES_PREFIX" ]; then        chmod u+w "$POSTGRES_PREFIX" || error_exit "Failed to set permissions on installation directory."    fi
}

create_postgres_user() {    if ! pw groupshow postgres >/dev/null 2>&1; then        echo "Creating 'postgres' group..."        pw groupadd postgres || error_exit "Failed to create 'postgres' group."    fi
    if ! pw usershow postgres >/dev/null 2>&1; then        echo "Creating 'postgres' user..."        pw useradd postgres -g postgres -m -s /usr/local/bin/bash || error_exit "Failed to create 'postgres' user."    else        echo "'postgres' user already exists."    fi
}

download_postgresql() {    echo "Downloading PostgreSQL $POSTGRES_VERSION..."    mkdir -p "$BUILD_DIR" || error_exit "Failed to create build directory."    cd "$BUILD_DIR" || error_exit "Failed to enter build directory."
    if [ ! -f "postgresql-$POSTGRES_VERSION.tar.bz2" ]; then        fetch "https://ftp.postgresql.org/pub/source/v$POSTGRES_VERSION/postgresql-$POSTGRES_VERSION.tar.bz2" || error_exit "Failed to download PostgreSQL source."    else        echo "Source tarball already exists, skipping download."    fi
    if [ ! -d "postgresql-$POSTGRES_VERSION" ]; then        tar -xvf "postgresql-$POSTGRES_VERSION.tar.bz2" || error_exit "Failed to extract PostgreSQL source."    else        echo "Source directory already exists, skipping extraction."    fi
    cd "postgresql-$POSTGRES_VERSION" || error_exit "Failed to enter PostgreSQL source directory."
}

configure_postgresql() {    echo "Configuring PostgreSQL with custom options..."    PYTHON_INCLUDE_DIR=$($PYTHON3_PATH -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())")    PYTHON_LIB_DIR=$($PYTHON3_PATH -c "from distutils.sysconfig import get_config_var; print(get_config_var('LIBDIR'))")
    # Add ICU library and include paths    ICU_LIBS="-L/usr/local/lib -licui18n -licuuc -licudata"    ICU_CFLAGS="-I/usr/local/include"
    # Add LZ4 library and include paths    LZ4_LIBS=$(pkg-config --libs liblz4)    LZ4_CFLAGS=$(pkg-config --cflags liblz4)
    export CC=gcc13    export LDFLAGS="-L/usr/local/lib -L$PYTHON_LIB_DIR $ICU_LIBS $LZ4_LIBS"    export CPPFLAGS="-I/usr/local/include -I$PYTHON_INCLUDE_DIR $ICU_CFLAGS $LZ4_CFLAGS"    export ICU_LIBS    export ICU_CFLAGS    export LZ4_LIBS    export LZ4_CFLAGS    export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"    export LIBRARY_PATH="/usr/local/lib:$LIBRARY_PATH"    export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH"
    config_command="./configure \        CC=gcc13 \        --prefix=\"$POSTGRES_PREFIX\" \        --with-blocksize=32 \        --with-segsize=8 \        --with-openssl \        --with-ssl=openssl \        --with-lz4 \        --with-python \        --with-icu \        --with-includes=\"/usr/local/include $PYTHON_INCLUDE_DIR\" \        --with-libraries=\"/usr/local/lib $PYTHON_LIB_DIR\""    echo "Configuration command: $config_command"    echo "LDFLAGS: $LDFLAGS"    echo "CPPFLAGS: $CPPFLAGS"    echo "ICU_LIBS: $ICU_LIBS"    echo "ICU_CFLAGS: $ICU_CFLAGS"    echo "LZ4_LIBS: $LZ4_LIBS"    echo "LZ4_CFLAGS: $LZ4_CFLAGS"    echo "LD_LIBRARY_PATH: $LD_LIBRARY_PATH"    echo "LIBRARY_PATH: $LIBRARY_PATH"    echo "PKG_CONFIG_PATH: $PKG_CONFIG_PATH"        # Run configure and capture output    if ! eval $config_command > configure_output.log 2>&1; then        echo "Configuration failed. Last 50 lines of output:"        tail -n 50 configure_output.log        error_exit "Configuration failed. See configure_output.log for details."    fi
}

verify_compilation_options() {    echo "Verifying compilation options..."    grep -E "BLCKSZ|RELSEG_SIZE" src/include/pg_config.h
}

compile_postgresql() {    echo "Compiling PostgreSQL..."    gmake || error_exit "Compilation failed."        echo "Compiling contrib modules (including pg_trgm)..."    cd contrib || error_exit "Failed to enter contrib directory."    gmake || error_exit "Compilation of contrib modules failed."        cd .. || error_exit "Failed to return to main PostgreSQL directory."    verify_compilation_options
}

install_postgresql() {    echo "Installing PostgreSQL..."    gmake install || error_exit "Installation failed."        echo "Installing contrib modules (including pg_trgm)..."    cd contrib || error_exit "Failed to enter contrib directory."    gmake install || error_exit "Installation of contrib modules failed."        cd .. || error_exit "Failed to return to main PostgreSQL directory."
}

setup_environment() {    echo "Setting up environment variables..."    if ! grep -q "$POSTGRES_PREFIX/bin" /etc/profile; then        echo "export PATH=\"$POSTGRES_PREFIX/bin:\$PATH\"" >> /etc/profile || warning_message "Failed to update /etc/profile."        . /etc/profile || warning_message "Failed to source /etc/profile."    else        echo "PATH already includes $POSTGRES_PREFIX/bin."    fi
}

initialize_database() {    echo "Initializing the PostgreSQL database..."    mkdir -p "$DATA_DIR" || error_exit "Failed to create data directory."    chown postgres:postgres "$DATA_DIR"    su -m postgres -c "$POSTGRES_PREFIX/bin/initdb -D $DATA_DIR" || error_exit "Database initialization failed."
}

create_extension_pg_trgm() {    echo "Creating pg_trgm extension..."    su -m postgres -c "$POSTGRES_PREFIX/bin/psql -d postgres -c 'CREATE EXTENSION IF NOT EXISTS pg_trgm;'" || warning_message "Failed to create pg_trgm extension. You may need to create it manually in your databases."
}

start_postgresql() {    echo "Starting PostgreSQL..."    su -m postgres -c "$POSTGRES_PREFIX/bin/pg_ctl -D $DATA_DIR -l $LOGFILE -w start"    sleep 5  # Give the server a moment to start up    if ! su -m postgres -c "$POSTGRES_PREFIX/bin/pg_isready -q"; then        check_log_file        error_exit "Failed to start PostgreSQL."    fi    echo "PostgreSQL started successfully."
}

check_log_file() {    echo "Checking PostgreSQL log file for errors..."    if [ -f "$LOGFILE" ]; then        tail -n 50 "$LOGFILE"    else        echo "Log file not found at $LOGFILE"    fi
}

verify_custom_options() {    echo "Verifying custom build options..."    su -m postgres -c "$POSTGRES_PREFIX/bin/psql -d postgres -c \"SHOW block_size;\"" || warning_message "Failed to verify block size."    su -m postgres -c "$POSTGRES_PREFIX/bin/psql -d postgres -c \"SHOW segment_size;\"" || warning_message "Failed to verify segment size."    echo "Checking PostgreSQL version and compile-time options:"    su -m postgres -c "$POSTGRES_PREFIX/bin/postgres -V"    su -m postgres -c "$POSTGRES_PREFIX/bin/pg_config --configure"        echo "Verifying pg_trgm extension installation:"    su -m postgres -c "$POSTGRES_PREFIX/bin/psql -d postgres -c \"SELECT * FROM pg_extension WHERE extname = 'pg_trgm';\"" || warning_message "Failed to verify pg_trgm extension."
}

stop_postgresql() {    echo "Stopping PostgreSQL..."    if command -v "$POSTGRES_PREFIX/bin/pg_ctl" > /dev/null 2>&1; then        su -m postgres -c "$POSTGRES_PREFIX/bin/pg_ctl -D $DATA_DIR stop -m fast" || warning_message "Failed to stop PostgreSQL."    else        echo "pg_ctl command not found; assuming PostgreSQL is not running."    fi
}

uninstall_postgresql() {    echo "Uninstalling PostgreSQL..."    stop_postgresql    if [ -d "$POSTGRES_PREFIX" ]; then        rm -rf "$POSTGRES_PREFIX" || warning_message "Failed to remove PostgreSQL directories."        echo "PostgreSQL uninstalled successfully."    else        echo "No PostgreSQL installation detected."    fi
}

perform_installation() {    check_prerequisites    create_postgres_user    ensure_install_directory    download_postgresql    configure_postgresql    compile_postgresql    install_postgresql    setup_environment    initialize_database    start_postgresql    create_extension_pg_trgm    check_log_file    verify_custom_options    echo "PostgreSQL installed and configured successfully with pg_trgm extension!"
}

# Ensure cleanup happens on script exit
trap cleanup EXIT

# Main function
case "$1" in    stop)        stop_postgresql        ;;    uninstall)        uninstall_postgresql        ;;    install)        perform_installation        ;;    *)        echo "Usage: $0 {install|stop|uninstall}"        exit 1        ;;
esac