x86_64 ubuntu上でcatapultをarm64用にビルドする(dragon)
Posted
[注意]この記事で書かれている不具合は、これを書いている時点でarm64向けにクロスコンパイルした時に起こるものです。通常の(x64上でx64向けにビルドする)時には起きません。
前回の記事
https://mijinc0.github.io/blog/post/20190602_building_catapult_for_arm/
前回、catapultのarm向けクロスコンパイルを行こないました。最初はversion dragon
でビルドをし、catapult.server
の起動は確認しましたが、、catapult.tools.nemgen
がどうもビルド出来ず、中途半端な状態になったためにバージョンを一旦cow
に下げた記事に変更しました。
その後、version dragon
のarm向けのクロスコンパイルが出来たので、それに関して書きます。
さいしょに
基本的には前回の記事と同じ。ただ、catapult.tools.nemgen
をビルドする時にエラーが出るので、その対処のみを抜き出して書きます。
まずは、前回の記事に沿ってcatapult.tools.nemgen
をビルドすると、どういったエラーが出るのかについて書いておきます。
catapult-server.d/_build$ cmake -DBOOST_ROOT=~/boost-build-1.69.0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=~/toolchain.arm.cmake ..
catapult-server.d/_build$ make catapult.tools.nemgen -j3
Scanning dependencies of target external
Scanning dependencies of target catapult.state
Scanning dependencies of target catapult.utils
[ 0%] Building C object external/CMakeFiles/external.dir/ref10/crypto_verify_32.c.o
[ 0%] Building C object external/CMakeFiles/external.dir/ref10/fe_0.c.o
[ 0%] Building C object external/CMakeFiles/external.dir/ref10/fe_1.c.o
[ 0%] Building C object external/CMakeFiles/external.dir/ref10/fe_add.c.o
[ 0%] Building C object external/CMakeFiles/external.dir/ref10/fe_cmov.c.o
...
[100%] Linking CXX static library ../../lib/libcatapult.tools.a
[100%] Built target catapult.tools
Scanning dependencies of target catapult.tools.nemgen
[100%] Building CXX object tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/BlockGenerator.cpp.o
[100%] Building CXX object tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/BlockSaver.cpp.o
[100%] Building CXX object tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/NemesisConfiguration.cpp.o
In file included from /home/mij/catapult-server.d/_build/inc/catapult/state/RootNamespace.h:22:0,
from /home/mij/catapult-server.d/tools/nemgen/NemesisConfiguration.h:24,
from /home/mij/catapult-server.d/tools/nemgen/BlockSaver.cpp:22:
/home/mij/catapult-server.d/_build/inc/catapult/state/Namespace.h:32:36: error: 'NamespaceId' was not declared in this scope
using Path = utils::CheckedArray<NamespaceId, Namespace_Max_Depth>;
^~~~~~~~~~~
/home/mij/catapult-server.d/_build/inc/catapult/state/Namespace.h:32:36: note: suggested alternative: 'Namespace'
using Path = utils::CheckedArray<NamespaceId, Namespace_Max_Depth>;
^~~~~~~~~~~
Namespace
/home/mij/catapult-server.d/_build/inc/catapult/state/Namespace.h:32:49: error: 'Namespace_Max_Depth' was not declared in this scope
using Path = utils::CheckedArray<NamespaceId, Namespace_Max_Depth>;
^~~~~~~~~~~~~~~~~~~
/home/mij/catapult-server.d/_build/inc/catapult/state/Namespace.h:32:68: error: template argument 1 is invalid
using Path = utils::CheckedArray<NamespaceId, Namespace_Max_Depth>;
^
/home/mij/catapult-server.d/_build/inc/catapult/state/Namespace.h:32:68: error: template argument 2 is invalid
/home/mij/catapult-server.d/_build/inc/catapult/state/Namespace.h:36:28: error: 'Path' does not name a type
(省略 : 果てしなく続くエラー文)
/home/mij/catapult-server.d/tools/nemgen/BlockGenerator.cpp:209:53: error: 'nonce' was not declared in this scope
auto mosaicId = transactions.addMosaicDefinition(nonce, mosaicEntry.definition().properties());
^~~~~
/home/mij/catapult-server.d/tools/nemgen/BlockGenerator.cpp:209:53: note: suggested alternative: 'nice'
auto mosaicId = transactions.addMosaicDefinition(nonce, mosaicEntry.definition().properties());
^~~~~
nice
/home/mij/catapult-server.d/tools/nemgen/NemesisConfiguration.cpp: At global scope:
/home/mij/catapult-server.d/tools/nemgen/NemesisConfiguration.cpp:81:8: error: 'auto catapult::tools::nemgen::{anonymous}::CreateMosaicEntry(const catapult::utils::ConfigurationBag&, const Key&, const string&, int)' defined but not used [-Werror=unused-function]
auto CreateMosaicEntry(
^~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/build.make:110: recipe for target 'tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/NemesisConfiguration.cpp.o' failed
make[3]: *** [tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/NemesisConfiguration.cpp.o] Error 1
/home/mij/catapult-server.d/tools/nemgen/BlockGenerator.cpp: At global scope:
/home/mij/catapult-server.d/tools/nemgen/BlockGenerator.cpp:54:15: error: 'std::__cxx11::string catapult::tools::nemgen::{anonymous}::GetChildName(const string&)' defined but not used [-Werror=unused-function]
std::string GetChildName(const std::string& namespaceName) {
^~~~~~~~~~~~
cc1plus: all warnings being treated as errors
tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/build.make:62: recipe for target 'tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/BlockGenerator.cpp.o' failed
make[3]: *** [tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/BlockGenerator.cpp.o] Error 1
CMakeFiles/Makefile2:14165: recipe for target 'tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/all' failed
make[2]: *** [tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/all] Error 2
CMakeFiles/Makefile2:14177: recipe for target 'tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/rule' failed
make[1]: *** [tools/nemgen/CMakeFiles/catapult.tools.nemgen.dir/rule] Error 2
Makefile:2417: recipe for target 'catapult.tools.nemgen' failed
make: *** [catapult.tools.nemgen] Error 2
最下部付近を読んでいくと、どうやらBlockGenerator.cpp.o
の生成に失敗している様子。
そして、例えば最上部付近を読んでみると、'NamespaceId' was not declared in this scope
とエラー文にあるとおり、定義されているはずの宣言を見つけることが出来ていない。つまり、インクルード廻りのエラーだと考えられます。
そして、結論から言うと、これに対処することで、ビルドが通るようになります。
環境
catapult
Dragon
コンパイルするOS
x86_64 GNU/Linux NAME=“Ubuntu” VERSION=“18.04.2 LTS (Bionic Beaver)”
対処
理由は後回しにして、“何をすべきか"を書きます。
対処自体は簡単で、catapult-server.d/tools/CMakeLists.txt
の上部、include_directories(. ${CMAKE_BINARY_DIR}/inc)
にBEFORE
オプションを追加します。
# catapult-server.d/tools/CMakeLists.txt
cmake_minimum_required(VERSION 3.2)
# BEFOREを追加
include_directories(BEFORE . ${CMAKE_BINARY_DIR}/inc)
add_subdirectory(address)
add_subdirectory(benchmark)
add_subdirectory(health)
add_subdirectory(nemgen)
add_subdirectory(network)
add_subdirectory(statusgen)
add_subdirectory(tools)
これでビルドすれば通ります。
何をしているのか
BEFORE
を追記することで、その場所でインクルードされるディレクトリの優先順位を上げています。
何故そんなことをする必要があるのか
先に、少しビルド時の挙動について触れておきます。
https://github.com/nemtech/catapult-server/blob/master/BUILDING.md
上記のCATAPULT
の部分を見ると、ninja -j4
を実行する前にninja publish
を実行しています。この操作は、pythonスクリプトを動かしているのですが、この操作によって、_build
ディレクトリ内にinc
ディレクトリが生成されます。
このinc
ディレクトリには、ビルドに必要なヘッダファイルが収められています。
そして、対処
のパートでBEFORE
を追記した部分を読むと、include_directories(. ${CMAKE_BINARY_DIR}/inc)
とあるとおり、ninja publish
によって生成したinc
ディレクトリを参照するように指示していることがわかります。
$ ninja publish
$ ninja -j4
何故src
内のヘッダファイルを直接参照しないのかと言うと、恐らくplugins
やextensions
などはsrc
内のヘッダファイルをインクルードするが、それらが収まるディレクトリツリーの外に完全に出てしまっているので、直接ディレクトリをインクルードすると煩雑になる。そのため、一旦inc
ディレクトリを生成してその中にsrc
やplubins
等で使うヘッダファイルを集約して、そこを参照するようにしているのだと考えられます。
とにかく、ビルドするときにはinc
ディレクトリ内のヘッダファイルをインクルードしたいのです。
そして今回、それが失敗しています。詳しい話は書くと長くなるので書きませんが、本来インクルードすべきではない別の場所を参照してしまっています。(下記図参照)
下記、Makefileにwarning
を追記してインクルードされているディレクトリを出力させてみた結果。
x86_64
/usr/bin/x86_64-linux-gnu-g++-7 $(CXX_DEFINES)
$(CXX_INCLUDES) -isystem boost-build-1.69.0/include
-Icatapult-server/tools/.
-Iatapult-server/_build/inc
$(CXX_FLAGS)
-o CMakeFiles/catapult.tools.nemgen.dir/BlockGenerator.cpp.o
-c catapult-server/tools/nemgen/BlockGenerator.cpp
x86_64
で普通にビルドしたときは、BlockGenerator.cpp.o
をコンパイルするときにはboost-build-1.69.0/include
、catapult-server/tools/.
、catapult-server/_build/inc
がインクルードディレクトリとして指定されている。
arm64
/usr/bin/aarch64-linux-gnu-g++-7 $(CXX_DEFINES)
$(CXX_INCLUDES) -isystem /home/mij/boost-build-1.69.0/include
-Icatapult-server
-Icatapult-server/src
-Icatapult-server/plugins/txes/mosaic/src
-Icatapult-server/tools/.
-Icatapult-server/_build/inc
$(CXX_FLAGS)
-o CMakeFiles/catapult.tools.nemgen.dir/BlockGenerator.cpp.o
-c catapult-server.d/tools/nemgen/BlockGenerator.cpp
arm64
向けにクロスコンパイルしたときは、catapult-server
とcatapult-server/src
とcatapult-server/plugins/txes/mosaic/src
がcatapult-server/_build/inc
よりも優先される位置でインクルードの指定を受けている。この為に本意でない場所のファイルをインクルードしてしまっていた。
なぜそれらがarm64
向けにビルドするときのみ残ってしまうのかが分からないが、理由が分かればもう少し良い修正方法がありそう。