Pourquoi personne n'utilise make for Java?

162

Presque tous les projets Java que j'ai vus utilisent Maven ou Ant. Ce sont de bons outils et je pense que n'importe quel projet peut les utiliser. Mais qu'est-il arrivé à faire ? Il est utilisé pour une variété de projets non Java et peut facilement gérer Java. Bien sûr, vous devez télécharger make.exe si vous utilisez Windows, mais Ant et Maven ne sont pas non plus fournis avec le JDK.

Y a-t-il un défaut fondamental avec make lorsqu'il est utilisé avec Java? Est-ce simplement parce que Ant et Maven sont écrits en Java?

Utilisateur1
la source
37
Si vous déplacez des éléments et faites plus que simplement invoquer le compilateur (et même alors), les éléments spécifiques à la plate-forme deviennent très difficiles à gérer make. Et avoir un makefile qui ne fonctionne que sur un seul système n'est pas très agréable pour un langage multiplateforme.
Joey
En passant, Gradle est un nouvel acteur dans l'espace Java, tout comme Gant (dans une moindre mesure). Maven ou Ant est une fausse dichotomie.
Michael Easter
@Michael Easter, la fausse dichotomie serait Maven / Ant vs Make. La vraie dichotomie, si je vous lis bien, serait Gradle / Maven / Gant / Ant vs Make. Mais c'est un peu difficile à dire :)
Dan Rosenstark

Réponses:

192

Le problème fondamental avec Make et Java est que Make fonctionne sur le principe que vous avez spécifié une dépendance, puis une règle pour résoudre cette dépendance.

Avec le C de base, qui typiquement "pour convertir un fichier main.c en fichier main.o, exécutez" cc main.c ".

Vous pouvez le faire en java, mais vous apprenez rapidement quelque chose.

Surtout que le compilateur javac est lent à démarrer.

La différence entre:

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

et

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

est la nuit et le jour.

Exacerbez cela avec des centaines de cours, et cela devient intenable.

Ensuite, vous combinez cela avec le fait que java a tendance à être organisé en groupes de fichiers dans des répertoires, contre C et d'autres qui tendent vers une structure plus plate. Make n'a pas beaucoup de support direct pour travailler avec des hiérarchies de fichiers.

Make n'est pas non plus très efficace pour déterminer quels fichiers sont obsolètes, au niveau de la collection.

Avec Ant, il passera en revue et résumera tous les fichiers obsolètes, puis les compilera en une seule fois. Make appellera simplement le compilateur java sur chaque fichier individuel. Ne pas faire cela nécessite suffisamment d'outils externes pour vraiment montrer que Make n'est pas tout à fait à la hauteur de la tâche.

C'est pourquoi des alternatives comme Ant et Maven ont surgi.

Will Hartung
la source
6
Donc, pour utiliser make dans un énorme projet Java, il serait nécessaire de maintenir une liste de tous les fichiers .java modifiés et d'appeler javac à la fin? Cela me semble loin d'être idéal. C'est la meilleure réponse que j'ai vue jusqu'à présent.
User1
32
J'aime cela. Essentiel, vous dites que Ant était nécessaire pour traiter le fait que javac est trop lent.
cmcginty
25
Non, Javac n'est pas lent si vous l'utilisez tel qu'il a été conçu pour être utilisé. C'est juste lent si vous l'utilisez pour compiler un fichier à la fois.
Stephen C
7
@Casey javac n'est pas trop lent. La machine virtuelle Java est trop lente pour démarrer.
Thorbjørn Ravn Andersen
7
GNU Make a au moins la $?variable automatique qui s'étend à "tous les prérequis qui sont plus récents que la cible". Il existe également la fonctionnalité de règles de modèle avec plusieurs cibles qui n'exécuteraient la recette qu'une seule fois pour mettre à jour tous les .classfichiers. Combinez cela avec une utilisation intelligente des fonctions fichier / texte comme $(wildcard), $(shell), $(eval)et vous pouvez apprendre à votre makefile pour découvrir des cibles de construction dispersés à travers votre mise en page d'annuaire.
Tanz87
33

