密閉型

このページでは、密閉性、密閉型ビルドを使用するメリット、ビルドで非密閉型動作を特定するための戦略について説明します。

概要

入力ソースコードとプロダクト構成が同じ場合、密閉型ビルドシステムは、ビルドをホストシステムに対する変更から分離することで、常に同じ出力を返します。

ビルドを分離するために、密閉型ビルドは、ローカルまたはリモートのホストマシンにインストールされているライブラリやその他のソフトウェアの影響を受けません。コンパイラなどのビルドツールの特定のバージョンや、ライブラリなどの依存関係によって異なります。これにより、ビルドプロセスは、ビルド環境の外部のサービスに依存しないため、自己完結型になります。

密閉性には以下の 2 つの重要な側面があります。

  • 分離: 密閉型のビルドシステムは、ツールをソースコードとして扱います。ツールのコピーをダウンロードしてストレージを管理し、マネージド ファイルツリー内で使用します。これにより、言語のインストール版を含め、ホストマシンとローカル ユーザーが分離されます。
  • ソース ID: 密閉型のビルドシステムは、入力の同一性を確保しようとします。Git などのコード リポジトリは、一意のハッシュコードを使用してコード ミューテーションのセットを識別します。密閉型のビルドシステムは、このハッシュを使用してビルドの入力に対する変更を識別します。

利点

密閉型ビルドの主なメリットは次のとおりです。

  • 速度: アクションの出力はキャッシュに保存できます。入力が変更されない限り、アクションを再度実行する必要はありません。
  • 並列実行: ビルドシステムは、所定の入力と出力に対してすべてのアクションのグラフを作成し、効率的で並列実行を計算することができます。ビルドシステムがルールを読み込み、アクション グラフとハッシュ入力を計算してキャッシュ内で検索します。
  • 複数のビルド: 同じマシン上に複数の密閉型ビルドをビルドできます。ビルドごとに異なるツールとバージョンを使用できます。
  • 再現性: 密閉型のビルドは、ビルドを生成した正確な条件を理解しているため、トラブルシューティングに役立ちます。

非密閉性の識別

Bazel に切り替える準備をしている場合は、既存のビルドの密閉性を事前に改善しておくと、移行が容易になります。ビルドにおける非密閉性の一般的な原因は次のとおりです。

  • .mk ファイル内の任意の処理
  • 通常はビルド ID またはタイムスタンプを含む、非確定的にファイルを作成するアクションやツール
  • ホストごとに異なるシステム バイナリ(/usr/bin バイナリ、絶対パス、ネイティブ C++ ルールの自動構成用のシステム C++ コンパイラなど)
  • ビルド中にソースツリーに書き込む。これにより、同じソースツリーが別のターゲットに使用されるのを防ぐことができます。最初のビルドはソースツリーに書き込み、ターゲット A のソースツリーを修正します。その後、ターゲット B をビルドしようとすると、失敗する可能性があります。

非密閉型ビルドのトラブルシューティング

ローカル実行から始めて、ローカル キャッシュのヒットに影響する問題により、非密閉型アクションが明らかになります。

  • null 順次ビルドを確保する: make を実行してビルドが成功した場合、ビルドを再度実行してもターゲットは再ビルドされません。各ビルドステップを 2 回または異なるシステムで実行した場合、ファイル コンテンツのハッシュを比較して異なる結果が得られた場合、ビルドは再現されません。
  • 可能性のあるさまざまなクライアント マシンからローカル キャッシュ ヒットをデバッグする手順を実行し、クライアント環境がアクションに流出していないかを確認します。
  • チェックアウトされたソースツリーとホストツールの明示的なリスト以外は何も含まれていない Docker コンテナ内でビルドを実行します。ビルドの破損やエラー メッセージにより、暗黙的なシステム依存関係が検出されます。
  • リモート実行ルールを使用して、密閉性の問題を検出して修正する。
  • ビルド内のアクションはステートフルで、ビルドまたは出力に影響することがあるため、アクションごとのレベルで厳格なサンドボックス化を有効にします。
  • ワークスペース ルールを使用すると、デベロッパーは外部ワークスペースに依存関係を追加できますが、プロセス内で任意の処理を行うことができるほど豊富なルールがあります。--experimental_workspace_rules_log_file=PATH フラグを Bazel コマンドに追加すると、Bazel ワークスペース ルールで密閉型でない可能性のあるアクションのログを取得できます。

Bazel による密閉性

他のプロジェクトで Bazel で密閉型ビルドを使用して成功した方法については、以下の BazelCon の講演をご覧ください。