コンテンツにスキップ

「ビルド (ソフトウェア)」の版間の差分

出典: フリー百科事典『ウィキペディア(Wikipedia)』
削除された内容 追加された内容
江口磐世☆ (会話 | 投稿記録)
m lang
 
(21人の利用者による、間の25版が非表示)
1行目: 1行目:
[[ソフトウェア]]の'''ビルド'''({{lang-en-short|build}})は、[[ソースコード]]ファイルを独立したソフトウェア生成物に変換するコンピュータ上で実行されるプロセス、またはその結果を指す。ビルドにおいても重要なのは[[コンパラ|コンパイル]]プロセスであり、[[ソースコード]]ファイルを[[実行ファイル]]に変換する。
[[ソフトウェア]]の'''ビルド'''({{lang-en-short|build}})は、[[プログラミング言語]]で書かれた[[ソースコード]]ファイルや各種[[リソースファイル]]{{要曖昧さ回避|date=2023年3月}}を独立したソフトウェア生成物に変換する[[コンピュータ]]上で実行されるプロセス、またはその結果を指す。ビルド終生成物は[[ナリ形式]]の[[実行ファイル]]であったり、再利用可能な[[ライブラリ]]であったり、[[バイトコード]]あるいはそれらをまとめた[[アーカイブ (コンピュータ)|アーカイブ]]であったりすることもある<ref>例えば[[Java]]では[[JAR (ファイルフォーマット)|JAR]][[Android (オペレーティングシステム)|Android]]では[[APK (ファイル形式)|APK]]をアーカイブ形式としてい。</ref>


== 概要 ==
単純なプログラムでは、単一のファイルを[[コンパイラ|コンパイル]]するだけで済むが、複雑なソフトウェアではソースコードは多数のファイルで構成されており、異なった組み合わせ方をすることで異なったバージョンを生成できる。
ビルドにはいくつかのステップがあり、その内容は[[プログラミング言語]]やビルドツール、開発環境や実行環境(ターゲットアーキテクチャ、[[オペレーティングシステム]]あるいは[[仮想マシン]])によっても異なる。例えば[[C言語]]あるいは[[C++]]の場合、[[ソースファイル]](ソースコード)を[[コンパイラ]]によって[[オブジェクトファイル]](オブジェクトコード)に翻訳(コンパイル)した後、[[リンケージエディタ|リンカ]]によってオブジェクトコードを結合し、[[実行ファイル]]を生成する。プログラムから実行時に参照される各種アイコン画像やローカライズされた文字列などを実行ファイル内に「リソース」として含めることもあり、ビルドプロセスでリソースのコンパイルとリンクを実行する。


単純なプログラムでは、単一のソースファイルをコンパイルするだけで済むが、複雑なソフトウェアでは通例メンテナンス性向上の観点からソースコードはモジュールごとに分類・分割された多数のファイルによって構成されており、各ファイルを個別にコンパイル(分割コンパイル)した後で、リンク時に実体の依存関係を解決する。C/C++のような原始的なプログラミング言語では、[[ヘッダファイル]]を利用して、ユーザー定義型や定数、および関数などの定義または宣言を共有することが多い。ヘッダーファイルのインクルードにより、ファイル間の依存関係が発生する。
[[プログラム (コンピュータ)|コンピュータプログラム]]のビルドは、一般に'''ビルドツール'''と呼ばれるプログラムを使い、他のプログラムを制御・統合して行う。ビルドツールの例としては、[[make]]、[[Apache Ant|ant]]、[[Apache Maven|maven]]、[[SCons]]などがある。ビルドユーティリティは、各種ファイル群を正しい順序で[[コンパイラ|コンパイル]]し[[リンケージエディタ|リンク]]する必要がある。また、開発時には何度もビルドを繰り返すが、前回のビルドから何も変更されていないファイルは[[コンパイラ|コンパイル]]する必要がない(ただし、[[ヘッダファイル]]などの依存関係も考慮する必要がある)。洗練されたビルドユーティリティは無駄な再コンパイルをしないようにして、ビルドに要する時間を短縮している。[[Subversion]]などの[[バージョン管理システム]]はビルドユーティリティの機能を内蔵している。さらに複雑なプロセスになると、ビルド中に他のプログラムを使ってコードやデータを生成することもある。

