Perché nessuno usa make per Java?


162

Quasi ogni progetto Java che ho visto utilizza Maven o Ant. Sono ottimi strumenti e penso che quasi tutti i progetti possano usarli. Ma che cosa mai è successo a fare ? È usato per una varietà di progetti non Java e può gestire facilmente Java. Sicuramente devi scaricare make.exe se usi Windows, ma anche Ant e Maven non vengono forniti con JDK.

C'è qualche difetto fondamentale con make quando usato con Java? È solo perché Ant e Maven sono scritti in Java?


37
Se muovi le cose e fai qualcosa di più che invocare il compilatore (e anche allora), le cose specifiche della piattaforma diventano molto difficili da gestire make. E avere un makefile che funziona solo su un sistema non è molto bello per un linguaggio multipiattaforma.
Joey,

A parte questo, Gradle è un nuovo giocatore nello spazio Java, così come Gant (in misura minore). Maven o Ant è una falsa dicotomia.
Michael Easter,

@Michael Easter, la falsa dicotomia sarebbe Maven / Ant vs. Make. La vera dicotomia, se ti sto leggendo bene, sarebbe Gradle / Maven / Gant / Ant vs. Make. Ma è un po 'difficile da dire :)
Dan Rosenstark,

Risposte:


192

Il problema fondamentale con Make e Java è che Make funziona sul presupposto che sia stata specificata una dipendenza, quindi una regola per risolverla.

Con C di base, che in genere "per convertire un file main.c in un file main.o, eseguire" cc main.c ".

Puoi farlo in Java, ma impari rapidamente qualcosa.

Principalmente che il compilatore javac è lento per l'avvio.

La differenza tra:

javac Main.java
javac This.java
javac That.java
javac Other.java

e

javac Main.java This.java That.java Other.java

è notte e giorno.

Esacerbalo con centinaia di classi e diventa insostenibile.

Quindi lo combini con il fatto che Java tende ad essere organizzato come gruppi di file in directory, vs C e altri che tendono verso una struttura più piatta. Make non ha molto supporto diretto per lavorare con gerarchie di file.

Inoltre, Make non è molto bravo a determinare quali file non sono aggiornati a livello di raccolta.

Con Ant, esaminerà e riassumerà tutti i file non aggiornati, quindi li compili in una volta sola. Make chiamerà semplicemente il compilatore Java su ogni singolo file. Avere make NOT per farlo richiede strumenti esterni sufficienti per dimostrare davvero che Make non è all'altezza del compito.

Ecco perché sono nate alternative come Ant e Maven.


6
Quindi, per usare make in un enorme progetto Java, sarebbe necessario mantenere un elenco di tutti i file .java modificati e quindi chiamare javac alla fine? A me sembra meno che ideale. Questa è la migliore risposta che ho visto finora.
Utente1

32
Amo questo. Essenziale, stai dicendo che Ant era necessaria per affrontare il fatto che javac è troppo lento.
cmcginty

25
No. Javac non è lento se lo usi perché è stato progettato per essere utilizzato. È solo lento se lo usi per compilare un file alla volta.
Stephen C,

7
@Casey javac non è troppo lento. La JVM è troppo lenta per l'avvio.
Thorbjørn Ravn Andersen,

7
GNU Make ha almeno la $?variabile automatica che si espande a "tutti i prerequisiti più recenti della destinazione". C'è anche la funzione delle regole del modello con più destinazioni che eseguono la ricetta una sola volta per aggiornare tutti i .classfile. Combina che con un po 'uso intelligente di file / funzioni di testo come $(wildcard), $(shell), $(eval)e si può insegnare al vostro makefile per scoprire gli obiettivi di build sparsi per il layout della directory.
Tanz87,

33

Il venerabile makeprogramma gestisce ragionevolmente bene i linguaggi compilati separatamente come C e C ++. Compilate un modulo, lo usa #includeper estrarre il testo di altri file include e scrive un singolo file oggetto come output. Il compilatore è un sistema alla volta, con un passaggio di collegamento separato per associare i file oggetto in un file binario eseguibile.

Tuttavia, in Java, il compilatore deve effettivamente compilare altre classi con cui si importa import. Sebbene sarebbe possibile scrivere qualcosa che abbia generato tutte le dipendenze necessarie dal codice sorgente Java, in modo da makecostruire le classi nell'ordine corretto una alla volta, ciò non gestirà comunque casi come dipendenze circolari.

