web-dev-qa-db-ja.com

Javaでmakeを使用していないのはなぜですか?

私が見たほとんどすべてのJavaプロジェクトはMavenまたはAntを使用します。これらは素晴らしいツールであり、どんなプロジェクトでもそれらを使用できると思います。しかし、これまでに起こったこと make ?Java以外のさまざまなプロジェクトで使用され、Javaを簡単に処理できます。Windowsを使用している場合はmake.exeをダウンロードする必要がありますが、AntとMavenもJDKには付属していません。

Javaで使用した場合、makeに基本的な欠陥はありますか? AntとMavenがJavaで書かれているからですか?

149
User1

MakeとJavaの基本的な問題は、Makeが依存関係を指定し、その依存関係を解決するルールを指定しているという前提で動作することです。

基本的なCでは、通常、「main.cファイルをmain.oファイルに変換するには、「cc main.c」を実行します。

Javaでそれを行うことができますが、すぐに何かを学びます。

ほとんどの場合、javacコンパイラは起動に時間がかかります。

の違い:

javac Main.Java
javac This.Java
javac That.Java
javac Other.Java

そして

javac Main.Java This.Java That.Java Other.Java

昼と夜です。

それを何百ものクラスで悪化させてください。

次に、これを、Javaはディレクトリ内のファイルのグループとして編成される傾向があるのに対し、Cやその他のフラットな構造に向かう傾向があります。makeは、作業を直接サポートしていません。ファイルの階層で。

また、Makeは、どのファイルが古くなっているかをコレクションレベルで判断するのにはあまり適していません。

Antを使用すると、古くなったすべてのファイルを調べて合計し、一度にコンパイルします。 Makeは、個々のファイルごとにJavaコンパイラーを呼び出します。makeを実行しない場合は、Makeがタスクに完全に対応していないことを示す十分な外部ツールが必要です。

それが、AntやMavenのような選択肢が生まれた理由です。

180
Will Hartung

由緒あるmakeプログラムは、CやC++などの個別にコンパイルされた言語を適切に処理します。モジュールをコンパイルし、#includeを使用して他のインクルードファイルのテキストを取り込み、単一のオブジェクトファイルを出力として書き込みます。コンパイラは、オブジェクトファイルを実行可能なバイナリにバインドするための個別のリンク手順を備えた非常に1度に1つのシステムです。

ただし、Javaでは、コンパイラは実際にcompileimportでインポートする他のクラスを使用する必要があります。 Javaソースコードからすべての必要な依存関係を生成する何かを書くことができるので、makeは一度に正しい順序でクラスを構築します。循環依存関係などのケースは処理しません。

Javaコンパイラーは、他のクラスのコンパイル結果をキャッシュすると同時に、既にコンパイルされたクラスの結果に依存するクラスをさらにコンパイルすることにより、より効率的になります。 makeのみ。

31
Greg Hewgill

質問は間違った仮定に基づいています:開発者の自明でない数domakeを使用します。 Java Build Tools:Ant vs. Maven を参照してください。開発者makeを使用しない理由:多くの開発者がmakeを使用したことがない、または使用したことがない千太陽よりも燃える火でそれを嫌っていました。そのため、代替ツールを使用します。

28
Hank Gay

実際、makeはすべての古いJavaファイルの1つのコマンドで再コンパイルを処理できます。ディレクトリ内のすべてのファイルをコンパイルしたくない場合、または特定の順序が必要な場合は最初の行を変更してください...

Java_FILES:=$(wildcard *.Java)
#
# the rest is independent of the directory
#
Java_CLASSES:=$(patsubst %.Java,%.class,$(Java_FILES))

.PHONY: classes
LIST:=

classes: $(Java_CLASSES)
        if [ ! -z "$(LIST)" ] ; then \
                javac $(LIST) ; \
        fi

$(Java_CLASSES) : %.class : %.Java
        $(eval LIST+=$$<)
21
user1251840

それぞれの技術的メリットに関する他のすべての答えは真実です。 AntMavenは、Javaよりもmakeに適している場合があります。または、ハンクゲイが指摘しているように、そうでない場合があります:)

ただし、AntとMavenがJavaで記述されていることが重要かどうかを尋ねました。 StackOverflowでは、そのような考え(閉じられた!プログラミング関連ではない!など)は考慮していませんが、コースの一部です。 On Rails私たちはRakeを使用し、Cの男はmakeを使用し、in JavaではAntとMavenを使用します。 Java開発者はおそらく他の開発者よりも優れていますが、別の質問もあります。Antタスクを何に書くのですか?Java。あなたがJava開発者なら、簡単にフィット。

