のぴぴのメモ

自分用のLinuxとかの技術メモ

PostgreSQL11.6のクライアントの共有ライブラリ&開発ツール(32bit)をソースコードからビルドする手順(on RHEL8)

はじめに

諸事情で、PostgreSQL11.6 クライアントとクライアントの開発環境(ECPG - C言語による埋め込みSQLのアプリ用ビルド環境)をRHEL8上で、32bitで準備する必要があって手順を確認したものです。32bitでビルドするポイントはconfigureの時にオプションで--build="i686-pc-linux-gnu" "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32"とすることです。

環境

手順

ビルドに必要なパッケージのインストール

bzip2はtarの解凍に、glibc-devel.i686 readline-devel.i686 zlib-devel.i686は、PostgreSQL11.7(32bit)のビルドの前提です。

sudo yum -y install gcc bzip2 make
sudo yum -y install glibc-devel.i686 readline-devel.i686 zlib-devel.i686

ソースコードのダウンロードと展開

curl https://ftp.postgresql.org/pub/source/v11.6/postgresql-11.6.tar.bz2 --output postgresql-11.6.tar.bz2
tar -jxf postgresql-11.6.tar.bz2
cd postgresql-11.6

PostgreSQL11.6 のビルドとインストール

インストール先はデフォルトは/usr/local/pgsql/になります。ここではインストール先を--prefix=XXXXオプションで/usr/local/pgsql-i686に指定します。

./configure --build="i686-pc-linux-gnu" "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32" --prefix="/usr/local/pgsql-i686"
make

sudo make install

確認

32bitのバイナリーが出来上がっていることを確認します。

cd /usr/local/pgsql-i686/

#ファイルの確認
file lib/libpq.so.5.11 
lib/libpq.so.5.11: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=a8582904f50478302be75a9aea0174f414dc9b04, not stripped

実行パスの追加

インストールしたPostgreSQL11.6 クライアント(32bit)のコマンドが実行できるようにパスを追加します。

#プロファイルにパスを追加
echo 'PATH="$PATH:/usr/local/pgsql-i686/bin"' >> ~/.bashrc
source ~/.bashrc

#パスの確認
which ecpg
/usr/local/pgsql-i686/bin/ecpg   <-- ecpgコマンドが表示されることを確認

サンプルプログラムでの動作確認

ECPGによるC言語による埋め込みSQLのサンプルプログラムを利用した32bitアプリケーションのビルドとDBへの接続テストを行います。

サンプルコード(sample.pgc)

ファイル名sample.pgcで、下記サンプルコードを書きます。
こちらのコードは、DBにコネクトして、DB名の取得とカレンと時間を取得するだけのDB接続テスト用のサンプルコードです。

#include <stdio.h>
#include <string.h>

#define BUFF_SIZE 1024

EXEC SQL BEGIN DECLARE SECTION;
    char    dbname[BUFF_SIZE];
    char    tmpstr[BUFF_SIZE];
    char    target[BUFF_SIZE];
    char    user[BUFF_SIZE];
    char    pass[BUFF_SIZE];
EXEC SQL END DECLARE SECTION;

int main(int argc, char **argv)
{
    if( argc > 3 ){
        strncpy(target, *(argv+1), BUFF_SIZE);
        strncpy(user,   *(argv+2), BUFF_SIZE);
        strncpy(pass,   *(argv+3), BUFF_SIZE);
    }else{
        printf("Invalid argument(s): ./sample 'dbname@host:port' 'user' 'password'\n");
        return(1);
    }

    printf("target=%s user=%s pass=%s\n",target, user, pass);

    EXEC SQL CONNECT TO :target USER :user IDENTIFIED BY :pass;

    EXEC SQL SELECT current_database() INTO :dbname;
    printf("current_database=%s \n", dbname);
    
    EXEC SQL select cast(current_timestamp as varchar) INTO :tmpstr;
    printf("current_timestamp=%s \n", tmpstr);

    EXEC SQL DISCONNECT;
    return 0;
}

ビルド

下記コマンドでビルドします。

ecpg sample.pgc
gcc -o sample -m32 -I/usr/local/pgsql-i686/include/ -L/usr/local/pgsql-i686/lib/ -lecpg -lpq -Wl,--rpath=/usr/local/pgsql-i686/lib/ sample.c
  • ecpg: 埋め込みSQLプリプロセッサです。EXEC SQL BEGIN DECLARE SECTIONの埋め込みSQLをライブラリの関数呼び出し形式に変換してコンパイル可能なCのコードを出力します。
  • gcc: 実行バイナリーを作成します。

テスト

下記コマンドを実行し、データベース名と現在の時刻が表示されれば接続成功です。

./sample "DBNAME@Host:Port" "UserName" "Password"
current_database=データベース名が表示 
current_timestamp=現在の時刻が表示