趣味的にHDF5ライブラリをmakeする（M1 Mac: arm64アークテクチャ）

# はじめに
　この記事では、地球観測衛星のファイル形式によく使われいてるHDF5 (Hierarchical Data Format version 5) 形式のファイルを読み書きするためのライブラリを、M1 Mac (mac OS Monterey 12.3) にmakeしてインストールする手順を説明します。HDF5の詳細は[本家(en)](https://www.hdfgroup.org/solutions/hdf5/)や[Wikipedia](https://ja.wikipedia.org/wiki/Hierarchical_Data_Format) からどうぞ。
　とは言っても、本家からPre-built Binaryが配布されているのでmakeしなくてもHDF5ライブラリは簡単にインストールできますので、この記事ではあえてソースコードからmakeでインストールを行う方向けの内容となります。
　HDF5は内部のデータを圧縮して保存でき、gzip形式がデフォルトで、オプションでszip形式を利用できます。この記事ではszipも読み込める様にHDF5をmakeしますが、szipのコンパイルにはcmakeを用いるので、cmakeが入ってないない場合は先にインストールが必要となります（Macには標準で入っていません）。szipはオプションなので、要らない場合は必要ありません。

# szlib? aeclib?
 　HDF5はszip形式を従来szlibを用いて読み書きしていましたが、[HDFのページで案内](https://portal.hdfgroup.org/display/HDF5/Szip+Compression+in+HDF+Products)されている様に、HDF5-1.10.7以降はオープンソース版のAECライブラリを使用するように切り替わったとのことです。本記事ではHDF5-1.12.1を利用するのでaeclibを利用します。

:::note warn
Please be aware that SZIP compression has been replaced by AEC compression as of HDF5-1.10.7. AEC is the open source version of SZIP.
HDF5-1.10.7時点でSZIP圧縮はAEC圧縮に変わったので注意してください。AECはSZIPのオープンソース版です。

The AEC library can be obtained from the German Climate Computing Center from:
AECライブラリはGerman Climate Computing Centerから取得できます：

https://gitlab.dkrz.de/k202009/libaec
:::

※ https://portal.hdfgroup.org/display/HDF5/Szip+Compression+in+HDF+Products より

# ソースコードの配布元
　本手順では、以下バージョンのライブラリを使用しています。必要に応じて新しいバージョンのライブラリを使用してください。

* zlib 1.2.12
http://zlib.net/zlib-1.2.12.tar.gz

* libaec-v1.0.6
https://gitlab.dkrz.de/k202009/libaec/-/tree/v1.0.6

* HDF5-1.12.1
https://www.hdfgroup.org/downloads/hdf5/source-code/
=> hdf5-1.12.1.tar.gz
ログインする必要があるので、アカウントがない人は作ってからダウンロードしてください（無料）。

# HDF5-1.12.1のmake手順
　この手順では`/lib`や`/opt`ディレクトリを汚したくないため、自分（hoge）のhomeディレクトリ下に作った`/Users/hoge/local`ディレクトリにインストールします。趣味の問題なので、特にこだわりがなければ以下の手順中で./configureから--prefixを省略し、デフォルトの場所にインストールして下さい。
　以下の手順でインストールを行います。

1. zlibのmake
1. aeclibのmake
1. HDF5ライブラリのmake

## zlibのmake
　zlibをM1 (arm64用) にコンパイルします。まず、ダウンロードしたzlib.tar.gzを適当な場所に解凍し、作成されたディレクトリに移動します。そして、以下のコマンドを順番に実行します。

```sh
cd zlib-1.2.12
mkdir build
cd build
CC=clang ../configure --prefix="/Users/hoge/local" --static --shared
make
make test
make install
```

## aeclibのcmake
　aeclibをM1 (arm64用) にコンパイルします。まず、ダウンロードしたlibaec-v1.0.6.tar.gzを適当な場所に解凍し、作成されたディレクトリに移動します。そして、以下のコマンドを順番に実行します。

```sh
cd libaec-v1.0.6
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/Users/hoge/local ..
make
make test
make install
```

## HDF5ライブラリのmake
　hdf5ライブラリをM1 (arm64用) にコンパイルします。まず、ダウンロードしたlibaec-v1.0.6.tar.gzを適当な場所に解凍し、作成されたディレクトリに移動します。そして、以下のコマンドを順番に実行します。

**1: configure**

```sh
mkdir build
cd build
../configure --prefix="/Users/hoge/local" --enable-build-mode="production" --with-zlib="/Users/hoge/local/include,/Users/hoge/local/lib" --with-szlib="/Users/hoge/local/include,/Users/hoge/local/lib"  CC="clang" LDFLAGS="-Wl,-rpath,/Users/hoge/local/lib"
```
 configure  ここまでにインストールしたzlibとaeclibを以下オプションで指定してconfigureします。

| 引数 | 説明 | 
|:-----------:|:------------:|
| --with-zlib=INC,LIB | zlibを指定する。カンマ(,)で分割してincludeディレクトリとlibディレクトリを別々に指定する。 | 
| --with-szlib=INC,LIB | szlibを指定する。カンマ(,)で分割してincludeディレクトリとlibディレクトリを別々に指定する。 | 

これら圧縮ライブラリを、ここまでの手順従ってシステムフォルト以外の場所にインストールした場合（この手順では`/Users/hoge/local/lib`）、その場所をrpath[^1]としてライブラリ実行時の依存ライブラリ検索先ディレクトリとして指定します。この設定はコンパイル時にリンカによって行われるため、以下の様にLDFLAGSを設定してリンカに渡しています。

```sh
LDFLAGS="-Wl,-rpath,LIB"
```
ここで、`-rpath=LIB`ではなく、`--rpath,LIB`で指定します。これはclangの仕様とのことで、gccの場合はどちらでも良いみたいです（[参考(en)](https://github.com/klee/klee/issues/591#issuecomment-799562331)）。また、今後この設定でmakeしたHDF5ライブラリを使用する場合、rpathで指定したディレクトリにリンクしたい動的ライブラリがないと実行に失敗します。そのため、このHDF5ライブラリを使用する限り、zlibとaeclibは動かさないでください[^2]。


[^1]: プログラムが実行時に動的ライブラリを呼び出す際、検索対象として追加されるディレクトリ。リンカーの-rpathフラグ等により指定されます。Unix系では`LD_LIBRARY_PATH`環境変数だったり、Macなら`DYLD_LIBRARY_PATH`環境変数にディレクトリを設定すれば同じことができたのだけど、OSアップデートのセキュリティアップデートでデフォルトで使えなくされたりしているので、ここではrpathを使って設定しています。

[^2]: もしzlibとaeclibを動かす必要があるならば、rpathで指定してディレクトリ内にそれぞれのシンボリックリンクを貼ってください。それか、HDF5ライブラリを再度makeして下さい。

**2: make**
　configureで指定さた設定で、HDF5ライブラリをmakeしてinstallします。この`make`と`make check`はかなり時間が掛かりますので、ゆっくり待つことが肝要です。ちなみに、INSTALLドキュメントにはmake時に`-j -lN`で並列コンパイルも可能と書いてあるのですが、これを行うとzlibの依存関係でmakeが失敗するため、この手順では行なっていません。zlibを指定せずにシステムデフォルトの物を使用すればもしかしたら可能なのかもしれませんが、未確認となります。

```sh
make 
make check
make install
make check-install
```

checkを行いエラーが起きなければ、M1(arm64)用HDF5ライブラリのmakeは完了となります。