Le vénérable makeprogramme gère assez bien les langages compilés séparément comme C et C ++. Vous compilez un module, il utilise #includepour extraire le texte d'autres fichiers d'inclusion et écrit un seul fichier objet en sortie. Le compilateur est vraiment un système un par un, avec une étape de liaison distincte pour lier les fichiers objets dans un binaire exécutable.

Cependant, en Java, le compilateur doit en fait compiler d' autres classes avec lesquelles vous importez import. Bien qu'il soit possible d'écrire quelque chose qui génère toutes les dépendances nécessaires à partir du code source Java, afin de makecréer des classes dans le bon ordre une par une, cela ne gère toujours pas les cas tels que les dépendances circulaires.

Le compilateur Java peut également être plus efficace en mettant en cache les résultats compilés d'autres classes tout en compilant d'autres classes qui dépendent des résultats de celles déjà compilées. Ce type d'évaluation automatique des dépendances n'est pas vraiment possible avec makeseul.

Greg Hewgill
la source
7
Cela semble être plus une réponse make versus javac qu'une réponse make versus ant / maven. Sur la base de votre réponse, pourquoi quelqu'un ne pourrait-il pas simplement utiliser make + javac (en donnant à javac un paquet entier ou un "module" à la fois, de sorte que les dépendances circulaires sont cachées à make)? Une fourmi ou un maven apporteraient-ils des avantages à cette approche?
Laurence Gonsalves
1
@Laurence: Vous pouvez donner à javac un paquet entier à la fois, mais ensuite il recompilera tout dans ce paquet (puisque c'est ce que vous lui avez dit de faire). Il est vrai que le compilateur java est assez rapide, mais il est encore plus rapide si vous le laissez déterminer quelles classes sont le minimum nécessaire pour recompiler après avoir changé quelque chose.
Greg Hewgill
Voulez-vous dire à javac de ne compiler que votre classe «principale», puis de lui faire construire automatiquement les éléments dont il dépend? La dernière fois, j'ai vérifié (certes, probablement en 1.4) qui était horriblement peu fiable. -Xdepend était légèrement meilleur (mais plus lent et toujours cassé), et ils ont supprimé cet indicateur dans la version 1.3.
Laurence Gonsalves
4
De plus, cela n'explique toujours pas pourquoi j'utiliserais Ant ou Maven plutôt que juste du javac pur ...
Laurence Gonsalves
28

La question se fonde sur une hypothèse erronée: un nombre non négligeable de développeurs ne utilisation make. Voir Outils de construction Java: Ant vs Maven . Quant à savoir pourquoi un développeur ne l' utiliserait pasmake : de nombreux développeurs ne l'ont jamais utilisé make, ou l'ont utilisé et l'ont détesté avec un feu qui brûle plus de mille soleils. À ce titre, ils utilisent des outils alternatifs.

Hank Gay
la source
10
Nous l'utilisons, et le feu est plus chaud que mille et un soleils.
recycle le
4
@reccles: Est-ce juste de la haine envers l'ingénierie de construction ou la fabrication elle-même? Comment Ant, Maven ou autre serait-il meilleur (c'est-à-dire faire un mauvais outil pour sa classe)?
User1
5
@ User1 makea beaucoup de "fonctionnalités" qui peuvent avoir un sens quand il a été écrit, mais qui sont maintenant plus comme des bogues, par exemple, vous devez utiliser un caractère TAB, pas des espaces, à certains endroits. Ce genre de chose ne dérange probablement pas les gens qui ont vraiment de l'expérience make, mais cela nous rend fous.
Hank Gay
4
@HankGuy: laissez votre éditeur se soucier de ce détail. Si votre éditeur ne peut pas gérer correctement les paramètres d'espace de tabulation <->, procurez-vous un nouvel éditeur et vous serez beaucoup plus heureux. Mais vous avez raison de dire que de nombreuses fonctionnalités sont obsolètes, comme la façon dont les dépendances dynamiques sont gérées ( make dependn'importe qui?)
D.Shawley
3
@ User1 C'est l'échelle du projet que nous construisons. Nous avons un membre du personnel à plein temps qui gère les fichiers make et les dépendances de construction. Ayant utilisé maven, je l'ai trouvé plus facile à gérer. Cela dit, maven n'était pas parfait non plus. Rien n'est plus exaspérant que d'essayer de déterminer quel paramètre XML est nécessaire pour faire une construction légèrement différente de la configuration prescrite.
recycle le
28

