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


162

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

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


37
コンパイラを起動するだけでなく、さらに移動する場合、プラットフォーム固有のものをで処理するのは非常に厄介ですmake。また、1つのシステムでのみ機能するmakefileを使用することは、クロスプラットフォーム言語にはあまり適していません。
Joey、

余談ですが、GradleはGantと同様に、Java空間の新しいプレーヤーです(程度は低いですが)。MavenまたはAntは誤った二分法です。
マイケルイースター

@マイケルイースター、誤った二分法はメイブン/アント対メイクです。本当の二分法は、私があなたを正しく読んでいるなら、Gradle / Maven / Gant / Ant対Makeでしょう。しかし、言うのは難しいです:)
Dan Rosenstark

回答:


192

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などの代替手段が登場しました。


6
したがって、巨大なJavaプロジェクトでmakeを使用するには、変更されたすべての.javaファイルのリストを維持し、最後にjavacを呼び出す必要がありますか?それは私には理想的とは言えません。これが、私がこれまで見てきた最良の答えです。
User1 2010

32
これ大好き。重要なのは、javacが遅すぎるという事実に対処するためにAntが必要だったということです。
cmcginty 2010年

25
いいえ。Javacは、使用するように設計されているため、使用しても遅くなりません。一度に1つのファイルをコンパイルするためにそれを使用する場合、それはただ遅いです。
スティーブンC

7
@Casey javacは遅すぎません。JVMが起動するには遅すぎます。
–ThorbjørnRavn Andersen 2012

7
GNU Makeには、「ターゲットよりも新しいすべての前提条件」に展開される$?自動変数があります。すべてのファイルを更新するためにレシピを一度だけ実行する複数のターゲット持つパターンルールの機能もあり.classます。ことは、のようなファイル/テキスト機能のいくつかの巧妙な使用と組み合わせて$(wildcard)$(shell)$(eval)、あなたのディレクトリレイアウトに散在ビルドターゲットを発見するために、あなたのメイクを教えることができます。
Tanz87 2016年

33

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

ただし、Javaでは、コンパイラーは実際にでインポートする他のクラスをコンパイルする必要がありますimport。Javaソースコードから必要なすべての依存関係を生成するものを記述makeして、一度に1つずつ正しい順序でクラスを構築することは可能ですが、これでも循環依存関係などのケースは処理されません。

Javaコンパイラーは、他のクラスのコンパイル結果をキャッシュすると同時に、すでにコンパイルされた結果に依存するクラスをさらにコンパイルすることで、より効率的にすることもできます。この種の自動依存関係評価は、make単独では実際には不可能です。


7
これはmake対ant / mavenの答えよりもmake対javacの答えのように見えます。あなたの答えに基づいて、なぜ誰かがmake + javacを使用できないのですか(javacに一度にパッケージ全体または「モジュール」を与えるため、循環依存関係はmakeから隠されています)。antやmavenはそのアプローチよりもメリットがありますか?
ローレンスゴンサルベス2010

1
@Laurence:javacにパッケージ全体を一度に与えることができますが、そのパッケージ内のすべてを再コンパイルします(これは、あなたがそうするように指示したためです)。確かに、Javaコンパイラーはかなり高速ですが、何かを変更した後に再コンパイルするために最低限必要なクラスを判別させると、さらに高速になります。
グレッグヒューギル2010

「メイン」クラスのみをコンパイルするようにjavacに指示し、それが依存するものを自動的にビルドさせることを参照していますか?最後に私は(確かに、おそらく1.4で)ひどく信頼できないことを確認しました。-Xdependは少し優れていましたが(ただし遅く、まだ壊れています)、1.3ではそのフラグが削除されました。
ローレンスゴンサルベス2010

4
また、これでも、単純なjavacではなくAntまたはMavenを使用する理由が説明されていません...
Laurence Gonsalves

28

この質問は、誤った仮定に基づいてますmake。重要な数の開発者使用してます。Java Build Tools:Ant vs. Mavenを参照してください。開発者使用しない理由については、make多くの開発者が使用したことがないか、使用せずにmake 1000太陽よりも熱い炎でそれを嫌っていました。そのため、彼らは代替ツールを使用しています。


10
私たちはそれを使用しており、火は千と一太陽よりも高温です。
2010

4
@reccles:ビルドエンジニアリングへの憎悪か、それとも自分自身を作るか?Ant、Maven、または他の何かがどのように改善されますか(つまり、そのクラスの悪いツールを作成します)?
User1 2010

5
@ User1 makeには多くの「機能」があり、書かれたときに意味をなしていたかもしれませんが、バグのようになりました。たとえば、特定の場所ではスペースではなく、TAB文字を使用する必要があります。そのようなことは、で実際に経験している人々を困らせることはおそらくありませんmakeが、それは私たちの残りの部分を混乱させます。
Hank Gay

4
@HankGuy:編集者にその詳細について心配させてください。エディターがタブ<->スペースの設定を正しく処理できない場合は、新しいエディターを入手してください。しかし、動的依存関係の処理方法(make depend誰か?)のように、多くの機能が古くなっているとあなたは言っています
D.Shawley

3
@ User1これは私たちが構築しているプロジェクトの規模です。フルタイムのスタッフメンバーがメイクファイルとビルドの依存関係を維持しています。mavenを使用していたので、より扱いやすいことがわかりました。メイベンも完璧ではなかったと今言っています。規定された設定とは少し異なるビルドを実行するために必要なXML設定を理解しようとすることほど腹立たしいことはありません。
2010

28

実際には、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+=$$<)

4
いいね!そんなものを探していました。ユニバーサルクラシックが正常に機能する場合は、言語ごとに異なるビルドツールを使用する必要はありません。ありがとう!
rsp

