GNを使ってV8を組み込む

GNを使ってV8を組み込む:

Google V8は、depot_toolsの中のGNというツールを使ってビルドされています。GNはgenerate ninjaの略です。ニンジャナンデ!!!!

ninjaは並列ビルドシステムで、Make代替のものです。

GNはninja向けのファイルを生成するメタビルドシステムで、特徴としては、クロスプラットフォームやカスタマイズなどを行えるという点です。ninjaがMake代替だとすれば、GNはGNU autotools代替と言えるでしょう。

V8をビルドして(静的もしくは動的な)ライブラリを生成して、それをリンクして組み込むだけならGNを意識する必要はありませんが、せっかくのクロスプラットフォームな仕組みなので、そこに乗っかってみるという記事です。


前提

この記事では direnv を前提としてしています。特定ディレクトリ以下でのPATH設定に使っているだけなので、PATH設定さえ別の手段で行うなら、direnv は無くてもかまいません。

Macで動作確認をしています。LinuxやWindowsで行う場合、他に手順が必要なケースがあるかもしれません。


depot_toolsをインストールする

まずはtoybox-v8というディレクトリを作成し、その中にdepot_toolsをインストールします。ディストリビューションなどによってはdepot_toolsはパッケージ化されているようです。

mkdir toybox-v8 
cd toybox-v8 
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 
echo "export PATH=`pwd`/depot_tools:$PATH" > .envrc 
direnv allow . 
最後の二行はパス設定のためのものです。depot_toolsはあまり汎用的とは言いがたいエコシステムなため、筆者はこのようにしています。


必要なファイルを用意する

fetch v8 
もしもGNを使わずに手動でV8をリンクしたいということであれば、あとは、Getting started with embedding V8の手順に従うといいでしょう。

今回はhello_world.ccを使います。まず今回のディレクトリを整備します。

mkdir hello-world 
cd hello-world 
GNでV8を組み込む場合、とても多くの下準備が必要になります。

ln -s ../depot_tools . 
ln -s ../v8 . 
ln -s v8/build . 
ln -s v8/build_overrides . 
ln -s v8/buildtools . 
ln -s v8/testing . 
 
mkdir third_party 
(cd third_party ; ln -s ../v8/third_party/googletest .) 
(cd third_party ; ln -s ../v8/third_party/jinja2 .) 
(cd third_party ; ln -s ../v8/third_party/llvm-build .) 
(cd third_party ; ln -s ../v8/third_party/markupsafe .) 
 
mkdir tools 
(cd tools ; ln -s ../v8/tools/clang .) 
 
cp v8/samples/hello-world.cc . 
ここまでで toybox-v8の中身はこのようになっているはずです。

├── depot_tools 
├── hello-world 
│   ├── build -> v8/build 
│   ├── build_overrides -> v8/build_overrides 
│   ├── buildtools -> v8/buildtools 
│   ├── depot_tools -> ../depot_tools 
│   ├── hello-world.cc 
│   ├── testing -> v8/testing 
│   ├── third_party 
│   │   ├── googletest -> ../v8/third_party/googletest 
│   │   ├── jinja2 -> ../v8/third_party/jinja2 
│   │   ├── llvm-build -> ../v8/third_party/llvm-build 
│   │   └── markupsafe -> ../v8/third_party/markupsafe 
│   ├── tools 
│   │   └── clang -> ../v8/tools/clang 
│   └── v8 -> ../v8 
└── v8 


GNファイルを作成する

GNファイルを2つ用意する必要があります。.gn というファイルと BUILD.gn です。


.gn

このファイルはV8のビルド情報を組み込んでビルド設定(引数)を定義するのが主目的です。

buildconfig = "//build/config/BUILDCONFIG.gn" 
 
check_targets = [] 
 
default_args = { 
  cc_wrapper = "ccache" 
  v8_enable_i18n_support = false 
  clang_use_chrome_plugins = false 
  v8_monolithic = true 
  is_component_build = false 
  v8_use_external_startup_data = false 
  v8_experimental_extra_library_files = [] 
  v8_extra_library_files = [] 
} 
ここではcc_wrapperとして ccache というC/C++コンパイル結果をキャッシュするラッパーを使っています。V8のビルドでは、数百〜千のファイルをコンパイルする必要があるためキャッシュがあれば圧倒的に楽になります。

無い場合や使いたくない場合は、cc_wrapper = "ccache"の行を削りましょう。


BUILD.gn

BUILD.gnはhello-worldをmakeするためのファイルです。

import("//v8/gni/v8.gni") 
 
group("default") { 
  deps = [ 
    ":hello_world", 
  ] 
} 
 
v8_executable("hello_world") { 
  include_dirs =["v8"] 
  sources = [ 
    "hello-world.cc", 
  ] 
 
  configs = [ "v8:external_config" ] 
 
  deps = [ 
    "//v8:v8_monolith", 
  ] 
} 


実際にビルドする

gn gen out 
ninja -C out 
最初のgn gen outで、outというディレクトリの下にninjaコマンドで必要なファイルをすべて生成します。

ninja -C outで、実際にビルドを行います。

成功すれば、out/hello_worldというバイナリが生成されているはずです。

$ ./out/hello_world 
Hello, World! 
3 + 4 = 7 
ちなみに1行目はJavaScriptのコードで、2行目の3+4という計算はWeb Assemblyで行われています。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)