https://chromium.googlesource.com/chromium/src/tools/gn/+/48062805e19b4697c5fbd926dc649c78b6aaa138/README.md

https://chromium.googlesource.com/chromium/src/+/lkgr/tools/gn/docs/quick_start.md#Dont-know-whats-going-on

GYP?と同水準にあるメタビルドツール、GYPよりもシンプル。今ではGYPに代わりGNを使いつつあるようだ。

BUILD.gnを読み込んでビルドする。

なんでGNを使うか

  1. GYPよりも読みやすい
  2. 早い
  • GYPより20倍速い。
  • Ninjaからの要求により起動できる。GNを起動しなければなならない状態であったことを覚えておく必要がない。
  1. 依存性の強制ができる。
  2. ビルドグラフ(依存関係の図)を検索できる。

現状は?

2015/8現在 (途中)

ビルドの実行

GYPではDebugとReleaseの両方がつくられるが、GNはしない。自分で設定する、ビルドディレクトリも設定する。

ビルドのセットアップ

ビルドディレクトリの設定 gn gen out/my_build

ビルド引数の設定

 
gn args out/by_build

これはエディタを起動する。以下のように記述する

 
is_component_build = true
is_debug = false

利用可能な引数と、デフォルト値を見るには以下

 
gn args --list out/my_build

クロスコンパイルの引数は例は以下

 
target_os = "chromeos"
target_os = "android"

target_cpu = "arm"
target_cpu = "x86"
target_cpu = "x64"

(途中)

descコマンド

状態の表示

 
gn desc out/my_build

パフォーマンス

以下のコマンドでトレースログを作成。これはChromiumのabout:tracingで読み込める。

 
gn --tracelog=mylog.trace

練習

実際にターゲットを追加して、Chromiumのソースに変更を加えてみる。 tools/gn/tutorial/BUILD.gnを作成して以下を入力。

 
executable("hello_world") {
  sources = [
    "hello_world.cc",
  ]
}

hello_world.ccも作成しなきゃならないが、すでにあるはずなので省略。このBUILD.gnは実行ファイルのターゲットhello_worldを定義している。これをchromiumのプロジェクトに含めるためにルート(toolsの一つ上のsrcディレクトリ)のBUILD.gnに以下を追加。

 
group("root") {
  deps = [
    "//url",
    "//tools/gn/tutorial:hello_world",
  ]
}

rootグループに属しているターゲットは//urlプロジェクトとhello_worldターゲットに依存する。//はソースのルートを表す。これでビルドしてみる。

 
gn gen out\hello
ninja -C out\hello hello_world

src\out\hello\obj\tools\gn\tutorialに.ninjaファイルが作成され、src\out\hello\hello_world.exeも作成された。

依存性を宣言する

練習の続き。静的ライブラリhelloを作成する。tools/gn/tutorial/BUILD.gnに以下を追加。

 
static_library("hello") {
  sources = [
    "hello.cc",
  ]
}

executableの方を以下のように修正。

 
executable("hello_world") {
  sources = [
    "hello_world.cc",
  ]
   deps = [
    ":hello",
  ]
}

hello_worldはhelloに依存するようになった。ここでは実際には依存していないがスルー。 ビルド

 
ninja -C out\hello hello_world

必要ならninjaは自動でgnを実行してくれる。

helloライブラリに機能を追加

同時に二人に挨拶できる機能を追加する。TWO_PEOPLEフラグでこの機能をコントロールする。BUILD.gnのhelloを以下のように修正。

 
static_library("hello") {
  sources = [
    "hello.cc",
  ]
  defines = [
    "TWO_PEOPLE",
  ]
}

これでgnしてみると、hello.ninjaにdefines = -DTWO_PEOPLEが追加される。しかしhello.hをインクルードしてる他のユーザはこのことを知らないので教える必要がある。その仕組みがconfigと呼ばれる。configはconfigとして独立していて、どこかに依存しているわけではない。hello_configという名前のconfigを作成するには以下のように記述する。

 
config("hello_config") {
  defines = [
    "TWO_PEOPLE",
  ]
}

これをターゲットに含めるには以下のように記述する。

 
static_library("hello") {
  ...
  configs += [
    ":hello_config",
  ]
}

