Apache Arrow の Issue を watch していたら、Gandiva が Windows 環境でも動くようになっていたので、開発環境を構築しました。
C++ Development Setup
Gandiva は C++ で開発されているので、まず C++ の開発環境が必要になります。Windows の C++ の開発環境の構築に関しては、以下に記載されています。
今回は Visual Studio 2017 の Community をインストールしました。
Compile
Apache Arrow は 様々な言語に対応していますが、それらを1つの git リポジトリで管理しています。
$ git clone https://github.com/apache/arrow.git
Developing on Windows に記載されている内容に沿って、ビルドできる状態にします。
$ activate arrow-dev
$ set ARROW_BUILD_TOOLCHAIN=%CONDA_PREFIX%\Library
$ "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" -arch=amd64
ビルドは以下のとおりです。
$ cd arrow\cpp
$ mkdir build
$ cd build
$ cmake -G "NMake Makefiles" -DARROW_GANDIVA=ON -DARROW_GANDIVA_JAVA=ON -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build . --config Release
Errors
error: expected function body after function declarator
D:/development/repository/git/arrow/cpp/src/gandiva/precompiled/../../arrow/vendored/datetime/date.h:229:81: error: expected function body after function declarator
CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT;
^
D:/development/repository/git/arrow/cpp/src/gandiva/precompiled/../../arrow/vendored/datetime/date.h:101:22: note: expanded from macro 'NOEXCEPT'
# define NOEXCEPT _NOEXCEPT
関数の最後に付いている NOEXCEPT
を認識することができず、コンパイルエラー。これは以下の変更をすることで回避しています。
(arrow-dev) D:\development\repository\git\arrow\cpp\build>git diff
diff --git a/cpp/src/gandiva/precompiled/CMakeLists.txt b/cpp/src/gandiva/precompiled/CMakeLists.txt
index 6d3daf2..c98c020 100644
--- a/cpp/src/gandiva/precompiled/CMakeLists.txt
+++ b/cpp/src/gandiva/precompiled/CMakeLists.txt
@@ -35,7 +35,7 @@ if(MSVC)
# Visual Studio 2015, and the standard library uses C++14 features,
# so we have to use that -std version to get the IR compilation to
# work
- set(PLATFORM_CLANG_OPTIONS -std=c++14 -fms-compatibility -fms-compatibility-version=19)
+ set(PLATFORM_CLANG_OPTIONS -std=c++14 -fms-compatibility -fms-compatibility-version=19.10)
else()
set(PLATFORM_CLANG_OPTIONS -std=c++11)
endif()
以下のページを見ると noexcept
は MSVC 19.0 (VS2015) でサポートされていることになっているので、変更前の設定で合っています。Clang のバージョンに依るのかな。
https://ja.cppreference.com/w/cpp/compiler_support
Clang のバージョンは以下のとおり。
(arrow-dev) C:\development\cmder\cmder_mini_1.3.4>clang --version
clang version 7.0.0 (tags/RELEASE_700/final)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\development\python\Miniconda3\envs\arrow-dev\Library\bin
error LNK2001
ライブラリ ..\..\..\release\gandiva_jni.lib とオブジェクト ..\..\..\release\gandiva_jni.exp を作成中
expression_registry_helper.cc.obj : error LNK2001: 外部シンボル ""class google::protobuf::internal::ExplicitlyConstructed<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char
> > > google::protobuf::internal::fixed_address_empty_string" (?fixed_address_empty_string@internal@protobuf@google@@3V?$ExplicitlyConstructed@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@123@A)" は未解決です。
Types.pb.cc.obj : error LNK2001: 外部シンボル ""class google::protobuf::internal::ExplicitlyConstructed<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > google::prot
obuf::internal::fixed_address_empty_string" (?fixed_address_empty_string@internal@protobuf@google@@3V?$ExplicitlyConstructed@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@123@A)" は未解決で
す。
jni_common.cc.obj : error LNK2001: 外部シンボル ""private: static int google::protobuf::io::CodedInputStream::default_recursion_limit_" (?default_recursion_limit_@CodedInputStream@io@protobuf@google@@0HA)"
は未解決です。
..\..\..\release\gandiva_jni.dll : fatal error LNK1120: 2 件の未解決の外部参照
libprotobuf の関数をリンクするあたりでエラーがでます。
以下のコマンドで libprotobuf.lib
に含まれている関数を確認すると、エラーになっている関数のシグネチャが出力されるので問題ないように見えるのですが…。
link /dump /exports C:\development\python\Miniconda3\envs\arrow-dev\Library\lib\libprotobuf.lib
?fixed_address_empty_string@internal@protobuf@google@@3V?$ExplicitlyConstructed@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@123@A (class google::protobuf::internal::ExplicitlyConstructed<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > google::protobuf::internal::fixed_address_empty_string)
もうちょっと調べてみると、問題はヘッダ側でした。
- include/google/protobuf/message_lite.h
// Default empty string object. Don't use this directly. Instead, call
// GetEmptyString() to get the reference.
PROTOBUF_EXPORT extern ExplicitlyConstructed<::std::string>
fixed_address_empty_string;
- include/google/protobuf/port_def.inc
#if defined(_MSC_VER) && defined(PROTOBUF_USE_DLLS)
#ifdef LIBPROTOBUF_EXPORTS
#define PROTOBUF_EXPORT __declspec(dllexport)
#else
#define PROTOBUF_EXPORT __declspec(dllimport)
#endif
#ifdef LIBPROTOC_EXPORTS
#define PROTOC_EXPORT __declspec(dllexport)
#else
#define PROTOC_EXPORT __declspec(dllimport)
#endif
#else
#define PROTOBUF_EXPORT
#define PROTOC_EXPORT
#endif
以上より、以下の設定を加えています。
diff --git a/cpp/src/gandiva/jni/CMakeLists.txt b/cpp/src/gandiva/jni/CMakeLists.txt
index 680b6e5..33a7e96 100644
--- a/cpp/src/gandiva/jni/CMakeLists.txt
+++ b/cpp/src/gandiva/jni/CMakeLists.txt
@@ -19,6 +19,8 @@ if(CMAKE_VERSION VERSION_LESS 3.11)
message(FATAL_ERROR "Building the Gandiva JNI bindings requires CMake version >= 3.11")
endif()
+add_definitions(-DPROTOBUF_USE_DLLS)
+
# Find JNI
find_package(JNI REQUIRED)
Java
現時点での Java の parent の pom.xml では Gandiva がビルド対象になっていないので、Java の parent で Gandiva もビルドする場合には、以下のように pom.xml に追加する必要があります。
diff --git a/java/pom.xml b/java/pom.xml
index 9e4afcf..cdb8885 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -652,6 +652,7 @@
<module>adapter/jdbc</module>
<module>plasma</module>
<module>flight</module>
+ <module>gandiva</module>
</modules>
<profiles>
Gandiva の test を実行する際に、C++ のビルドで生成した gandiva_jni.dll
が必要になります。以下のコマンドで実行します。
mvn install -Dcheckstyle.skip -Dflatc.download.skip=true -Dgandiva.cpp.build.dir=<path to gandiva_jni.dll dir>
また、以下の Erros
で記載していますが、Windows で Arrow の Java モジュールをビルドする際に必要な flatc.exe
はMaven から取得することができないので、自分でダウンロードして配置し、-Dflatc.download.skip=true
をつけてビルドする必要があります。
Errors
Could not find artifact com.github.icexelloss:flatc-windows-x86_64:exe:1.9.0 in central (https://repo.maven.apache.org/maven2)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 47.503 s
[INFO] Finished at: 2019-04-06T21:54:03+09:00
[INFO] Final Memory: 72M/464M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-dependency-plugin:3.0.1:copy (copy-flatc) on project arrow-format: Unable to find/resolve artifact.: Could not find artifact com.github.icexelloss:flatc-windows-x86_64:exe:1.9.0 in central (https://repo.maven.apache.org/maven2) -> [Help 1]
これは com.github.icexelloss:flatc-windows-x86_64:exe:1.9.0
が Maven Central Repository に無いことに起因しています。以下に対応方法が記載されています。
Conclusion
以上の手順で Windows / Java の環境で Gandiva を動かすことができました。Arrow は Windows ビルドも積極的にサポートしているので、興味がある人はぜひトライしてください。今回の変更内容は、適用する条件を整理して PR を投げるつもりです。