Il compilatore Java può anche essere più efficiente memorizzando nella cache i risultati compilati di altre classi mentre compilando ulteriori classi che dipendono dai risultati di quelli già compilati. Questo tipo di valutazione automatica delle dipendenze non è realmente possibile con il makesolo.


7
Sembra più una risposta make contro javac che una risposta make contro form / maven. In base alla tua risposta, perché qualcuno non potrebbe semplicemente usare make + javac (dando a javac un intero pacchetto o "modulo" alla volta, quindi le dipendenze circolari sono nascoste da make)? La formica o la maven fornirebbero qualche vantaggio rispetto a tale approccio?
Laurence Gonsalves,

1
@Laurence: potresti dare a javac un intero pacchetto in una volta, ma poi ricompilerà tutto in quel pacchetto (dato che è quello che gli hai detto di fare). È vero che il compilatore java è piuttosto veloce, ma è ancora più veloce se lasci che determini quali classi sono il minimo necessario per ricompilare dopo aver cambiato qualcosa.
Greg Hewgill,

Ti riferisci a dire a javac di compilare solo la tua classe "principale", e poi farla costruire automaticamente le cose da cui dipende? L'ultima volta che ho verificato (è vero, probabilmente in 1.4) che era orribilmente inaffidabile. -Xdepend era leggermente migliore (ma più lento e ancora rotto), e hanno rimosso quella bandiera in 1.3.
Laurence Gonsalves,

4
Inoltre, questo non spiega ancora perché dovrei usare Ant o Maven piuttosto che semplicemente javac dritto ...
Laurence Gonsalves

28

La domanda si basa su un presupposto errato: un numero non banale di sviluppatori fanno uso make. Vedi Java Build Tools: Ant vs. Maven . Per quanto riguarda il motivo per cui uno sviluppatore non avrebbe usato make: molti sviluppatori o non l'hanno mai usato makeo l'hanno usato e lo odiavano con un fuoco che brucia più caldo di mille soli. Come tali, usano strumenti alternativi.


10
Lo usiamo e il fuoco è più caldo di mille e uno soli.
recc

4
@Reccles: è solo odio verso l'ingegneria della costruzione o farsi da sé? In che modo sarebbe meglio Ant, Maven o qualcos'altro (ovvero creare uno strumento negativo per la sua classe)?
Utente 1

5
@ User1 makeha molte "caratteristiche" che potrebbero avere senso quando è stato scritto, ma ora sono più simili a bug, ad esempio, è necessario utilizzare un carattere TAB, non spazi, in determinati punti. Questo genere di cose probabilmente non disturba le persone con esperienza make, ma fa impazzire il resto di noi.
Hank Gay,

4
@HankGuy: lascia che il tuo editor si preoccupi di quel dettaglio. Se il tuo editor non è in grado di gestire correttamente le impostazioni dello spazio della scheda <->, ottieni un nuovo editor e sarai molto più felice. Ma hai ragione nel dire che molte funzionalità sono obsolete come il modo in cui vengono gestite le dipendenze dinamiche ( make dependchiunque?)
D.Shawley,

3
@ Utente1 È la scala del progetto che stiamo costruendo. Abbiamo un membro dello staff a tempo pieno che mantiene i file di creazione e crea dipendenze. Avendo usato Maven l'ho trovato più gestibile. Ora, detto anche che Maven non era perfetto. Niente è più esasperante che cercare di capire quali impostazioni XML sono necessarie per fare una build leggermente diversa dalla configurazione prescritta.
Reccles

28

In realtà, make può gestire la ricompilazione in un comando di tutti i file java obsoleti. Cambia la prima riga se non vuoi compilare tutti i file nella directory o vuoi un ordine specifico ...

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
Bello! Stavo cercando qualcosa del genere. Non è necessario utilizzare uno strumento di costruzione diverso per ogni lingua quando il classico universale funziona bene. Grazie!
rsp

17

Tutte le altre risposte sui meriti tecnici di ciascuno sono vere. Ante Mavenpotrebbe essere più adatto a Java che a creare, o come sottolinea Hank Gay, potrebbero non :)

