psycopg2-binaryのインストール時のエラーを解決する

# はじめに

- `psycopg2-binary`のインストール時に毎回エラーが出ている気がするので、自分の環境でよく出るエラーとその解決策についてまとめておく

# `psycopg2-binary`とは

- PythonでPostgreSQLのデータベースに接続するためのライブラリ([DB-API 2.0](https://peps.python.org/pep-0249/)に準拠)
- `psycopg2`(サイコップ)のバイナリ版のパッケージ
- バイナリ版とはいえ、いくつかの共有ライブラリに依存しており、インストール時にそのライブラリが存在しない場合はインストールに失敗する

# エラー１: `ld: library not found for -lssl`

## 動作環境

- OS: macOS Ventura

## エラーログ

```bash
$ pipenv install psycopg<2.9
...
[pipenv.exceptions.InstallError]:       ld: library not found for -lssl
[pipenv.exceptions.InstallError]:       clang: error: linker command failed with exit code 1 (use -v to see invocation)
[pipenv.exceptions.InstallError]:       error: command '/usr/bin/clang' failed with exit code 1
[pipenv.exceptions.InstallError]:       [end of output]
[pipenv.exceptions.InstallError]:   
[pipenv.exceptions.InstallError]:   note: This error originates from a subprocess, and is likely not a problem with pip.
[pipenv.exceptions.InstallError]: error: legacy-install-failure
[pipenv.exceptions.InstallError]: 
[pipenv.exceptions.InstallError]: × Encountered error while trying to install package.
[pipenv.exceptions.InstallError]: ╰─> psycopg2-binary
...
```

## 原因

- `ld`が`libssl`を見つけられないことでエラーが発生している
- `ld`はGNUプロジェクトで開発されているリンカ
- `libssl`はOpenSSLを構成する主要なライブラリの１つ(もう１つは`libcrypto`)
- `libssl`は`psycopg2-binary`がPostgreSQLとSSL/TLS通信を行う際に必要とする共有ライブラリ
- macOS環境では、OpenSSLが標準の場所にインストールされていないため、このような問題が発生することがある

## 解決策

- シェルの環境変数に適切なパスを設定する
- HomebrewでインストールしたOpenSSLの場合は以下のような設定となる

```bash
$ export LDFLAGS=-L/usr/local/opt/openssl@3/lib
```

- `LDFLAGS`は`ld`等のリンカに対して、リンク時のオプションを指定するフラグで、この場合は`libssl`のパスを指定することによって、リンク時に`ld`が`libssl`を参照できるように設定している

# エラー２: `Error: pg_config executable not found.`

## 動作環境

- Dockerイメージ: `python:3.10.8-slim`
    - OS(ディストリビューション)はDebian 11(bullseye)

## エラーログ

```bash
$ pipenv install psycopg<2.9
...
[pipenv.exceptions.InstallError]:       Error: pg_config executable not found.
[pipenv.exceptions.InstallError]:       
[pipenv.exceptions.InstallError]:       pg_config is required to build psycopg2 from source.  Please add the directory
[pipenv.exceptions.InstallError]:       containing pg_config to the $PATH or specify the full executable path with the
[pipenv.exceptions.InstallError]:       option:
[pipenv.exceptions.InstallError]:       
[pipenv.exceptions.InstallError]:           python setup.py build_ext --pg-config /path/to/pg_config build ...
[pipenv.exceptions.InstallError]:       
[pipenv.exceptions.InstallError]:       or with the pg_config option in 'setup.cfg'.
[pipenv.exceptions.InstallError]:       
[pipenv.exceptions.InstallError]:       If you prefer to avoid building psycopg2 from source, please install the PyPI
[pipenv.exceptions.InstallError]:       'psycopg2-binary' package instead.
[pipenv.exceptions.InstallError]:       
[pipenv.exceptions.InstallError]:       For further information please check the 'doc/src/install.rst' file (also at
[pipenv.exceptions.InstallError]:       <https://www.psycopg.org/docs/install.html>).
[pipenv.exceptions.InstallError]:       
[pipenv.exceptions.InstallError]:       [end of output]
...
```

## 原因

- `pg_config`が見つからないため、エラーが発生している
- `pg_config`はPostgreSQLのDBのインストールに関する情報を提供するユーティリティ
- `pg_config`は`libpq-dev`パッケージに含まれている

## 解決策

- `libpq-dev`パッケージをインストールする

```bash
$ apt-get update
$ apt-get install libpq-dev -y
```

# エラー３: `error: command 'gcc' failed: No such file or directory`

## 動作環境

- Dockerイメージ: `python:3.10.8-slim`
    - OS(ディストリビューション)はDebian 11(bullseye)

## エラーログ

```bash
$ pipenv install psycopg<2.9
...
[pipenv.exceptions.InstallError]:       running build_ext
[pipenv.exceptions.InstallError]:       building 'psycopg2._psycopg' extension
[pipenv.exceptions.InstallError]:       creating build/temp.linux-x86_64-cpython-310
[pipenv.exceptions.InstallError]:       creating build/temp.linux-x86_64-cpython-310/psycopg
[pipenv.exceptions.InstallError]:       gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC "-DPSYCOPG_VERSION=2.8.6 (dt dec pq3 ext lo64)" -DPG_VERSION_NUM=130009 -DHAVE_LO64=1 -I/usr/local/include/python3.10 -I. -I/usr/include/postgresql -I/usr/include/postgresql/13/server -c psycopg/adapter_asis.c -o build/temp.linux-x86_64-cpython-310/psycopg/adapter_asis.o -Wdeclaration-after-statement
[pipenv.exceptions.InstallError]:       
[pipenv.exceptions.InstallError]:       It appears you are missing some prerequisite to build the package from source.
[pipenv.exceptions.InstallError]:       
[pipenv.exceptions.InstallError]:       You may install a binary package by installing 'psycopg2-binary' from PyPI.
[pipenv.exceptions.InstallError]:       If you want to install psycopg2 from source, please install the packages
[pipenv.exceptions.InstallError]:       required for the build and try again.
[pipenv.exceptions.InstallError]:       
[pipenv.exceptions.InstallError]:       For further information please check the 'doc/src/install.rst' file (also at
[pipenv.exceptions.InstallError]:       <https://www.psycopg.org/docs/install.html>).
[pipenv.exceptions.InstallError]:       
[pipenv.exceptions.InstallError]:       error: command 'gcc' failed: No such file or directory
[pipenv.exceptions.InstallError]:       [end of output]
...
```

## 原因

- `gcc`が見つからないため、エラーが発生している

## 解決策

- `gcc`をインストールする

```bash
$ apt-get update
$ apt-get install gcc -y
```