17

それぞれの技術的なメリットに関する他のすべての答えは真です。AntそしてMaven、より良いメイクよりもJavaのに適した、またはハンクゲイが指摘するように、彼らはないかもしれすることができる:)

ただし、AntとMavenがJavaで記述されていることが重要かどうかを尋ねました。StackOverflowでは、そのような考え(クローズド!プログラミング関連ではない!など)は考慮していませんが、コースはその一部です。RailsではRakeを使用し、Cの男はmakeを使用し、JavaではAntとMavenを使用します。AntまたはMavenの開発者がJava開発者をおそらく他の人よりもよく見守るのは事実ですが、別の質問もあります。Antタスクを何で作成しますか?Java。あなたがJava開発者であれば、それは簡単に適合します。

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


7
Antは、JavaコミュニティがXMLに夢中になっているときにも発生しました。(XMLに場所がないと言っているわけではありません。)
Laurence Gonsalves

3
ある@Laurenceゴンサルベス、そう真。しかし、ここではSOの流行については触れません:)私は当時Java devを教えていましたが、すべてがXMLでした。現在でもXMLですが、誰も気にしません。
Dan Rosenstark、2010

1
ツールのコメントは興味深いものです。makeはUNIXのバックグラウンドから来ているため、便利なコンパクトユーティリティを作成し、それらを一緒にパイプライン処理することによってツールが実行されます。これが、ほとんどのステッチがシェルコマンドを使用して行われる理由です。
D.Shawley 2010

2
@D。Shawley、make小さなUnix utils に関してはすべて正しい。GITもそのプロセスの子です。個人的には、それが良くないわけではありません。しかし、これはJavaプログラマにとって大きなパラダイムシフトです。Antは、Javaの考え方にずっと調和しています。
Dan Rosenstark、2010

12

Ant以降のMavenは、Make(プロセス中に新しい問題を作成する際に)引き起こされるいくつかの頭痛を解決するように設計されています。

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

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

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

それが持っている主な利点は、Javaと統合する可能性です。

rakeたとえば、似たような歴史があったと思います。


4
それはあまり具体的ではありません。Mavenはmakeによって引き起こされるどのような問題を解決しますか?
ローレンスゴンサルベス2010

1
@ゴンサルベス:それはすべての新しいテクノロジーの主観的な側面の1つであり、代替の作成者はそれが多くの問題を解決すると言い、置き換えられたテクノロジーの作成者はそれらは欠陥ではなく美徳などであると言います。この特定の状況では、
すぐに使える

2
[最新のコメントではなく、回答の編集を参照]それでも解決された問題については説明されていません。問題が解決されたと作成者のアリが主張しているだけです...:-/私の印象は、Antが最初に作成したものですMakeに代わるより簡単な方法です。時間の経過とともに、欠けているものがあり、Antがmakeと同じくらい複雑になるまで機能が追加されましたが、binutilsが組み込まれています(makeはcp、rmなどの外部ツールに大きく依存しています)。もちろんXML構文もあります。
ローレンスゴンサルベス2010

2
はい。ただし、新しい選択肢の作成者ができる最善のことは、実際に何が問題であるかを言わずに「これで古い問題が解決する」と言うことです。これは、どのオプションを使用するかを検討している人にはあまり役に立ちません。Ant は、makeでが持っている問題解決しますか、それとも、新しい問題を紹介するときに問題とは見なさないものを解決しますか?
ローレンスゴンサルベス2010

9

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


6

最もありそうな説明は、いくつかの要因が、重要な期間(1990年代後半)にJavaコミュニティ内でmakeを使用することを妨げたと考えています。

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

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


5

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


5

短い答え:なぜなら make良くないから。Cのフロントでも、多くの選択肢がポップアップ表示されます。

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

依存関係の解決

make本質的に、ファイルは互いにツリーのような依存関係を持っていると想定しています。1つのファイルは、他のファイルをいくつかビルドした結果の出力です。ヘッダーファイルを処理するとき、これはすでにCで逆効果です。ヘッダーファイルに対するCファイルの依存関係を表すために-固有のインクルードファイルを生成するmake必要がある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スクリプトです。makeWindowsへのポートがありますが、それが正しく動作するbashためには、ファイルシステムのPOSIXエミュレーションレイヤーを含むのポートにバンドルする必要があります。

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

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

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

そのため、Windowsでは、標準のビルドツールはまったく同じmakeではなくMSBuild、XMLベースのツールであり、原則としてに近いツールですant

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

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

Cプログラムでさえmakeをネイティブに使用しない

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

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


4

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

「GNU Makeを使用したプロジェクトの管理」(GFDLで利用可能)には、makeJavaプロジェクトでの使用に特化した完全な章が含まれています。

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


これは正確な要約ですか?makeは(さまざまなフレーバーで)Javaで使用できますが、多少苦労します。AntMaven(およびjmake?)は、Javaプロジェクトをより速く簡単に構築するために、Javaが必要とする特別なことを行います。また、Java以外のプロジェクトのプラットフォームに依存しないビルドプロセスにも使用できますが、Java向けに調整されています。
Phil Perry

3

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


1

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


1

むかしむかし、gmakeを使用するJavaプロジェクトに取り組みました。私の思い出はかすんでいますが、IIRCはjavacが期待するパッケージディレクトリ構造を扱うのに苦労しました。また、些細なことがなければ、JARファイルの作成が面倒だったことも覚えています。


1

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

AntVsMakeを助けるかもしれませ


反対票の理由を知りたいのですが。
hagello 2018

0

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


0

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

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

最近では、コードを共有するJava開発者にAntがインストールされていると思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.