En fait, make peut gérer la recompilation en une seule commande de tous les fichiers java obsolètes. Modifiez la première ligne si vous ne souhaitez pas compiler tous les fichiers du répertoire ou si vous souhaitez un ordre spécifique ...

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+=$$<)
user1251840
la source
4
Agréable! Je cherchais quelque chose comme ça. Pas besoin d'utiliser un outil de construction différent pour chaque langue lorsque le classique universel fonctionne correctement. Merci!
rsp
17

Toutes les autres réponses sur les mérites techniques de chacun sont vraies. Antet Mavenpeuvent être mieux adaptés à Java qu'à make, ou comme le souligne Hank Gay, ils peuvent ne pas l'être :)

Cependant, vous avez demandé s'il était important que Ant et Maven soient écrits en Java. Bien que sur StackOverflow, nous ne considérions pas de telles pensées (fermées! Non liées à la programmation! Etc.), BIEN SÛR, CELA FAIT PARTIE DE LA CHOSE. Sur les rails, nous utilisons Rake, les mecs C utilisent make, et en Java, nous utilisons Ant et Maven. S'il est vrai que les développeurs Ant ou Maven s'occuperont peut-être mieux du développeur Java que d'autres, il y a aussi une autre question: dans quoi écrivez-vous les tâches Ant? Java. Si vous êtes un développeur Java, c'est une solution facile.

Donc oui, une partie de cela consiste à utiliser des outils écrits dans la langue que vous utilisez.

Dan Rosenstark
la source
7
Ant est également apparu à un moment où la communauté Java était entichée de XML. (Ce qui ne veut pas dire que XML n'a pas de place.)
Laurence Gonsalves
3
@Laurence Gonsalves, c'est tellement vrai. Mais s'il vous plaît, nous ne parlons pas de modes ici sur SO :) J'enseignais Java dev à l'époque, et TOUT était XML. Maintenant, c'est toujours du XML, mais personne ne s'en soucie.
Dan Rosenstark
1
Le commentaire sur l'outillage est intéressant. makevient d'un arrière-plan UNIX, donc l'outillage se fait en écrivant des utilitaires compacts utiles et en les regroupant. C'est pourquoi la plupart des assemblages sont effectués à l'aide de commandes shell.
D.Shawley
2
@RÉ. Shawley, tout est vrai en ce qui concerne makeet les petits utils Unix. GIT est également un enfant de ce processus. Sur une note personnelle, je ne dirais pas que ce n'est pas mieux. Mais c'est un énorme changement de paradigme pour les programmeurs Java. Ant est beaucoup plus conforme aux modes de pensée Java.
Dan Rosenstark
12

Ant et plus tard Maven ont été conçus pour résoudre certains maux de tête causés par Make(tout en en créant de nouveaux dans le processus). C'est juste une évolution.

... Peu de temps après, plusieurs projets Java open source ont réalisé qu'Ant pouvait résoudre les problèmes qu'ils avaient avec Makefiles ...

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

Qu'ils résolvent quoi que ce soit ou qu'ils créent simplement un format supplémentaire pour apprendre est un sujet subjectif. La vérité est que c'est à peu près l'histoire de chaque nouvelle invention: le créateur dit que cela résout beaucoup de problèmes et les utilisateurs originaux disent que ce sont des vertus.