これをやるとdefinesの時と同様に-DTWO_PEOPLEが追加される。

Dependant configs

これで設定をカプセル化したが、使う側はこのコンフィグを設定しないとならない。自動でこのコンフィグを使うには以下のように記述する。

 
static_library("hello") {
  sources = [
    "hello.cc",
  ]
  all_dependent_configs = [
    ":hello_config"
  ]
}

これでninjaすると、hello_world.ninjaにも-DTWO_PEOPLEが追加される。

print()とdesc

print()をBUILD.gnに書ける。

 
static_library("hello") {
  ...
  print(configs)
}

gn descで出力できる。

 
gn desc out\debug //tools/gn/tutorial:hello_world
gn desc  out\debug //tools/gn/tutorial:hello

面白いこともできる。誰がTWO_HELLOを設定したのかを知りたければ以下のようにする。

 
gn desc out\hello //tools/gn/tutorial:hello_world defines --blame

これはターゲットのフルパスを指定する必要があるようだ。hello_worldのdefineが誰によって指定されたのかを見ることができる。

以下も面白い。

 
gn desc out\hello //tools/gn/tutorial:hello_world deps

hello_worldが依存しているターゲットを表示。

ターゲットの一覧

 
gn ls out\hello

Hack

GN自体をビルド

gn自体がchromiumツリーの一部。ビルドできる。

 
ninja -C out\hello gn

GNのユニットテストを実行

 
ninja -C out\hello gn_unittests
out\hello\gn_unittests.exe

実用コマンド

あるソースファイルがどのターゲットに含まれているかを探す

gn refs out\Default //base/task_scheduler/scheduler_worker_pool_impl.cc
//base:base

実行ファイルを生成するターゲットを探す

gn ls out\Default --type=executable
//base:base_i18n_perftests
//base:base_perftests
//base:base_unittests
//base:build_utf8_validator_tables
//base:check_example
//breakpad:dump_syms
//cc:cc_perftests
//cc:cc_unittests
//cc/blink:cc_blink_unittests
//chrome:chrome_initial
//chrome/chrome_watcher:system_load_estimator_unittests
//chrome/install_static:install_static_unittests
//chrome/installer/gcapi:gcapi_test
//chrome/installer/mini_installer:mini_installer
...

小さそうな実行形式ターゲットをVisual Studio 2015で開く

ターゲット//mash/example/views_examples:views_examplesで実験。 ソリューションファイルを作成。

gn gen --ide=vs --sln=mashviewsexample --filters=//mash/example/* out\Default
Generating Visual Studio projects took 17298ms
Done. Made 6202 targets from 1344 files in 26003ms

ビルド

ninja -C out\Default mash/example/views_examples:views_examples

作成されたソリューションをVisual Studio 2015で開く。

devenv out\Default\mashviewsexample.sln

devenvプロセスはdepot_toolsにパスが通っていないとならない。これでも500近いプロジェクトを含んでいるので、VSの拡張機能filterを使って読み込むプロジェクトを絞れば速くなる。

GNのビルドフラグを理解する

https://www.chromium.org/developers/gn-build-configuration

ビルドフラグを編集する

gn args out\Default

エディタが起動し現在の設定を確認できる。エディタを閉じると.ninjaを作成しなおす。

設定可能なビルドフラグの一覧

gn args out\Default --list

現在のビルドフラグの設定値(デフォルト含め)の確認

gn args out\Default --list=is_component_build
is_component_build
Current value (from the default) = true
From //build/config/BUILDCONFIG.gn:169


共通のビルドフラグ

is_debug = false

デフォルトはデバッグビルド、falseだとリリース。

is_component_build

コンポーネントビルド? sharedライブラリかどうかtrueならsharedライブラリ

symbol_level

デバッグ時のシンボル作成の深さ。

remove_webcore_debug_symbols

WebCoreは多くのテンプレートを使っており、デバッグシンボルが多くなる。WebCoreのデバッグを考えてないならスキップすべき。 警告:Windowsでは、pdbが見つからないため他のリビルドが動いて逆に遅くなる。

target_cpu

ターゲットCPU

Page last modified on June 16, 2019, at 04:21 PM
Powered by PmWiki