[[プログラム (コンピュータ)|コンピュータプログラム]]のビルドは、一般に'''ビルドツール'''と呼ばれるプログラムを使い、他のプログラムを制御・統合して行う。ビルドツールの例としては、[[make (UNIX)|make]]、[[Apache Ant|ant]]、[[Apache Maven|maven]]、[[SCons]]、[[MSBuild]]、[[Gradle]]などがある。[[統合開発環境]]には通例何らかのビルドツールが内蔵されており、直感的かつシームレスにプログラミングとビルド作業のサイクルを行なえるようになっている。ビルドユーティリティは、各種ファイル群を正しい順序で[[コンパイラ|コンパイル]]し[[リンケージエディタ|リンク]]する必要がある。また、開発時には何度もビルドを繰り返すが、前回のビルドから何も変更されていないファイルは[[コンパイラ|コンパイル]]する必要がない(ただし、[[ヘッダファイル]]などの依存関係も考慮する必要がある)。洗練されたビルドユーティリティは無駄な再コンパイルをしないようにして、ビルドに要する時間を短縮している。[[Apache Subversion|Subversion]]などの[[バージョン管理システム]]はビルドユーティリティの機能を内蔵している。さらに複雑なプロセスになると、ビルド中に他のプログラムを使ってコードやデータを生成することもある。