Son principal avantage est la possibilité de s'intégrer avec java.

Je suppose qu'une histoire similaire serait avec rakepar exemple.

OscarRyz
la source
4
Ce n'est pas très précis. Quels maux de tête provoqués par Make Maven résout-il?
Laurence Gonsalves
1
@Gonsalves: Eh bien, c'est l'un des aspects subjectifs de chaque nouvelle technologie, le créateur de l'alternative dit qu'elle résout beaucoup de problèmes et les créateurs de la technologie remplacée disent que ce ne sont pas des défauts mais des vertus, etc. Je pense que dans cette situation particulière, il y avait l'intégration java et la compilation croisée hors de la boîte
OscarRyz
2
[Se référant à votre modification de réponse, pas à votre commentaire le plus récent] Cela n'explique toujours pas quels problèmes ont été résolus, seulement que les créateurs affirment que les problèmes ont été résolus ...: - / J'ai l'impression que Ant a été créé à l'origine pour être une alternative plus simple à Make. Au fil du temps, les gens ont constaté qu'il manquait des éléments et ont donc ajouté des fonctionnalités jusqu'à ce que Ant devienne aussi complexe que make, mais avec binutils intégré (make repose fortement sur des outils externes tels que cp, rm, etc.), et bien sûr, il y a la syntaxe XML.
Laurence Gonsalves
2
Oui, mais le meilleur que le créateur d'une nouvelle alternative puisse faire est de dire «cela résout les problèmes de l'ancienne» sans vraiment dire quels sont ces problèmes, ce n'est pas si utile pour ceux qui envisagent quelle option utiliser. Est-ce que Ant résout les problèmes que j'ai avec make ou est-ce que cela résout des choses que je ne considère pas comme des problèmes tout en introduisant de nouveaux problèmes pour moi?
Laurence Gonsalves
9

L'un des principaux problèmes résolus par Maven (et les configurations Ant compatibles Ivy) sur make est la résolution automatisée des dépendances et le téléchargement de vos fichiers JAR de dépendances.

Ophidien
la source
6

Je pense que l'explication la plus probable est que plusieurs facteurs ont découragé l'utilisation de make au sein de la communauté Java dans une période critique (fin des années 1990):

  1. Parce que Java englobe plusieurs plates-formes, les programmeurs Java en général n'étaient pas aussi compétents avec les outils Unix que les programmeurs généralement confinés à un environnement Unix (par exemple, les programmeurs C et Perl). Notez que c'est EN GÉNÉRAL. Sans aucun doute, il y a et étaient des programmeurs Java doués avec une compréhension approfondie d'Unix.
  2. Par conséquent, ils étaient moins habiles à faire et ne savaient pas comment utiliser le make efficacement.
  3. Bien qu'il soit possible d'écrire un Makefile court et simple qui compile Java efficacement, une attention particulière est nécessaire pour le faire d'une manière indépendante de la plate-forme.
  4. Par conséquent, il y avait un appétit pour un outil de construction intrinsèquement indépendant de la plate-forme.
  5. C'est dans cet environnement qu'Ant et plus tard Maven ont été créés.

En bref, si make peut très certainement être utilisé pour les projets Java, il y a eu un moment opportun pour en faire l'outil de construction Java de facto. Ce moment est passé.

David A. Ventimiglia
la source
5

Les scripts ont tendance à être intrinsèquement dépendants de la plate-forme. Java est censé être indépendant de la plate-forme. Par conséquent, avoir un système de construction qui ne fonctionne que sur une seule plate-forme pour une base source multi-plate-forme est un peu un problème.

Brian Fox
la source
5

Réponse courte: parce que ce maken'est pas bon. Même sur le front C, vous voyez apparaître de nombreuses alternatives.