Tuttavia, hai chiesto se è importante che Ant e Maven siano scritti in Java. Sebbene su StackOverflow non consideriamo tali pensieri (chiusi! Non relativi alla programmazione! Ecc.), DEL CORSO CHE È PARTE DELLA COSA. Su rotaie usiamo Rake, C dudes usa make e in Java usiamo Ant e Maven. Mentre è vero che gli sviluppatori Ant o Maven si prenderanno cura dello sviluppatore Java forse meglio di altri, c'è anche un'altra domanda: in cosa scrivi le attività Ant? Giava. Se sei uno sviluppatore Java, è una soluzione semplice.

Quindi sì, parte di esso è usare strumenti scritti nella lingua che stai attrezzando.


7
La formica sorse anche in un momento in cui la comunità Java era infatuata di XML. (Il che non vuol dire che XML non abbia un posto.)
Laurence Gonsalves il

3
@Laurence Gonsalves, è così vero. Ma per favore, non parliamo di mode qui su SO :) All'epoca insegnavo a Java dev, e TUTTO era XML. Ora è ancora XML, ma a nessuno importa.
Dan Rosenstark,

1
Il commento sugli utensili è interessante. makeproviene da un background UNIX, quindi gli strumenti vengono eseguiti scrivendo utili utility compatte e pipeline insieme. Questo è il motivo per cui la maggior parte delle cuciture viene effettuata usando i comandi di shell.
D.Shawley,

2
@D. Shawley, tutto vero riguardo ai makepiccoli programmi di utilità Unix. Anche GIT è figlio di quel processo. Su una nota personale, non direi che non è meglio. Ma è un enorme cambiamento di paradigma per i programmatori Java. La formica è molto più consona al modo di pensare di Java.
Dan Rosenstark,

12

Ant e in seguito Maven sono stati progettati per risolvere alcuni mal di testa causati da Make(mentre ne creano di nuovi nel processo). È solo evoluzione.

... Poco dopo, diversi progetti Java open source hanno capito che Ant poteva risolvere i problemi che avevano con Makefile ....

Da http://ant.apache.org/faq.html#history

Sia che risolvano qualcosa o semplicemente creino un formato extra da imparare è un argomento soggettivo. La verità è che è praticamente la storia di ogni nuova invenzione: il creatore dice che risolve molti problemi e gli utenti originali dicono che sono virtù.

Il vantaggio principale che ha è la possibilità di integrarsi con Java.

Immagino che una storia simile sarebbe con, rakeper esempio.


4
Non è molto specifico. Quali mal di testa causati da make risolve Maven?
Laurence Gonsalves,

1
@Gonsalves: Beh, questo è uno degli aspetti soggettivi di ogni nuova tecnologia, il creatore dell'alternativa dice che risolve molti problemi e i creatori della tecnologia sostituita affermano che quelli non sono difetti ma virtù e così via. Penso che in questa particolare situazione sia stata l'integrazione java e la compilazione incrociata fuori dagli schemi
OscarRyz,

2
[Facendo riferimento alla tua modifica della risposta, non al tuo commento più recente] Ciò non spiega ancora quali problemi siano stati risolti, solo che la formica dei creatori afferma che i problemi sono stati risolti ...: - / La mia impressione è stata che la Formica originariamente creata per essere un'alternativa più semplice a Make. Nel corso del tempo, le persone hanno scoperto che mancavano cose e quindi hanno aggiunto funzionalità fino a quando Ant non è diventata tanto complessa quanto make, ma con binutils integrati (make si basa fortemente su strumenti esterni come cp, rm, ecc.) E ovviamente c'è la sintassi XML.
Laurence Gonsalves,

2
Sì, ma quando il meglio che il creatore di una nuova alternativa può fare è dire "questo risolve i problemi del vecchio" senza dire davvero quali siano questi problemi, non è così utile per coloro che considerano quale opzione usare. Ant risolve i problemi che ho con make, o risolve cose che non considero problemi mentre introduce nuovi problemi per me?
Laurence Gonsalves il

9

Uno dei principali problemi risolti da Maven (e dalle configurazioni Ant abilitate per Ivy) su make è la risoluzione automatica delle dipendenze e il download dei vasi di dipendenza.


6