ええ、その一部は、あなたが使っている言語で書かれたツールを使うことです。

17
Dan Rosenstark

Antおよび後のMavenは、Makeによって引き起こされるいくつかの頭痛を解決するために設計されました(プロセスで新しいものを作成する際に)それは単なる進化です。

...その後すぐに、いくつかのオープンソースJavaプロジェクトは、AntがMakefilesにあった問題を解決できることに気づきました。..

から http://ant.Apache.org/faq.html#history

彼らが何かを解決するか、単に学習するための特別な形式を作成するかは、主観的なトピックです。真実は、それがほとんどすべての新しい発明の歴史だということです。作成者は多くの問題を解決し、元のユーザーはそれらが美徳だと言います。

主な利点は、Javaと統合できることです。

同様の履歴は、たとえばrakeにも当てはまります。

12
OscarRyz

Maven(およびIvy対応のAntセットアップ)がmakeで解決した主要な問題の1つは、依存関係の自動解決と依存関係jarのダウンロードです。

9
Ophidian

最も可能性の高い説明は、いくつかの要因が重要な期間(1990年代後半)にJavaコミュニティ内でのmakeの使用を妨げたためだと思います。

  1. Javaは複数のプラットフォームを網羅しているため、Javaプログラマーは一般的にUnixツールに精通していませんでした。これは一般的なものであることに注意してください。疑いもなく、Unixを深く理解しているJavaプログラマーがいます。
  2. その結果、彼らはmakeにあまり慣れておらず、makeを効果的に使用する方法を知りませんでした。
  3. Javaを効率的にコンパイルする短くシンプルなMakefileを作成することは可能ですが、プラットフォームに依存しない方法で行うには特別な注意が必要です。
  4. その結果、本質的にプラットフォームに依存しないビルドツールへの欲求がありました。
  5. Antと後のMavenが作成されたのは、この環境です。

要するに、makeはJavaプロジェクトに最も確実に使用できますが、事実上のJavaビルドツールにする機会がありました。その瞬間は過ぎました。

Makeスクリプトは本質的にプラットフォームに依存する傾向があります。 Javaはプラットフォームに依存しないことになっています。したがって、マルチプラットフォームソースベースの1つのプラットフォームでのみ動作するビルドシステムを使用することは、一種の問題です。

5
Brian Fox

簡単な答え:makeは良くないからです。 Cの前面でも、多くの選択肢が表示されます。

長い答え:makeには、Cのコンパイルにはほとんど適さず、Javaのコンパイルにはまったく適さないいくつかの欠陥があります。必要に応じてJavaのコンパイルを強制することもできますが、問題が発生する可能性があり、その一部には適切な解決策や回避策がありません。以下にいくつかを示します。

依存関係の解決

makeは本質的に、ファイルが互いにツリー状の依存関係を持つことを期待します。この場合、1つのファイルは他のいくつかのビルドの出力です。これは、ヘッダーファイルを処理するときにCで既に裏目に出ます。 makeでは、ヘッダーファイルへのCファイルの依存関係を表すために、make固有のインクルードファイルを生成する必要があります。したがって、後者を変更すると、事前ビルドが再構築されます。ただし、Cファイル自体は再作成されない(単に再構築される)ため、多くの場合、makeはターゲットを.PHONYとして指定する必要があります。幸いなことに、GCCはこれらのファイルの自動生成をサポートしています。

Javaでは、依存関係を循環させることができ、make形式でクラスの依存関係を自動生成するツールはありません。代わりに、antDependタスクは、クラスファイルを直接読み取り、インポートするクラスを決定し、それらのいずれかが古い場合はクラスファイルを削除できます。これがないと、重要な依存関係がないため、クリーンビルドを繰り返し使用せざるを得ず、ビルドツールを使用する利点がなくなります。

ファイル名のスペース

JavaもCもソースコードのファイル名にスペースを使用することを推奨していませんが、makeでは、スペースがファイルパスにある場合でも問題になります。たとえば、ソースコードがC:\My Documents\My Code\program\srcに存在する場合を考慮してください。これはmakeを壊すのに十分でしょう。これは、makeがファイル名を文字列として扱うためです。 antは、パスを特別なオブジェクトとして扱います。

ビルドのためのファイルのスキャン

makeでは、ターゲットごとにビルドするファイルを明示的に設定する必要があります。 antを使用すると、ソースファイルを自動スキャンするフォルダーを指定できます。少し便利なように思えるかもしれませんが、Javaでは新しいクラスごとに新しいファイルが必要になることを考慮してください。プロジェクトにファイルを追加すると、大きな手間がかかります。

