BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース なぜGerritはBuckを選んだのか

なぜGerritはBuckを選んだのか

原文(投稿日:2013/10/31)へのリンク

今日EclipseConでShawn Pearce氏(Gerritプロジェクトのメンテナ)が,Improve your Java Builds with Buckと題する講演を行った (スライド, 追加スライド)。これらの資料は,GerritプロジェクトがMavenからBuckへとスイッチした結果,Gerrit 2.8以降のビルドでは最終的にBuckのみを使用するようになった,その理由を説明したものだ。

Buckは,Google社内で使用されているビルドシステムの 'blaze' を基本モデルとしたビルドシステムで,現在はFacebookに所属する元Google社員の手で開発された。Facebookでありながら,このビルドシステムはApacheライセンスのオープンソースとしてGitHubで公開されている。BuckはPythonベースだが,GerritではおもにJavaのコンパイルに使用している。

Buckの言語はDSLの一種で,基礎となるビルドファイルにはPythonを使用する。下記に示すのは,ファイルシステム上の別の場所に配置されたGuavaを参照する 'printy_lib' というJavaライブラリの定義である:

 java_library(   name = 'printy_lib',   srcs = glob(['src/main/java/**/*.java']),   deps = [':guava'], )  prebuilt_jar(   name = 'guava',   binary_jar = 'guava.jar', ) 

Gerritプロジェクトでは,JAR参照をMaven Centralで解決してローカルシステムに取得する機能を追加した。取得するJARファイルの内容は,GAVによる識別とSHA1のチェックサムを使ってダウンロード時に検証される。 これらの拡張機能は現在のBuckでは使用できないが,将来的には寄贈される可能性もある。

 include_defs('//lib/maven.defs')  maven_jar(   name = 'guava',   id = 'com.google.guava:guava:14.0',   sha1 = '67b7be4ee7ba48e4828a42d6d5069761186d4a53',   license = 'Apache2.0', ) 

Mavenに対してBuckが持つ明確なメリットは,その処理速度だ。それを実現する重要なアドバンテージがいくつかある。モジュールをまたいだビルドの並列実行はそのひとつだ。Buckのビルドでは,デフォルト値としてCPU数×1.25のスレッドを使用している(MavenやMakeも並列ビルドは可能だが,モジュール単位での並列性に制限される)。Gerritの速度改善として示されているのは次の値だ:

  • クリーンビルド
    mvn package -Dmaven.{javadoc,test}.skip=true  ... 6分50秒
    buck build :gerrit                            ... 2分 3秒
    buck test --all                               ... 2分 5秒
    
  • No-op インクリメンタル・リビルド
    mvn package -Dmaven.{javadoc,test}.skip=true  ... 4分44秒
    buck build :gerrit                            ...     2秒
    
  • buckdがバックグラウンドで実行されている場合はさらに高速に動作する
    ~/buck/bin/buckd
    time buck :gerrit                             ...    0.5秒
    

デフォルトでマルチスレッドがサポートされている以外にも,Buckはインクリメンタルビルドやコンパイル対象を変更されたクラスに限定するなどの方法で,コンパイル速度を向上している。更新されたソースファイルの検出には,ファイルシステムのタイムスタンプ(すべてのシステムで信頼性があるとは限らない)ではなく,最終コンパイル時をベースとしたSHAによる内容比較を用いている。ビルドファイルのハッシュ値も取得しているので,ビルド定義が変更された場合にはすべてのファイルが再コンパイルされる。

BuckにはJavaの依存関係に関する詳細な情報も組み込まれている。相互依存関係にあるクラスのビルド方法や,内部メソッドではなく公開されたAPIの変更時にのみ依存関係によるコンパイルを実施する処理などを実現する。

ローカルシステム上でビルド用のコンテントを共有するのと同様に,BuckをApache Cassandaストレージシステムに接続することで,複数の開発者によるライブラリ共有を許可することも可能だ。これは構築済,あるいは旧バージョン用のコンポーネントをダウンロード可能なリポジトリ機構として動作する。必要なコンポーネントが何かを解決する処理は,Buckビルドシステムが実行する。これによって問題の切り分けが簡単にできるようになると同時に,毎回ビルド処理を行うことなく,過去のビルドからの資産を解析することが可能になる。コンテンツはハッシュされているので,アップデートされていないバージョンや公開されていないバージョンも利用可能だ。

処理速度の向上は,より柔軟な開発作業を可能にする。ビルドが1秒以内に実行可能なため(Gerritデーモン実行時),Gerritの開発ビルドでは開発モードで実行されていることを検出して,HTTP要求ごとにリビルドとリロードを起動するようなことが可能になる。これによって非常に短いターンアラウンドでのパッチ提供が可能になり,開発時にリビルドやデプロイのために数秒あるいは数分を待つ必要がなくなる。

Buckは開発中であるため,Gradleが提供しているコミュニティや資料に比べれば不足する部分もある。最後に,BuckはJavaで記述されているが,DSLとしてはPythonを使用する。また,テストはおもにMacとLinuxマシンで実施されている。これはつまり,現時点ではWindowsサポートの優先順位が低いことを意味する。

Buckに関する詳細な情報は,FaceBookのBuckを紹介したページを参照してほしい。

この記事に星をつける

おすすめ度
スタイル

BT