私は最近、ほとんどの言語のメインのビルドツール/システムが、基礎となるプログラミング言語自体とは異なる言語を使用していることに気付いたとき、職場でNodejsプロジェクトのいくつかのビルドツールを使用しています。
たとえば、 make はスクリプトの作成にCまたはC++を使用せず、 ant (またはMaven)はJavaを言語として使用しませんスクリプト用。
Rubyのような新しい言語は rake のようなビルドツールに同じ言語を使用しますが、これは私にとっては理にかなっています。基礎となる言語とは異なる言語を使用するビルドツールを使用する利点は何ですか?
何かを実行するために使用するプログラミング言語の選択は、そのプロジェクトに関連する他のタスクではなく、その目標の特定の機能に依存する必要があります。
ビルドツールは非常に特殊な仕事を行います。メインプロジェクトで使用する言語に関係なく、ビルドツールはそれ自体がソフトウェアです。
メインプロジェクトとそのビルドツールを結びつけるのは、非常に悪い決定です。ビルドツールで必要なのは、主にファイルとIOを高速に管理する、単純なルールの高速プロセスです。
Rubyのような言語が自分自身を使用してビルドツールを実装する場合、すべてを同じ言語で記述する必要があるという想定よりも、その言語の機能に関連しています。
CやJavaなどの言語をスクリプト言語として使用するビルドツールを作成することは不可能ではありません。ただし、ビルドツールは、より多くのdeclarativeスクリプト言語を使用することでメリットを得ます。 Cでmakefile(またはbuild.xmlなど)を書くことの苦痛と定型を想像してみてください。
ビルドツールは、DSLの使用から利益を得ます。DSLの使用は、Cが特に適切な選択ではないタスクです。 Cは一般的すぎるビルドツールの場合、エラーが発生しやすく、低レベルの詳細にあまりにも関心があります。たとえば、ビルドツールでの明示的なメモリ管理について気にしたくありません! Cのような構文を使用していても、おそらくスクリプトツールでガベージコレクションを使用しているでしょう。
Rubyは、CやJavaよりも高レベルで宣言的な言語であるため、これに使用できます。また、Gradle、sbtも参照してください。
実際の例を挙げましょう。
15年ほど前に、Cで書かれた大規模システムをUnixからWindowsに移植する作業をしました。これは約300万行のコードでした。スケールの考え方を示すために、一部のUNIXシステム(RS6000)でコンパイルするのに24時間以上かかりました。Windowsは約4時間でシステムをコンパイルできました。
(独自のインタプリタ言語で200万行のコードもありましたが、ファイル処理用に設計されていないため、ビルドシステムには使用しないことにしました。また、言語を実装するCコードをコンパイルするためのビルドシステムが必要でした。)
ビルドシステムがシェルスクリプトとメイクファイルの混合で記述された当時、これらはWindowsに移植可能ではなかったため、独自のビルドシステムを作成することにしました。
Cを使用することもできましたが、Pythonを使用することにしました。理由はいくつかありました。 (同時に、ソースコード管理システムをpythonで書き直しました。これはビルドシステムと非常に統合されているため、チェックインされたモジュールのオブジェクトファイルは開発者が共有できます。)
ほとんどのコードは、ファイルの命名規則に基づいて駆動されたいくつかの単純なルール(すべてのプラットフォーム、Windows、VMS、および6バージョンのUnixの場合は数千行のpython)で構築できます。
当時、RegExは異なるプラットフォームのCシステム間であまり標準的ではなかったため、PythonはRegExを組み込みました。
いくつかのモジュールではカスタムビルドステップが必要でしたが、Pythonではクラスファイルを動的にロードできました。フォルダにマジックネームのあるpythonファイルがあることに基づいて、カスタムクラスを使用してモジュール(lib)を構築することを許可しました。 これがpythonを使用する大きな理由でした。
Javaを検討しましたが、その時点ではすべてのプラットフォームで出荷されていませんでした。
(私たちのソースコード管理システムのUIは、すべてのプラットフォーム間で移植可能であるため、Webブラウザーを使用しました。これは、インターネットに接続する前の6か月でした。X25経由でブラウザーをダウンロードする必要がありました!)
この質問に対する簡単な答えは、これがビルドツールとは何かであるということです。一部のソースファイルから最終製品を構築することを目的として、他のツールの使用を自動化するツール。製品自体と同じ言語でビルドスクリプトを記述している場合、言語固有のツールの領域に入ります。これは、同じ方法でビルドツールとは見なされません。
これは問題を提起します-なぜコンパイラは、makeのようなツールから慣れ親しんでいるようなビルド自動化を提供しないのですか? makeが存在するため、答えは単に(= /// =)です。 「1つのことをうまく行う」というUnixの哲学は、これを提供することはコンパイラーの責任ではないことを示唆しています。とは言っても、私は個人的にmakeの悩みの種を経験しており、独自の見積もりと非見積もりの「ネイティブ」ビルドシステムを提供するコンパイラを試してみたいと思います。
この方法で設計されたコンパイラーの例については、C++の置き換えを意図した言語である Jon Blow (まだリリースされていない)Jaiを参照してください。コンパイラーの講演とデモへのリンクが収集されます ここ 。この言語は、コンパイラー内で実行されるバイトコードにコンパイルされます。バイナリーへのコンパイルは、バイトコードからアクセス可能な標準ライブラリー提供関数です。その意図は、言語のネイティブ構文内でビルドの自動化とメタプログラミングの両方を可能にすることです。
* MicrosoftのVisual Studioを見ると、反対の哲学の例がわかります。 :)
ビルドツールは、「gcc」、「ls」、「awk」、または「git」と同じように、何よりもまずツールです。ツールに入力(ファイル名、パラメーターなど)をフィードすると、それに応じていくつかの処理が行われます。
これらのすべてのツールを使用すると、記述および理解するのに十分単純な方法で入力を渡すことができます。ビルドツールの特定のケースでは、入力はレシピファイルです。これは、プロジェクトがソースファイルから完成品に至るまでの過程を記述するファイルです。
レシピが、使用するプロジェクトとコンパイラを含むフォルダを渡すだけの単純なものである場合は、宣言的な「言語」で十分です。レシピがますます複雑になり、ロジックが増えると、宣言型言語でレシピを処理するのが面倒になり、より汎用的な言語が使用されます。
ビルドレシピの記述に使用される言語と製品コードの記述に使用される言語の間には、目的と要件が異なるという理由だけで関連がないことが明らかになりました。ビルドツールが記述されている言語とビルドレシピが記述されている必要がある「言語」の間にも関係はありません。常に、ジョブに最適なツールを使用してください。