カタパルトサーバーのマニュアルビルド方法


# 概要
Symbolのカタパルトサーバーのマニュアルビルド方法です。

# 環境

```bash
$ uname -a
Linux vmi649314.contaboserver.net 5.4.0-105-generic #119-Ubuntu SMP Mon Mar 7 18:49:24 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
```

```bash
$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="20.04.5 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.5 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
```

## python
```bash
$ python3 -V
>Python 3.9.18
```

## openssl
```bash
$ openssl version
>OpenSSL 1.1.1f  31 Mar 2020
```
OpenSSlはバージョンが低かったので以下の手順で入れ直し

```bash
$ sudo apt update
# 依存関係をインストール
$ sudo apt install build-essential checkinstall zlib1g-dev -y
# 3.1.0のソースコードを取得
$ sudo wget https://github.com/openssl/openssl/releases/download/openssl-3.1.0/openssl-3.1.0.tar.gz
# 解凍、ビルド、インストール
$ sudo tar xvf openssl-3.1.0.tar.gz
$ cd openssl-3.1.0/
$ ./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl shared zlib
$ make
$ sudo make install
# 設定ファイル
$ cat <<- __EOF__ | sudo tee -a /etc/ld.so.conf.d/openssl-3.1.1.conf
/usr/local/ssl/lib64
__EOF__
# 設定反映
$ sudo ldconfig -v
# パスを通す
$ sudo tee /etc/profile.d/openssl.sh<<EOF
export PATH=/usr/local/ssl/bin:\$PATH
export LD_LIBRARY_PATH=/usr/local/ssl/lib:\$LD_LIBRARY_PATH
export OPENSSL_ROOT_DIR=/usr/local/ssl
EOF
$ source /etc/profile.d/openssl.sh
# バージョンの確認
$ openssl version
OpenSSL 3.1.0 14 Mar 2023 (Library: OpenSSL 3.1.0 14 Mar 2023)
```

# 前提条件
- git
- python3.7+
- openssl3.1.0+
- 約15GBの空きディスク容量

# ビルド

## ステップ1

catapult-clientのクローン

```bash
$ git clone https://github.com/symbol/symbol.git
# v1.0.3.6のタグを指定してチェックアウト
$ git checkout -b v1.0.3.6 refs/tags/client/catapult/v1.0.3.6
$ cd symbol/client/catapult
```

## ステップ2

ソースからすべての依存関係をダウンロード、ビルド、インストールする

```bash
$ PYTHONPATH="../../jenkins/catapult/" python3 "../../jenkins/catapult/installDepsLocal.py" \
	--target "./_deps" \
	--versions "../../jenkins/catapult/versions.properties" \
	--download \
	--build
```

各ツールのダウンロード&ビルドに~~少し~~かなり時間がかかります

### cmakeのエラーが発生した時

```bash
[*] cmake
      -DCMAKE_BUILD_TYPE=RelWithDebInfo
      -DCMAKE_INSTALL_PREFIX=/home/dai/src/symbol/client/catapult/_deps/google
      -DCMAKE_POSITION_INDEPENDENT_CODE=ON
      -DBUILD_GMOCK=OFF
      ..
Traceback (most recent call last):
  File "/home/dai/src/symbol/client/catapult/../../jenkins/catapult/installDepsLocal.py", line 195, in <module>
    main()
  File "/home/dai/src/symbol/client/catapult/../../jenkins/catapult/installDepsLocal.py", line 191, in main
    builder.build_git_dependency(repository[0], repository[1])
  File "/home/dai/src/symbol/client/catapult/../../jenkins/catapult/installDepsLocal.py", line 105, in build_git_dependency
    self.process_manager.dispatch_subprocess(cmake_options + ['..'])
  File "/home/dai/src/symbol/jenkins/catapult/process.py", line 18, in dispatch_subprocess
    with Popen(command_line, stdout=PIPE, stderr=STDOUT) as process:
  File "/home/dai/.pyenv/versions/3.9.18/lib/python3.9/subprocess.py", line 951, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/home/dai/.pyenv/versions/3.9.18/lib/python3.9/subprocess.py", line 1837, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'cmake'
```

### 解決策

CMakeを入れる