== ビルドの自動化 ==
== ビルドの自動化 ==
21行目: 24行目:
* 手順ミスの排除
* 手順ミスの排除
* 特定のエキスパートに依存しなくて済む。
* 特定のエキスパートに依存しなくて済む。
* 履歴を保持することで、問題発生時に原因を究しやすい。
* 履歴を保持することで、問題発生時に原因を究しやすい。
* 時間と金を節約できる<ref>[http://www.denverjug.org/meetings/files/200410_automation.pdf Pragmatic Project Automation] Mike Clark、2004年</ref>
* 時間と金を節約できる<ref>[http://www.denverjug.org/meetings/files/200410_automation.pdf Pragmatic Project Automation] {{webarchive|url=https://web.archive.org/web/20081123044304/http://www.denverjug.org/meetings/files/200410_automation.pdf |date=2008年11月23日 }} Mike Clark、2004年</ref>


ビルドツールはユーザーが手動で起動することもできるが、時間を決めて毎日実行する場合(夜間に行うことが多いのでナイトリービルド (Nightly Build) などと呼ぶ)、[[バージョン管理システム]]がソースファイルの変更がコミットされるたびに自動的に実行する場合などもある。
ビルドツールはユーザーが手動で起動することもできるが、時間を決めて毎日実行する場合(夜間に行うことが多いので[[ナイトリービルド]] (Nightly Build) などと呼ぶ)、[[バージョン管理システム]]がソースファイルの変更がコミットされるたびに自動的に実行する場合などもある。


== 歴史 ==
== 歴史 ==
一般に、プログラムはソースファイルをコンパイルしリンクすることで、実行ファイルとなる。ソースファイルが1つしかないなら、それらの作業をコマンドラインから実行するのも簡単だが、ソースファイルが多数存在するプロジェクトでは、正しい順序とオプションで手作業するのは至難の業である。この問題を解決する手段として[[make]]のようなスクリプト言語が登場した。それにより、コンパイルやリンクを正しい順序で行うスクリプトを書くことができる。GNU Make<ref>[http://www.gnu.org/software/make/ GNU Make]</ref>では更にソースコードの依存関係を管理でき、変更された部分だけをコンパイルするインクリメンタルビルドが可能になった。これがビルドの自動化の始まりである。その第一の目的はコンパイラやリンカの呼び出しを自動化することだった。ビルドプロセスが複雑化するに従い、コンパイラ呼び出しの前後に様々な作業(バージョン管理システムからのチェックアウトや生成した実行ファイルのテスト環境への投入など)を追加するようになった。
実行ファイル形式のプログラムを成果物(最終出力)とする方式のソフトウェア開発で、まずソースファイル(ソースコード)をコンパイルしてオブジェクトファイル(オブジェクトコード)に変換した後、そのオブジェクトファイルをリンクコンピュータ([[オペレーティングシステム]])が直接実行できるバイナリ形式のファイルを生成する作業が必要となる。ソースファイルが1つしかないなら、それらの作業をコマンドラインから実行するのも簡単だが、ソースファイルが多数存在するプロジェクトでは、正しい順序とオプションで手作業するのは至難の業である。この問題を解決する手段として[[make (UNIX)|make]]のようなスクリプト言語が登場した。それにより、コンパイルやリンクを正しい順序で行うスクリプトを書くことができる。GNU Make<ref>[http://www.gnu.org/software/make/ GNU Make]</ref>では更にソースコードの依存関係を管理でき、変更された部分だけをコンパイルするインクリメンタルビルドが可能になった。これがビルドの自動化の始まりである。その第一の目的はコンパイラやリンカの呼び出しを自動化することだった。ビルドプロセスが複雑化するに従い、コンパイラ呼び出しの前後に様々な作業(バージョン管理システムからのチェックアウトや生成した実行ファイルのテスト環境への投入など)を追加するようになった。


さらに、ビルドツールは進化し、スクリプト(Makefile)自体を生成するものが登場した。これらツールは、頻繁にビルドを行う[[継続的インテグレーション]]で特に便利である。
さらに、ビルドツールは進化し、スクリプト(Makefile)自体を生成するものが登場した。これらツールは、頻繁にビルドを行う[[継続的インテグレーション]]で特に便利である。また、複数のターゲットプラットフォームや異なる開発環境に応じたビルドスクリプトを必要に応じて自動生成するのにも役立つ


高度なビルドツールは分散ビルドや分散処理が可能である。「分散ビルド」とは、実際のコンパイルやリンクをそれぞれ別々のマシン上で行い、ビルドを高速化する手法である。一方、分散処理とは例えば、テスト用スクリプトを複数のマシンに配置し、新たな実行ファイルのテストを分散環境で自動的に行うことなどを指す。分散ビルドを行うには、ソースコードの依存関係を自動的に把握することが必須である。一部のビルドツールは依存関係を自動的に発見でき(Ratinal ClearMake<ref>{{cite|url= http://www.ddj.com/architect/184405385|accessdate=2009-04-13|title=Dr. Dobb's Distributed Loadbuilds}}</ref>、Electric Cloud ElectricAccelerator<ref>{{cite|url= http://www.ddj.com/architect/184415472|title=Dr. Dobb's Take My Build, Please}}</ref>など)、別のビルドツールではユーザーが定義した依存関係のみを扱う(Platform LSF lsmake<ref>{{cite|url= http://www.lle.rochester.edu/pub/support/lsf/10-lsmake.html|accessdate=2009-04-13|title=LSF User's Guide - Using lsmake}}</ref>など)。ソースコードの依存関係を把握できるビルドツールは、コンパイルおよびリンクを並行モードで実行するよう設定できる。すなわち、コンパイラやリンカを複数コアのマシン上でマルチスレッドモードで実行することができる。全てのビルドツールが分散ビルドを実施できるわけではない。
高度なビルドツールは分散ビルドや分散処理が可能である。「分散ビルド」とは、実際のコンパイルやリンクをそれぞれ別々のマシン上で行い、ビルドを高速化する手法である。一方、分散処理とは例えば、テスト用スクリプトを複数のマシンに配置し、新たな実行ファイルのテストを分散環境で自動的に行うことなどを指す。分散ビルドを行うには、ソースコードの依存関係を自動的に把握することが必須である。一部のビルドツールは依存関係を自動的に発見でき(Rational ClearMake<ref>{{cite|url= http://www.ddj.com/architect/184405385|accessdate=2009-04-13|title=Dr. Dobb's Distributed Loadbuilds}}</ref>、Electric Cloud ElectricAccelerator<ref>{{cite|url= http://www.ddj.com/architect/184415472|title=Dr. Dobb's Take My Build, Please}}</ref>など)、別のビルドツールではユーザーが定義した依存関係のみを扱う(Platform LSF lsmake<ref>{{cite|url= http://www.lle.rochester.edu/pub/support/lsf/10-lsmake.html|accessdate=2009-04-13|title=LSF User's Guide - Using lsmake}}</ref>など)。ソースコードの依存関係を把握できるビルドツールは、コンパイルおよびリンクを並行モードで実行するよう設定できる。すなわち、コンパイラやリンカを複数コアのマシン上でマルチスレッドモードで実行することができる。全てのビルドツールが分散ビルドを実施できるわけではない。


分散ビルドの例として Xoreax の IncrediBuild<ref>{{cite|url= http://www.xoreax.co.jp/|accessdate=2009-06-16|title=高速分散コンパイル環境ソリューション}}</ref>がある。
分散ビルドの例として Xoreax の IncrediBuild<ref>{{cite|url= http://www.xoreax.co.jp/|accessdate=2009-06-16|title=高速分散コンパイル環境ソリューション}}</ref>がある。

== インクリメンタルビルド ==
複数のソースファイルから成るソフトウェアの開発プロセスにおいて、ソースファイルにちょっとした変更を加えただけで、毎回すべてのソースファイルを無条件にコンパイルし直すのは効率が悪い。自動化されたビルドシステムでは、[[タイムスタンプ]]などを利用して変更のあったファイルのみを検出し、そのファイル自身とそれに依存する関連ファイルのみをコンパイルし直してリンクする「インクリメンタルビルド」(増分ビルド)をサポートしている<ref>[https://docs.microsoft.com/ja-jp/visualstudio/msbuild/incremental-builds インクリメンタル ビルド - Visual Studio | Microsoft Docs]</ref><ref>[https://blog.gradle.org/introducing-incremental-build-support Introducing Incremental Build Support | Gradle Blog]</ref>。これにより、コード編集・ビルド・実行・テストの開発サイクルを高速化することができる。

さらに、変更のあったモジュールのみをリンクし直す「インクリメンタルリンク」(増分リンク)をサポートする処理系も存在する<ref>[https://docs.microsoft.com/en-us/cpp/build/reference/incremental-link-incrementally /INCREMENTAL (Link Incrementally) | Microsoft Docs]</ref>。実行時に個別のライブラリモジュールをロードして結合する[[動的リンク]]ライブラリ方式の場合、リンク処理はシンボル情報のみが書かれたインポートライブラリを実行ファイルにリンクするだけなので高速だが、ビルド時にすべてのモジュールを結合して1つのファイルを生成する[[静的リンク]]ライブラリ方式の場合、リンク処理には時間がかかるため、インクリメンタルリンクが特に効果を発揮する。

ビルドシステムではなく、コンパイラモジュール自身が「インクリメンタルコンパイル」(増分コンパイル)をサポートしている言語もある。例えば[[Rust (プログラミング言語)|Rust]]のコンパイラはバージョン1.24以降でインクリメンタルコンパイルをサポートする<ref>[https://doc.rust-lang.org/edition-guide/rust-2018/the-compiler/incremental-compilation-for-faster-compiles.html Incremental Compilation for faster compiles - The Edition Guide]</ref><ref>[https://blog.rust-lang.org/2016/09/08/incremental.html Incremental Compilation | Rust Blog]</ref>。Rustコンパイラは、最初のステップとして[[抽象構文木]] (abstract syntax tree, AST) を構築し、次にASTを解析することで型情報 (type information) および個々の関数に関する中位の中間表現 (mid-level intermediate representation, MIR) を生成する。その後、エラーが見つからなければ、ソースレベルのモジュールごとにオブジェクトファイルを生成しながら、MIRから機械語コードに変換される。これらの型情報やMIR、およびオブジェクトファイルの要素を中間結果 (intermediate result) とみなし、ディスクにキャッシュとして保存しておき、2回目以降のコンパイルではキャッシュからロードする。また依存関係グラフをもとに、変更のあった要素だけを更新する。ただしRustのインクリメンタルコンパイルは2回目以降のビルドサイクルを高速化させるものの、最終的に生成されるバイナリの実行速度を若干低下させるデメリットがあるため、リリースビルドでは有効化されない。

=== Go ===
[[Go (プログラミング言語)|Go言語]]のコマンドラインツールは、ソースファイルのコンパイル<ref>[https://golang.org/cmd/compile/ compile - The Go Programming Language]</ref>とパッケージのビルド<ref>[https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies go - The Go Programming Language]</ref>をそれぞれ別々にサポートするが、Go 1.10以降の<code>go build</code>コマンドは、純粋にソースファイルの内容、ビルドフラグ、およびコンパイル済みパッケージ内に保存されているメタデータに基づいて、無効になったパッケージを検出してインクリメンタルビルドするようになり、ファイルの更新日時は無関係となった<ref>[https://golang.org/doc/go1.10#build Go 1.10 Release Notes - The Go Programming Language]</ref>。


== Makefile生成 ==
== Makefile生成 ==
ビルド自動化の一形態として、[[Make|Makefile]]の自動生成がある。例えば、次のようなツールがMakefileを自動生成する。
ビルド自動化の一形態として、[[Makefile]]の自動生成がある。例えば、次のようなツールがMakefileを自動生成する。
* [[Autotools|GNU Automake]]
* [[Autotools|GNU Automake]]
* [[CMake]]
* [[CMake]]
43行目: 56行目:
* [[Apache Ant]]
* [[Apache Ant]]
* [[Apache Maven]]
* [[Apache Maven]]

== 関連項目 ==
* [[スクリプト言語]]
* [[ソフトウェアテスト]]
* [[ソフトウェアのバージョン]]


== 脚注 ==
== 脚注 ==
{{脚注ヘルプ}}
{{reflist}}
{{reflist}}


== 参考文献 ==
== 参考文献 ==
* Mike Clark: ''Pragmatic Project Automation'', The Pragmatic Programmers ISBN 0-9745140-3-9
* Mike Clark: ''Pragmatic Project Automation'', The Pragmatic Programmers ISBN 0-9745140-3-9

== 関連項目 ==
* [[スクリプト言語]]
* [[ソフトウェアテスト]]
* [[ソフトウェアのバージョン]]


{{DEFAULTSORT:ひると}}
{{DEFAULTSORT:ひると}}
[[Category:プログラミング]]
[[Category:プログラミング]]
[[Category:ソフトウェア開発]]
{{Software-stub}}
{{Software-stub}}

[[de:Erstellungsprozess]]
[[en:Software build]]
[[ko:소프트웨어 빌드]]
[[pl:Kompilacja (informatyka)]]
[[uk:Застосунок побудова]]

2023年3月2日 (木) 09:19時点における最新版

ソフトウェアビルド: build)は、プログラミング言語で書かれたソースコードファイルや各種リソースファイル[要曖昧さ回避]を独立したソフトウェア生成物に変換するコンピュータ上で実行されるプロセス、またはその結果を指す。ビルドの最終生成物はバイナリ形式実行ファイルであったり、再利用可能なライブラリであったり、バイトコードあるいはそれらをまとめたアーカイブであったりすることもある[1]

概要

[編集]

ビルドにはいくつかのステップがあり、その内容はプログラミング言語やビルドツール、開発環境や実行環境(ターゲットアーキテクチャ、オペレーティングシステムあるいは仮想マシン)によっても異なる。例えばC言語あるいはC++の場合、ソースファイル(ソースコード)をコンパイラによってオブジェクトファイル(オブジェクトコード)に翻訳(コンパイル)した後、リンカによってオブジェクトコードを結合し、実行ファイルを生成する。プログラムから実行時に参照される各種アイコン画像やローカライズされた文字列などを実行ファイル内に「リソース」として含めることもあり、ビルドプロセスでリソースのコンパイルとリンクを実行する。

単純なプログラムでは、単一のソースファイルをコンパイルするだけで済むが、複雑なソフトウェアでは通例メンテナンス性向上の観点からソースコードはモジュールごとに分類・分割された多数のファイルによって構成されており、各ファイルを個別にコンパイル(分割コンパイル)した後で、リンク時に実体の依存関係を解決する。C/C++のような原始的なプログラミング言語では、ヘッダファイルを利用して、ユーザー定義型や定数、および関数などの定義または宣言を共有することが多い。ヘッダーファイルのインクルードにより、ファイル間の依存関係が発生する。

コンピュータプログラムのビルドは、一般にビルドツールと呼ばれるプログラムを使い、他のプログラムを制御・統合して行う。ビルドツールの例としては、makeantmavenSConsMSBuildGradleなどがある。統合開発環境には通例何らかのビルドツールが内蔵されており、直感的かつシームレスにプログラミングとビルド作業のサイクルを行なえるようになっている。ビルドユーティリティは、各種ファイル群を正しい順序でコンパイルリンクする必要がある。また、開発時には何度もビルドを繰り返すが、前回のビルドから何も変更されていないファイルはコンパイルする必要がない(ただし、ヘッダファイルなどの依存関係も考慮する必要がある)。洗練されたビルドユーティリティは無駄な再コンパイルをしないようにして、ビルドに要する時間を短縮している。Subversionなどのバージョン管理システムはビルドユーティリティの機能を内蔵している。さらに複雑なプロセスになると、ビルド中に他のプログラムを使ってコードやデータを生成することもある。

ビルドの自動化

[編集]

ビルドの自動化とは、以下のような開発作業をスクリプト化または自動化することを指す。

  • ソースコードをバイナリコードにコンパイルする。
  • バイナリコードをパッケージ化する。
  • テストを実行する。
  • 生産システムに配備する。
  • 文書やリリースノートを作成する。

ビルドを自動化する利点は次の通り。

  • 製品品質を向上させる。
  • コンパイルとリンクの所要時間短縮
  • 冗長なタスクの排除
  • 手順ミスの排除
  • 特定のエキスパートに依存しなくて済む。
  • 履歴を保持することで、問題発生時に原因を究明しやすい。
  • 時間と金を節約できる[2]

ビルドツールはユーザーが手動で起動することもできるが、時間を決めて毎日実行する場合(夜間に行うことが多いのでナイトリービルド (Nightly Build) などと呼ぶ)、バージョン管理システムがソースファイルの変更がコミットされるたびに自動的に実行する場合などもある。

歴史

[編集]

実行ファイル形式のプログラムを成果物(最終出力)とする方式のソフトウェア開発では、まずソースファイル(ソースコード)をコンパイルしてオブジェクトファイル(オブジェクトコード)に変換した後、そのオブジェクトファイルをリンクし、コンピュータ(オペレーティングシステム)が直接実行できるバイナリ形式のファイルを生成する作業が必要となる。ソースファイルが1つしかないならば、それらの作業をコマンドラインから実行するのも簡単だが、ソースファイルが多数存在するプロジェクトでは、正しい順序とオプションで手作業するのは至難の業である。この問題を解決する手段としてmakeのようなスクリプト言語が登場した。それにより、コンパイルやリンクを正しい順序で行うスクリプトを書くことができる。GNU Make[3]では更にソースコードの依存関係を管理でき、変更された部分だけをコンパイルするインクリメンタルビルドが可能になった。これがビルドの自動化の始まりである。その第一の目的はコンパイラやリンカの呼び出しを自動化することだった。ビルドプロセスが複雑化するに従い、コンパイラ呼び出しの前後に様々な作業(バージョン管理システムからのチェックアウトや生成した実行ファイルのテスト環境への投入など)を追加するようになった。

さらに、ビルドツールは進化し、スクリプト(Makefile)自体を生成するものが登場した。これらのツールは、頻繁にビルドを行う継続的インテグレーションで特に便利である。また、複数のターゲットプラットフォームや異なる開発環境に応じたビルドスクリプトを必要に応じて自動生成するのにも役立つ。

高度なビルドツールは分散ビルドや分散処理が可能である。「分散ビルド」とは、実際のコンパイルやリンクをそれぞれ別々のマシン上で行い、ビルドを高速化する手法である。一方、分散処理とは例えば、テスト用スクリプトを複数のマシンに配置し、新たな実行ファイルのテストを分散環境で自動的に行うことなどを指す。分散ビルドを行うには、ソースコードの依存関係を自動的に把握することが必須である。一部のビルドツールは依存関係を自動的に発見でき(Rational ClearMake[4]、Electric Cloud ElectricAccelerator[5]など)、別のビルドツールではユーザーが定義した依存関係のみを扱う(Platform LSF lsmake[6]など)。ソースコードの依存関係を把握できるビルドツールは、コンパイルおよびリンクを並行モードで実行するよう設定できる。すなわち、コンパイラやリンカを複数コアのマシン上でマルチスレッドモードで実行することができる。全てのビルドツールが分散ビルドを実施できるわけではない。

分散ビルドの例として Xoreax の IncrediBuild[7]がある。

インクリメンタルビルド

[編集]

複数のソースファイルから成るソフトウェアの開発プロセスにおいて、ソースファイルにちょっとした変更を加えただけで、毎回すべてのソースファイルを無条件にコンパイルし直すのは効率が悪い。自動化されたビルドシステムでは、タイムスタンプなどを利用して変更のあったファイルのみを検出し、そのファイル自身とそれに依存する関連ファイルのみをコンパイルし直してリンクする「インクリメンタルビルド」(増分ビルド)をサポートしている[8][9]。これにより、コード編集・ビルド・実行・テストの開発サイクルを高速化することができる。

さらに、変更のあったモジュールのみをリンクし直す「インクリメンタルリンク」(増分リンク)をサポートする処理系も存在する[10]。実行時に個別のライブラリモジュールをロードして結合する動的リンクライブラリ方式の場合、リンク処理はシンボル情報のみが書かれたインポートライブラリを実行ファイルにリンクするだけなので高速だが、ビルド時にすべてのモジュールを結合して1つのファイルを生成する静的リンクライブラリ方式の場合、リンク処理には時間がかかるため、インクリメンタルリンクが特に効果を発揮する。

ビルドシステムではなく、コンパイラモジュール自身が「インクリメンタルコンパイル」(増分コンパイル)をサポートしている言語もある。例えばRustのコンパイラはバージョン1.24以降でインクリメンタルコンパイルをサポートする[11][12]。Rustコンパイラは、最初のステップとして抽象構文木 (abstract syntax tree, AST) を構築し、次にASTを解析することで型情報 (type information) および個々の関数に関する中位の中間表現 (mid-level intermediate representation, MIR) を生成する。その後、エラーが見つからなければ、ソースレベルのモジュールごとにオブジェクトファイルを生成しながら、MIRから機械語コードに変換される。これらの型情報やMIR、およびオブジェクトファイルの要素を中間結果 (intermediate result) とみなし、ディスクにキャッシュとして保存しておき、2回目以降のコンパイルではキャッシュからロードする。また依存関係グラフをもとに、変更のあった要素だけを更新する。ただしRustのインクリメンタルコンパイルは2回目以降のビルドサイクルを高速化させるものの、最終的に生成されるバイナリの実行速度を若干低下させるデメリットがあるため、リリースビルドでは有効化されない。

Go

[編集]

Go言語のコマンドラインツールは、ソースファイルのコンパイル[13]とパッケージのビルド[14]をそれぞれ別々にサポートするが、Go 1.10以降のgo buildコマンドは、純粋にソースファイルの内容、ビルドフラグ、およびコンパイル済みパッケージ内に保存されているメタデータに基づいて、無効になったパッケージを検出してインクリメンタルビルドするようになり、ファイルの更新日時は無関係となった[15]

Makefile生成

[編集]

ビルド自動化の一形態として、Makefileの自動生成がある。例えば、次のようなツールがMakefileを自動生成する。

脚注

[編集]

参考文献

[編集]

関連項目

[編集]