Réponse longue: makea plusieurs défauts qui le rendent à peine adapté à la compilation C, et inadapté du tout à la compilation Java. Vous pouvez le forcer à compiler Java, si vous le souhaitez, mais attendez-vous à rencontrer des problèmes, dont certains n'ont pas de solution ou de contournement appropriée. Voici quelques-uns:

Résolution des dépendances

makes'attend par nature à ce que les fichiers aient une dépendance semblable à une arborescence les uns sur les autres, dans lequel un fichier est le résultat de la construction de plusieurs autres. Cela se retourne déjà en C lors du traitement des fichiers d'en-tête. makenécessite qu'un makefichier d'inclusion spécifique soit généré pour représenter la dépendance d'un fichier C sur ses fichiers d'en-tête, donc une modification de ce dernier entraînerait la reconstruction du fichier antérieur. Cependant, comme le fichier C lui-même n'est pas recréé (simplement reconstruit), make nécessite souvent de spécifier la cible comme .PHONY. Heureusement, GCC prend en charge la génération automatique de ces fichiers.

En Java, la dépendance peut être circulaire et il n'y a pas d'outil pour générer automatiquement des dépendances de classe au makeformat. antLa Dependtâche de la tâche peut, à la place, lire directement le fichier de classe, déterminer les classes qu'elle importe et supprimer le fichier de classe si l'une d'entre elles est obsolète. Sans cela, toute dépendance non triviale peut vous obliger à utiliser des générations propres répétées, supprimant tout avantage lié à l'utilisation d'un outil de génération.

Espaces dans les noms de fichiers

Bien que ni Java ni C n'encouragent l'utilisation d'espaces dans vos noms de fichiers de code source, makecela peut poser problème même si les espaces sont dans le chemin du fichier. Considérez, par exemple, si votre code source existe dans C:\My Documents\My Code\program\src. Ce serait suffisant pour casser make. En effet, makeles noms de fichiers sont traités comme des chaînes. anttraite les tracés comme des objets spéciaux.

Analyse des fichiers pour la construction

makenécessite de définir explicitement les fichiers à créer pour chaque cible. antpermet de spécifier un dossier qui doit être analysé automatiquement pour les fichiers source. Cela peut sembler une commodité mineure, mais considérez qu'en Java, chaque nouvelle classe nécessite un nouveau fichier. L'ajout de fichiers au projet peut devenir très fastidieux.

Et le plus gros problème avec make:

make dépend de POSIX

La devise de Java est "compiler une fois exécuté partout". Mais limiter cette compilation aux systèmes basés sur POSIX, dans lesquels le support Java est en fait le pire, n'est pas l'intention.

Les règles de construction dans makesont essentiellement de petits bashscripts. Même s'il existe un port de makevers Windows, pour qu'il fonctionne correctement, il doit être associé à un port de bash, qui comprend une couche d'émulation POSIX pour le système de fichiers.

Cela se décline en deux variétés:

  1. MSYS qui tente de limiter la traduction POSIX aux chemins de fichiers, et peut donc avoir des pièges désagréables lors de l'exécution d'outils externes qui ne sont pas spécialement conçus pour cela.

  2. cygwinqui fournit une émulation POSIX complète. Les programmes résultants, cependant, ont tendance à toujours s'appuyer sur cette couche d'émulation.

Pour cette raison, sous Windows, l'outil de construction standard n'est même pas makedu tout, mais plutôt MSBuild, qui est également un outil basé sur XML, plus proche en principe de ant.

En revanche, il antest construit en Java, peut s'exécuter partout et contient des outils internes, appelés «tâches», pour manipuler des fichiers et exécuter des commandes d'une manière indépendante de la plate-forme. Il est suffisamment polyvalent pour que vous puissiez en fait avoir plus de facilité à créer un programme C dans Windows en utilisant antqu'avec make.

Et un dernier mineur:

Même les programmes C n'utilisent pas make nativement

