PostgreSQL の RPM パッケージをビルドするには

[PostgreSQL 開発元の Yum リポジトリ](https://yum.postgresql.org/) では、新しいマイナーバージョンがリリースされると、古いものが削除されてしまいます。そのため、古いマイナーバージョンをインストールしたければ、自分で RPM パッケージをビルドしなければなりません。

そこで、ここでは PostgreSQL の RPM パッケージをビルドする手順について説明します。

1. RPM パッケージのビルドに必要なパッケージをインストールします。

    ```shell-session
    # yum -y install git rpm-build gcc bison flex perl-ExtUtils-Embed \
        python-devel tcl-devel readline-devel zlib-devel openssl-devel \
        krb5-devel e2fsprogs-devel libxml2-devel libxslt-devel pam-devel \
        systemtap-sdt-devel libuuid-devel openldap-devel systemd-devel
    (省略)
    完了しました!
    ```

1. PostgreSQL 関連 RPM パッケージビルド用の Git リポジトリをクローンします。

    いくら待ってもクローンが終わらないので、はじめに最新のコミットのみをクローンし、あとで残りをフェッチするようにしました。

    ```shell-session
    # git clone --depth=1 https://git.postgresql.org/git/pgrpms.git
    Cloning into 'pgrpms'...
    remote: Counting objects: 8801, done.
    remote: Compressing objects: 100% (5324/5324), done.
    remote: Total 8801 (delta 3520), reused 5378 (delta 1723)
    Receiving objects: 100% (8801/8801), 51.55 MiB | 771.00 KiB/s, done.
    Resolving deltas: 100% (3520/3520), done.
    # cd pgrpms
    # git fetch --unshallow
    remote: Counting objects: 67268, done.
    remote: Compressing objects: 100% (33060/33060), done.
    remote: Total 67268 (delta 42052), reused 53885 (delta 30844)
    Receiving objects: 100% (67268/67268), 133.80 MiB | 661.00 KiB/s, done.
    Resolving deltas: 100% (42052/42052), completed with 1006 local objects.
    ```

1. RPM パッケージがビルドされた時点のコミットをチェックアウトします。

    とくにタグが打たれているわけではないので、どのコミットをチェックアウトするかはログを見て判断するしかありません。そのバージョンに更新したというログがあれば、そのコミットでおそらく問題ないでしょう。ここでは、バージョン 9.6.3 をビルドすることにします。

    ```shell-session
    # git log --oneline | grep -F 9.6.3
    eb2cbe0 PostgreSQL/9.6: Update to 9.6.3, switch to symlinks, and delete obsoleted patch from RHEL 6 directory.
    # git checkout eb2cbe0
    Note: checking out 'eb2cbe0'.
    
    You are in 'detached HEAD' state. You can look around, make experimental
    changes and commit them, and you can discard any commits you make in this
    state without impacting any branches by performing another checkout.
    
    If you want to create a new branch to retain commits you create, you may
    do so (now or later) by using -b with the checkout command again. Example:
    
      git checkout -b new_branch_name
    
    HEAD is now at eb2cbe0... PostgreSQL/9.6: Update to 9.6.3, switch to symlinks, and delete obsoleted patch from RHEL 6 directory.
    ```

1. RPM パッケージのビルドに必要なファイルが置いてあるディレクトリに移動し、Git リポジトリに入っていないファイルをダウンロードします。

    ダウンロードが必要なのは PostgreSQL のソースコードと PDF 形式のマニュアルです。

    ```shell-session
    # cd rpm/redhat/9.6/postgresql/EL-7
    # curl -Os https://download.postgresql.org/pub/source/v9.6.3/postgresql-9.6.3.tar.bz2
    # curl -Os https://www.postgresql.org/files/documentation/pdf/9.6/postgresql-9.6-A4.pdf
    ```

1. 最後に RPM パッケージをビルドします。

    spec ファイルでエラーが発生した場合には、その後のコミットで修正されているはずなので、チェックアウトするコミットを進めてビルドしなおすといいでしょう。

    ```shell-session
    # rpmbuild -ba -D "_sourcedir $(pwd)" -D "dist .rhel7" postgresql-9.6.spec
    (省略)
    + exit 0
    ```

    ビルドが終わると、RPM パッケージができています。

    ```shell-session
    # ls ~/rpmbuild/RPMS/x86_64
    postgresql96-9.6.3-1PGDG.rhel7.x86_64.rpm
    postgresql96-contrib-9.6.3-1PGDG.rhel7.x86_64.rpm
    postgresql96-debuginfo-9.6.3-1PGDG.rhel7.x86_64.rpm
    postgresql96-devel-9.6.3-1PGDG.rhel7.x86_64.rpm
    postgresql96-docs-9.6.3-1PGDG.rhel7.x86_64.rpm
    postgresql96-libs-9.6.3-1PGDG.rhel7.x86_64.rpm
    postgresql96-plperl-9.6.3-1PGDG.rhel7.x86_64.rpm
    postgresql96-plpython-9.6.3-1PGDG.rhel7.x86_64.rpm
    postgresql96-pltcl-9.6.3-1PGDG.rhel7.x86_64.rpm
    postgresql96-server-9.6.3-1PGDG.rhel7.x86_64.rpm
    postgresql96-test-9.6.3-1PGDG.rhel7.x86_64.rpm
    ```