そして、makeの最大の問題:

makeはPOSIX依存です

Javaのモットーは、「どこでも実行したらコンパイル」です。ただし、Javaサポートが実際に最悪であるPOSIXベースのシステムにそのコンパイルを制限することは意図していません。

makeのビルドルールは、本質的に小さなbashスクリプトです。 makeのWindowsへのポートがありますが、それが適切に機能するためには、bashのポートにバンドルする必要があります。これには、ファイルシステムのPOSIXエミュレーションレイヤーが含まれます。

これには2つの種類があります。

  1. MSYSは、POSIX変換をファイルパスに制限しようとするため、特に作成されていない外部ツールを実行するときに不快な落とし穴が生じる可能性があります。

  2. 完全なPOSIXエミュレーションを提供するcygwin。ただし、結果のプログラムは、そのエミュレーション層に依存する傾向があります。

そのため、Windowsでは、標準ビルドツールはmakeでさえありませんが、MSBuildはXMLベースのツールであり、原則としてant

対照的に、antはJavaで構築され、どこでも実行でき、プラットフォームに依存しない方法でファイルを操作し、コマンドを実行するための「タスク」と呼ばれる内部ツールを含みます。 antを使用するよりもmakeを使用してWindowsでCプログラムを作成する方が実際に簡単にできるほど十分に汎用性があります。

そして最後のマイナーなもの:

Cプログラムでもmakeをネイティブに使用しません

最初はこれに気付かないかもしれませんが、Cプログラムには通常Makefileが付属していません。それらは、実際のbashを生成するCMakeLists.txtまたはMakefile構成スクリプトとともに出荷されます。対照的に、antを使用してビルドされたJavaプログラムのソースには、ビルド済みのantスクリプトが付属しています。 Makefileは他のツールの製品です-それだけでmakeがビルドツールとして不適切です。 antはスタンドアロンであり、Javaビルドプロセスに必要なすべてを処理します。追加の要件や依存関係はありません。

antを任意のプラットフォームで実行すると、Just Works(tm)になります。 makeでそれを取得することはできません。プラットフォームと構成に非常に依存しています。

4
SlugFiller

私が誰でもない限り、Javaにmakeを使用することは(誤)だれもしないという仮定は間違っています。

「GNU Makeを使用したプロジェクトの管理」(GFDLで利用可能)には、make with Javaプロジェクト。

他のツールの代わりにmakeを使用することの長所と短所の長い(そしてできれば公平な)リストが含まれているので、そこを調べてみてください。 (参照: http://oreilly.com/catalog/make3/book/

4
mikyra

AntはMakefilesに対するXML構成指向の改善であり、MavenはAntに対する依存関係構築ツールの改善です。 3つすべてを使用するプロジェクトもあります。 JDKプロジェクトでは、メイクファイルとantを組み合わせて使用​​していたと思います。

3
Berlin Brown

ApacheAntはMakeのようなものではありません。 Makeは、ファイル間の依存関係の記述と、ファイルの構築方法に関するものです。 Antは「タスク」間の依存関係に関するものであり、実際にはビルドスクリプトを結合する方法の1つです。

それはあなたを助けるかもしれません AntVsMake

1
Venky Vungarala

昔々、私はgmakeを使用したJavaプロジェクトに取り組みました。私の思い出はかすんでいますが、IIRCはjavacが期待するパッケージディレクトリ構造を扱うのに苦労しました。些細なことをしない限り、ファイルは面倒です。

1
carej

大きな理由の1つは、AntとMaven(およびほとんどのJavaターゲットSCM、CI、およびIDEツール)がJava開発者によってJavaで書かれていることです。これにより、開発環境への統合がより簡単になり、IDEやCIサーバーなどの他のツールがビルド/展開インフラストラクチャ内のant/mavenライブラリの一部を統合できるようになります。

1
Chris Nava

AntとMavenは、ビルドの依存関係グラフとその管理を、より「現代的な」観点からアプローチします...しかし、オスカーが言うように、makeで古い問題に対処しようとしながら、独自の問題を作成しました。

0
John Weldon

GNU Make for Javaプロジェクトを使用したことがありませんが、以前は jmk を使用していました。残念ながら、更新されていません。 2002年以降。

Java固有の機能がいくつかありましたが、サイズを大幅に増やすことなくソースtarballに含めることができるほど小さいものでした。

最近では、コードを共有する開発者がAntをインストールしているJava.

0
finnw