```bash
$ sudo apt install -y software-properties-common
$ wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null
$ sudo apt-add-repository "deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main"
$ sudo apt update
$ sudo apt -y install cmake
$ cmake --version
cmake version 3.28.1

CMake suite maintained and supported by Kitware (kitware.com/cmake).
```

### mv boost_1_80_0 boost exited with 1 などのエラーが出る

```bash
[*] tar -xzf boost_1_80_0.tar.gz
[*] mv boost_1_80_0 boost
mv: cannot move 'boost_1_80_0' to 'boost/boost_1_80_0': Directory not empty
Traceback (most recent call last):
  File "/home/dai/src/symbol/client/catapult/../../jenkins/catapult/installDepsLocal.py", line 195, in <module>
    main()
  File "/home/dai/src/symbol/client/catapult/../../jenkins/catapult/installDepsLocal.py", line 173, in main
    downloader.download_boost()
  File "/home/dai/src/symbol/client/catapult/../../jenkins/catapult/installDepsLocal.py", line 22, in download_boost
    self.download_boost_unix()
  File "/home/dai/src/symbol/client/catapult/../../jenkins/catapult/installDepsLocal.py", line 31, in download_boost_unix
    self.process_manager.dispatch_subprocess(['mv', f'boost_1_{version}_0', 'boost'])
  File "/home/dai/src/symbol/jenkins/catapult/process.py", line 39, in dispatch_subprocess
    raise SubprocessError(f'{formatted_command_line} exited with {process.returncode}')
subprocess.SubprocessError: mv boost_1_80_0 boost exited with 1
```

### 解決策

とりあえず、_depsフォルダを削除する（他にも方法はあるが手っ取り早いので）

```bash
$ rm -fr _deps/
```

### CMake Error...Could NOT find PkgConfig　エラーが出る

```bash
CMake Error at /usr/share/cmake-3.28/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE)
Call Stack (most recent call first):
  /usr/share/cmake-3.28/Modules/FindPackageHandleStandardArgs.cmake:600 (_FPHSA_FAILURE_MESSAGE)
  /usr/share/cmake-3.28/Modules/FindPkgConfig.cmake:99 (find_package_handle_standard_args)
  builds/cmake/Modules/FindSodium.cmake:7 (find_package)
  CMakeLists.txt:265 (find_package)


-- Configuring incomplete, errors occurred!
Traceback (most recent call last):
  File "/home/dai/src/symbol/client/catapult/../../jenkins/catapult/installDepsLocal.py", line 195, in <module>
    main()
  File "/home/dai/src/symbol/client/catapult/../../jenkins/catapult/installDepsLocal.py", line 191, in main
    builder.build_git_dependency(repository[0], repository[1])
  File "/home/dai/src/symbol/client/catapult/../../jenkins/catapult/installDepsLocal.py", line 105, in build_git_dependency
    self.process_manager.dispatch_subprocess(cmake_options + ['..'])
  File "/home/dai/src/symbol/jenkins/catapult/process.py", line 39, in dispatch_subprocess
    raise SubprocessError(f'{formatted_command_line} exited with {process.returncode}')
subprocess.SubprocessError: cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/home/dai/src/symbol/client/catapult/_deps/zeromq -DWITH_TLS=OFF .. exited with 1
```

### 解決策

pkg-configを入れる

```bash
$ sudo apt install pkg-config
```

## ツールへのパスを設定

※「root/symbol/client/catapult」の部分はご自分の環境に合わせてください。

```bash
export CAT_DEPS_DIR=/root/symbol/client/catapult/_deps
export CMAKE_PREFIX_PATH=$CAT_DEPS_DIR/boost:$CAT_DEPS_DIR/facebook:$CAT_DEPS_DIR/google:$CAT_DEPS_DIR/mongodb:$CAT_DEPS_DIR/zeromq
export LD_LIBRARY_PATH=$CAT_DEPS_DIR/boost/lib:$CAT_DEPS_DIR/facebook/lib:$CAT_DEPS_DIR/google/lib:$CAT_DEPS_DIR/mongodb/lib:$CAT_DEPS_DIR/zeromq/lib
```

# ステップ3

カタパルトを組み立てる

テストを実行するととてつもなく長いので以下の例では「-DENABLE_TESTS=OFF」を入れてあえてテストを無効にしています。