Penso che la spiegazione più probabile sia che diversi fattori abbiano scoraggiato l'uso di make all'interno della comunità Java in un periodo critico di tempo (fine anni '90):

  1. Poiché Java comprende più piattaforme, i programmatori Java in generale non erano così abili negli strumenti Unix come i programmatori generalmente confinati in un ambiente Unix (ad esempio, programmatori C e Perl). Si noti che questo è IN GENERALE. Senza dubbio ci sono ed erano programmatori Java dotati di una profonda conoscenza di Unix.
  2. Di conseguenza erano meno abili nel creare e non sapevano come usarlo in modo efficace.
  3. Sebbene sia possibile scrivere un Makefile breve e semplice che compili Java in modo efficiente, è necessario prestare particolare attenzione in modo indipendente dalla piattaforma.
  4. Di conseguenza c'era un appetito per uno strumento di costruzione intrinsecamente indipendente dalla piattaforma.
  5. Fu in questo ambiente che furono creati Ant e successivamente Maven.

In breve, sebbene make sia sicuramente utilizzabile per progetti Java, c'è stato un momento di opportunità per renderlo lo strumento di costruzione Java di fatto. Quel momento è passato.


5

Rendere gli script tendenzialmente dipendenti dalla piattaforma. Java dovrebbe essere indipendente dalla piattaforma. Pertanto, avere un sistema di compilazione che funziona solo su una piattaforma per una base multi-piattaforma è un problema.


5

Risposta breve: Perché make non va bene. Anche sul fronte C si vedono spuntare molte alternative.

Risposta lunga: makepresenta diversi difetti che la rendono a malapena adatta per la compilazione di C e non adatta per la compilazione di Java. Puoi forzarlo a compilare Java, se lo desideri, ma ti aspetti di incorrere in problemi, alcuni dei quali non dispongono di una soluzione o soluzione alternativa adatta. Eccone alcuni:

Risoluzione delle dipendenze

makesi aspetta intrinsecamente che i file abbiano una dipendenza simile ad un albero, in cui un file è l'output di crearne altri. Questo già si ritorce contro in C quando si tratta di file header. makerichiede makeche venga generato un file di inclusione specifico per rappresentare la dipendenza di un file C dai suoi file di intestazione, quindi una modifica a quest'ultimo causerebbe la ricostruzione del precedente. Tuttavia, poiché il file C stesso non viene ricreato (semplicemente ricostruito), make spesso richiede di specificare il target come .PHONY. Fortunatamente, GCC supporta la generazione automatica di questi file.

In Java, la dipendenza può essere circolare e non esiste uno strumento per la generazione automatica delle dipendenze di classe in makeformato. antL' Dependattività può invece leggere direttamente il file di classe, determinare quali classi importa ed eliminare il file di classe se uno di essi non è aggiornato. Senza questo, qualsiasi dipendenza non banale potrebbe comportare la costrizione all'uso di build pulite ripetute, eliminando qualsiasi vantaggio derivante dall'uso di uno strumento di build.

Spazi nei nomi dei file

Mentre né Java né C incoraggiano l'uso di spazi nei nomi dei file del codice sorgente, in makequesto può essere un problema anche se gli spazi si trovano nel percorso del file. Considera, ad esempio, se il tuo codice sorgente esiste in C:\My Documents\My Code\program\src. Questo sarebbe abbastanza per rompersi make. Questo perché maketratta i nomi dei file come stringhe. anttratta i percorsi come oggetti speciali.

Scansione dei file per build

makerichiede l'impostazione esplicita di quali file devono essere creati per ogni destinazione. antconsente di specificare una cartella che deve essere scansionata automaticamente per i file di origine. Può sembrare una comodità minore, ma considera che in Java ogni nuova classe richiede un nuovo file. L'aggiunta di file al progetto può diventare una vera seccatura.

E il problema più grande con make:

make dipende da POSIX

Il motto di Java è "compilare una volta eseguito ovunque". Ma limitare tale compilazione ai sistemi basati su POSIX, in cui il supporto Java è in realtà il peggiore, non è l'intenzione.

Le regole di compilazione makesono essenzialmente piccoli bashscript. Anche se esiste una porta makeper Windows, affinché funzioni correttamente, deve essere abbinato a una porta di bash, che include un livello di emulazione POSIX per il file system.

Questo è disponibile in due varietà:

  1. MSYS che tenta di limitare la traduzione POSIX ai percorsi dei file e può quindi avere spiacevoli problemi quando si eseguono strumenti esterni non creati appositamente per esso.

  2. cygwinche fornisce un'emulazione POSIX completa. I programmi risultanti, tuttavia, tendono ancora a fare affidamento su quello strato di emulazione.

Per questo motivo, su Windows, lo strumento di compilazione standard non è nemmeno del maketutto, ma piuttosto MSBuild, che è anche uno strumento basato su XML, più vicino in linea di principio a ant.

Al contrario, antè costruito in Java, può essere eseguito ovunque e contiene strumenti interni, chiamati "task", per manipolare file ed eseguire comandi in modo indipendente dalla piattaforma. È sufficientemente versatile che puoi effettivamente divertirti a costruire un programma C in Windows usando antpiuttosto che usando make.

E un ultimo minore:

Anche i programmi C non usano make nativamente

Inizialmente potresti non accorgertene, ma i programmi C generalmente non vengono spediti con a Makefile. Sono spediti con un CMakeLists.txt, o uno bashscript di configurazione, che genera l'effettivo Makefile. Al contrario, l'origine di un programma Java creato usando antviene fornito con uno antscript pre-costruito. A Makefileè un prodotto di altri strumenti - Ecco quanto makenon è adatto per essere uno strumento di costruzione da solo. antè autonomo e si occupa di tutto il necessario per il processo di compilazione Java, senza ulteriori requisiti o dipendenze.

Quando si esegue antsu qualsiasi piattaforma, funziona (tm). Non puoi ottenerlo make. È incredibilmente dipendente dalla piattaforma e dalla configurazione.


4

A meno che io non sia nessuno, il presupposto che nessuno stia (usando) make per java è sbagliato.

"Gestione dei progetti con GNU Make" (disponibile sotto GFDL) contiene un capitolo completo dedicato all'utilizzo makecon i progetti Java.

Dato che contiene un lungo (e si spera giusto) elenco dei pro e dei contro dell'utilizzo di make anziché di altri strumenti che potresti voler dare un'occhiata lì. (vedi: http://oreilly.com/catalog/make3/book/ )


È un riassunto accurato? make (in vari gusti) è utilizzabile per Java, ma con qualche dolore. Formica e Maven (e jmake ?) Fanno alcune cose speciali di cui Java ha bisogno / mi piace, per rendere i progetti Java più veloci e facili da costruire. Possono anche essere utilizzati per un processo di compilazione più indipendente dalla piattaforma per progetti non Java, ma sono più ottimizzati per Java.
Phil Perry,

3

Ant è un miglioramento orientato alla configurazione XML rispetto a Makefile e Maven è un miglioramento dello strumento di creazione di dipendenza rispetto a Ant. Alcuni progetti usano tutti e tre. Penso che i progetti JDK usassero un mix di makefile e formica.


1

Un grande motivo è che sia Ant che Maven (e la maggior parte degli strumenti SCM, CI e IDE mirati a Java) sono scritti in Java da / per gli sviluppatori Java. Ciò semplifica l'integrazione nel proprio ambiente di sviluppo e consente ad altri strumenti come i server IDE e CI di integrare parti delle librerie ant / maven all'interno dell'infrastruttura di compilazione / distribuzione.


1

Una volta ho lavorato a un progetto Java che utilizzava gmake. Il mio ricordo è confuso ma IIRC ha avuto difficoltà a gestire la struttura della directory dei pacchetti che javac si aspetta. Ricordo anche che costruire file JAR era una seccatura a meno che tu non avessi qualcosa di banale.


1

ApacheAnt non è niente come Make. Make riguarda la descrizione delle dipendenze tra i file e come creare i file. La formica riguarda le dipendenze tra "compiti", ed è davvero un modo per incollare insieme gli script di compilazione.

ti può aiutare AntVsMake


Mi piacerebbe davvero sapere le ragioni dei voti negativi.
hagello,

0

Ant e Maven affrontano il grafico delle dipendenze di build e la sua gestione da una visione più "moderna" ... Ma come dice Oscar, hanno creato i loro problemi mentre cercavano di affrontare i vecchi problemi con make.


0

Non ho mai usato GNU Make per progetti Java, ma usavo jmk . Purtroppo non è stato aggiornato dal 2002.

Aveva alcune funzionalità specifiche di Java ma era abbastanza piccolo da essere incluso nel tarball di origine senza aumentarne significativamente le dimensioni.

Oggi suppongo che qualsiasi sviluppatore Java con cui condivido il codice abbia installato Ant.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.