Vous ne le remarquerez peut-être pas initialement, mais les programmes C ne sont généralement pas livrés avec un fichier Makefile. Ils sont livrés avec un CMakeLists.txt, ou un bashscript de configuration, qui génère le fichier réel Makefile. En revanche, la source d'un programme Java construit en utilisant antest livrée avec un antscript pré-construit. A Makefileest un produit d'autres outils - C'est à quel point il makene convient pas d'être un outil de construction à lui seul. antest autonome et traite tout ce dont vous avez besoin pour votre processus de construction Java, sans aucune exigence ou dépendance supplémentaire.

Lorsque vous exécutez antsur n'importe quelle plate-forme, cela fonctionne (tm). Vous ne pouvez pas obtenir cela avec make. Cela dépend incroyablement de la plate-forme et de la configuration.

SlugFiller
la source
4

Sauf si je ne suis personne, l'hypothèse que personne n'utilise (mal) make for java est fausse.

"Gérer des projets avec GNU Make" (disponible sous GFDL) contient un chapitre complet dédié à l'utilisation makeavec des projets java.

Comme il contient une longue liste (et j'espère juste) des avantages et des inconvénients de l'utilisation de make au lieu d'autres outils, vous voudrez peut-être y jeter un coup d'œil. (voir: http://oreilly.com/catalog/make3/book/ )

Mikyra
la source
Est-ce un résumé précis? make (dans différentes saveurs) est utilisable pour Java, mais avec une certaine douleur. Ant et Maven (et jmake ?) Font des choses spéciales dont Java a besoin / aime, pour rendre les projets Java plus rapides et plus faciles à construire. Ils peuvent également être utilisés pour un processus de construction plus indépendant de la plate-forme pour les projets non Java, mais sont plus adaptés pour Java.
Phil Perry
3

Ant est une amélioration orientée configuration XML par rapport à Makefiles et Maven est une amélioration de l'outil de création de dépendances par rapport à Ant. Certains projets utilisent les trois. Je pense que les projets JDK utilisaient un mélange de makefiles et de fourmi.

Brun de Berlin
la source
1

L'une des principales raisons est que Ant et Maven (et la plupart des outils SCM, CI et IDE ciblés par Java) sont écrits en java par / pour les développeurs Java. Cela simplifie l'intégration dans votre environnement de développement et permet à d'autres outils tels que les serveurs IDE et CI d'intégrer des parties des bibliothèques ant / maven dans l'infrastructure de construction / déploiement.

Chris Nava
la source
1

Il était une fois, j'ai travaillé sur un projet Java utilisant gmake. Mon souvenir est flou mais IIRC nous avons eu du mal à gérer la structure de répertoires de paquets attendue par javac. Je me souviens également que la création de fichiers JAR était un problème à moins que vous n'ayez quelque chose de trivial.


la source
1

ApacheAnt ne ressemble en rien à Make. Make consiste à décrire les dépendances entre les fichiers et à créer des fichiers. Ant concerne les dépendances entre les «tâches», et est en fait plus un moyen de coller des scripts de construction ensemble.

cela peut vous aider AntVsMake

Venky Vungarala
la source
J'aimerais vraiment connaître les raisons des votes négatifs.
hagello
0

Ant et Maven abordent le graphe de dépendance de build et sa gestion d'un point de vue plus «moderne» ... Mais comme le dit Oscar, ils ont créé leurs propres problèmes en essayant de résoudre les anciens problèmes avec make.

John Weldon
la source
0

Je n'ai jamais utilisé GNU Make pour les projets Java, mais j'avais l'habitude d'utiliser jmk . Malheureusement, il n'a pas été mis à jour depuis 2002.

Il avait des fonctionnalités spécifiques à Java mais était suffisamment petit pour être inclus dans votre archive tar source sans augmenter considérablement sa taille.

De nos jours, je suppose que tout développeur Java avec lequel je partage du code a Ant installé.

finnw
la source