```bash
$ mkdir -p _build && cd _build
$ BOOST_ROOT="$(realpath ../_deps/boost)" cmake .. \
	-DENABLE_TESTS=OFF \
	-DCMAKE_BUILD_TYPE=RelWithDebInfo \
	-DCMAKE_PREFIX_PATH="$(realpath ../_deps/facebook);$(realpath ../_deps/google);$(realpath ../_deps/mongodb);$(realpath ../_deps/zeromq)" \
	-GNinja
$ ninja publish
$ ninja
```

### Ninjaが見つからない

```bash
CMake Error: CMake was unable to find a build program corresponding to "Ninja".  CMAKE_MAKE_PROGRAM is not set.  You probably need to select a different build tool.
CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage
CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
-- Configuring incomplete, errors occurred!
```

### ninja-buildを入れる

```bash
$ wget https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-linux.zip
$ sudo unzip ninja-linux.zip -d /usr/local/bin/
$ sudo update-alternatives --install /usr/bin/ninja ninja /usr/local/bin/ninja 1 --force
$ /usr/bin/ninja --version
>1.11.1
```

### GTestが見つからない

```bash
CMake Warning (dev) at CMakeLists.txt:36 (find_package):
  Policy CMP0144 is not set: find_package uses upper-case <PACKAGENAME>_ROOT
  variables.  Run "cmake --help-policy CMP0144" for policy details.  Use the
  cmake_policy command to set the policy and suppress this warning.

  Environment variable BOOST_ROOT is set to:

    /home/dai/src/symbol/client/catapult/_deps/boost

  For compatibility, find_package is ignoring the variable, but code in a
  .cmake module might still use it.
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Found Boost: /home/dai/src/symbol/client/catapult/_deps/boost/lib/cmake/Boost-1.80.0/BoostConfig.cmake (found suitable exact version "1.80.0") found components: atomic chrono date_time filesystem log log_setup program_options regex thread 
boost     ver: 1.80.0
boost     inc: /home/dai/src/symbol/client/catapult/_deps/boost/include
boost    libs: Boost::atomic;Boost::chrono;Boost::date_time;Boost::filesystem;Boost::log;Boost::log_setup;Boost::program_options;Boost::regex;Boost::thread
--- locating gtest dependencies ---
CMake Error at /usr/share/cmake-3.28/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Could NOT find GTest (missing: GTEST_LIBRARY GTEST_INCLUDE_DIR
  GTEST_MAIN_LIBRARY) (Required is exact version "1.13.0")
Call Stack (most recent call first):
  /usr/share/cmake-3.28/Modules/FindPackageHandleStandardArgs.cmake:600 (_FPHSA_FAILURE_MESSAGE)
  /usr/share/cmake-3.28/Modules/FindGTest.cmake:270 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  CMakeLists.txt:47 (find_package)
```

### 解決策

GTestを入れます
（本来パスが正しく設定されていれば不要のはず）

```bash
$ sudo apt-get -y install libgtest-dev
```

### なんか変な時

cmakeのキャッシュファイルを削除する

```bash
rm -fr CMakeCache.txt 
```

# ステップ4

検証

以下のように`./bin/catapult.tools.address --help`を実行して結果が返ってくれば成功です。

```
$ ./bin/catapult.tools.address --help

Address Inspector Tool
Copyright (c) Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp.
catapult version: 1.0.3.6 afea1ae8 [v1.0.3.6]

Address Inspector Tool options:
  -h [ --help ]     print help message
  -l [ --loggingConfigurationPath ] arg
                    path to the logging configuration file
  -n [ --network ] arg (=testnet)
                    network, possible values: testnet (default), mainnet
  -i [ --input ] arg
                    input value (comma-delimited) or file
  -o [ --output ] arg
                    (optional) output file
  -f [ --format ] arg (=pretty)
                    output format, possible values: pretty (default), csv
  --suppressConsole 
                    true to suppress console output
  -m [ --mode ] arg mode, possible values: encoded, decoded, public, secret```
```

# おまけ

カタパルトのエクステンションなどを開発してソースコードに追加した際にはステップ３から実行すればOKです。
その際にcmakeのキャッシュファイルが残っている場合は削除しておいたほうが安全です。

# 参考
https://github.com/symbol/symbol/blob/client/catapult/v1.0.3.6/client/catapult/docs/BUILD-manual.md