netCDF4 C++ APIのビルド備忘録

なんか仕事でnetCDF4を使いそうなのでインストールしました。いつもの備忘録です。
~~spackでもいいんだけどMPI版が入ってしまうので微妙。。。~~

# 環境
OS: `Red Hat Enterprise Linux Server release 7.8 (Maipo)`

## 依存ライブラリ
- gcc/7.4.0
- hdf5/1.8.12 (serial)
- cmake/3.19.2
- zlib/1.2.11
- curlも必要らしいけど元々入ってたのを使ったのでバージョン不明

## ビルドするnetCDF4のバージョン
- [netCDF-c](https://github.com/Unidata/netcdf-c)/v4.8.1
- [netcdf-cxx4](https://github.com/Unidata/netcdf-cxx4)/v4.3.1

インストールディレクトリは以下を想定
```
$HOME/ulocal/install
 |- netcdf4
   |- c/4.8.1
   |- cxx/4.3.1
```

# ビルド手順

## modulefiles
ビルドの途中で依存関係が出てきそうなのでEnvironment Modulesでパスを通しておく。CMakeのPATHでもいいんだろうけどそっちはよくわかりません。。

```tcl:netcdf4
#%Module
#

## netcdf4-c
set base $::env(HOME)/ulocal/install/netcdf4/c/4.6.1
prepend-path PATH               $base/bin
prepend-path C_INCLUDE_PATH     $base/include
prepend-path CPLUS_INCLUDE_PATH $base/include
prepend-path LD_LIBRARY_PATH    $base/lib64
prepend-path MAN_PATH           $base/share/man

## netcdf4-cxx
set base $::env(HOME)/ulocal/install/netcdf4/cxx/4.3.1
prepend-path PATH               $base/bin
prepend-path CPLUS_INCLUDE_PATH $base/include
prepend-path LD_LIBRARY_PATH    $base/lib64
```

## netcdf4-c
GitHubからソース取ってきてビルドするいつものやつです。
なんですがなんかコンパイルが落ちる。。とりあえずv4.6.1かv4.8.1なら通ったけど。。
**追記**: v4.8.1だとnetcdf4-cxxが落ちるのでv4.6.1が良さそうですね
**さらに追記**: `-D CMAKE_BUILD_TYPE=Release` にしたら4.8.1でも通りました。

```bash
module load gcc cmake hdf5 netcdf4
version=4.8.1
git clone https://github.com/Unidata/netcdf-c
cd netcdf-c
git co v${version} -b _v${version}
mkdir build && cd build
cmake .. \
  -D CMAKE_INSTALL_PREFIX=$HOME/ulocal/install/netcdf4/c/${version} \
  -D CMAKE_C_COMPILER=gcc \
  -D CMAKE_BUILD_TYPE=Release
make
make install
```

## netcdf4-cxx
netcdf4-cに依存しているらしいので上のビルドのあとパスを通してから実行しましょう。
`netcdf-cxx4/cxx4/ncFilter.cpp:28:11: error: ‘nc_inq_var_filter’ was not declared in this scope`みたいなエラーが出たらパスが正しいか確認しまししょう。

バージョンはとりあえず原稿執筆時点の最新版のv4.3.1にしておきます。
```bash
module load gcc cmake hdf5 netcdf4
version=4.3.1
https://github.com/Unidata/netcdf-cxx4
cd netcdf-cxx4
git co v${version} -b _v${version}
mkdir build && cd build
cmake .. \
  -D CMAKE_INSTALL_PREFIX=$HOME/ulocal/install/netcdf4/cxx/${version} \
  -D CMAKE_C_COMPILER=gcc \
  -D CMAKE_CXX_COMPILER=g++ \
  -D CMAKE_BUILD_TYPE=Release
make
make install
```

# 動作確認
公式のexmapleの[simple_xy_wr.cpp](http://unidata.github.io/netcdf-cxx4/simple__xy__wr_8cpp_source.html)を実行してみます。

makeの方法はよくわかりません。いつものようにmakefile書きましょう。
`ncxx4-config`を使えば必要なcxxflagsとかldflagsとかを取得できるらしいのでそれで。
```makefile
CXX := $(shell ncxx4-config --cxx)
CXXFLAGS := -Wall -Wextra -O3
CXXFLAGS += $(shell ncxx4-config --cflags)
CXXFLAGS += $(shell ncxx4-config --libs)

EXECUTABLE := simple_xy_wr.out
NCFILE := simple_xy.nc

.PHONY: all test clean

all: $(EXECUTABLE)

test:
        ./$(EXECUTABLE)
        ncinfo $(NCFILE)

.cpp.out:
        $(CXX) $(CXXFLAGS) $< -o $@

clean:
        rm -f $(EXECUTABLE)
        rm -f $(NCFILE)
```

```bash
$ module load gcc hdf5 netcdf4

$ make
/home/app/gcc/7.4.0/bin/g++ -Wall -Wextra -O3 -I/home/g4/a190094/ulocal/install/netcdf4/cxx/4
.3.1/include -L/home/g4/a190094/ulocal/install/netcdf4/cxx/4.3.1/lib64 -lnetcdf-cxx4 -lnetcdf
 simple_xy_wr.cpp -o simple_xy_wr.out
/usr/bin/ld: warning: libnetcdf.so.13, needed by /home/g4/a190094/ulocal/install/netcdf4/cxx/
4.3.1/lib64/libnetcdf-cxx4.so, may conflict with libnetcdf.so.7

$ make test
./simple_xy_wr.out
ncinfo simple_xy.nc
<class 'netCDF4._netCDF4.Dataset'>
root group (NETCDF4 data model, file format HDF5):
    dimensions(sizes): x(6), y(12)
    variables(dimensions): int32 data(x, y)
    groups: 
```

とりあえず動いたっぽいですね。お疲れ様でした。（~~`ld: warning: conflict`とは。。。~~ → /usr 以下にHDF5が入ってて$HOME以下のHDF5とバージョン競合していただけのようですね。しかもなんか`H5Free unsupported` みたいなエラーが出る不完全なバージョンだったので謎。。。）