web-dev-qa-db-fra.com

Pourquoi personne n'utilise make pour Java?

À peu près tous les projets Java que j'ai vus utilisent Maven ou Ant. Ce sont de bons outils et je pense que presque tous les projets peuvent les utiliser. Mais ce qui est arrivé à make ? 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 fournis avec le JDK.

Existe-t-il un défaut fondamental avec make utilisé avec Java? Est-ce juste parce que Ant et Maven sont écrits en Java?

149
User1

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

Avec C de base, cela "généralement" pour convertir un fichier main.c en un fichier main.o, exécutez "cc main.c".

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

Généralement, 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

c'est nuit et jour.

Exacerbez cela avec des centaines de classes 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, par opposition à C et d’autres qui tendent vers une structure plus plate. Make n’a pas beaucoup de soutien direct pour travailler avec des hiérarchies de fichiers.

Make n’est pas 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 périmés, puis les compilera en une fois. Make appellera simplement le compilateur Java sur chaque fichier individuel. Avoir fait NOT NE nécessite pas assez d'outils externes pour vraiment montrer que Make n'est pas à la hauteur de la tâche.

C'est pourquoi des alternatives comme Ant et Maven se sont levées.

180
Will Hartung

Le vénérable programme make gère relativement bien les langages compilés séparément, tels que C et C++. Vous compilez un module, il utilise #include pour extraire le texte des autres fichiers inclus et écrit un fichier objet unique en sortie. Le compilateur est un système un à un, avec une étape de liaison distincte pour lier les fichiers objet à un binaire exécutable.

Cependant, en Java, le compilateur doit réellement compiler autres classes que vous importez avec 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, de sorte que make puisse construire les classes dans le bon ordre, un à la fois, ne traiterait 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. Cette sorte d’évaluation automatique de la dépendance n’est pas vraiment possible avec make seul.

31
Greg Hewgill

La question est basée sur une hypothèse incorrecte: un nombre non négligeable de développeurs ne utilisent make. Voir Outils de génération Java: Ant vs. Maven . Pourquoi un développeur n’utiliserait-il pas make: de nombreux développeurs n’ont jamais utilisé make, ou l’ont utilisé et l'a détesté avec un feu qui brûle plus chaud que mille soleils. En tant que tels, ils utilisent des outils alternatifs.

28
Hank Gay

En fait, make peut gérer la recompilation en une seule commande parmi tous les fichiers obsolètes Java. Modifiez la première ligne si vous ne voulez 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+=$$<)
21
user1251840

Toutes les autres réponses sur les mérites techniques de chacune sont vraies. Ant et Maven conviendront peut-être mieux à Java que make, ou, comme le souligne Hank Gay, ils ne le feront peut-être pas :)

Cependant, vous avez demandé s'il importait 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.), C’est bien sûr une partie de la chose. Sur Rails, nous utilisons Rake, C d’utiliser make, et en Java, nous utilisons Ant et Maven. Même s’il est vrai que les développeurs Ant ou Maven s’occuperont de vous le Java peut-être meilleur que d'autres, il y a aussi une autre question: que rédigez-vous dans Ant? Java? Si vous êtes un développeur Java, c'est un ajustement facile.

Donc, une partie de cela consiste à utiliser des outils écrits dans le langage que vous utilisez.

17
Dan Rosenstark

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). Il s’agit simplement d’une évolution.

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

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

Qu'ils résolvent n'importe quoi ou créent simplement un format supplémentaire à 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 d'origine disent que ce sont des vertus.

Son principal avantage est la possibilité de s’intégrer à Java.

Je suppose qu'un historique similaire serait avec rake par exemple.

12
OscarRyz

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

9
Ophidian

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 au cours d'une période critique (la fin des années 1990):

  1. Parce que Java englobe plusieurs plates-formes, les programmeurs Java n'étaient pas aussi adeptes des outils Unix que les programmeurs généralement confinés à un environnement Unix (par exemple, C et Perl programmeurs). Notez que c’est EN GÉNÉRAL. Sans aucun doute, il y a et ont été doués Java avec une connaissance approfondie de Unix.
  2. En conséquence, ils étaient moins habiles à fabriquer et ne savaient pas comment utiliser efficacement.
  3. Bien qu'il soit possible d'écrire un Makefile court et simple compilant Java efficacement, des efforts supplémentaires sont nécessaires pour le faire de 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 que Ant et plus tard Maven ont été créés.

En bref, bien que make puisse très certainement être utilisé pour les projets Java, il y avait un moment opportun pour en faire de facto Java de génération. Ce moment a passé.

6

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

5
Brian Fox

Réponse courte: Parce que make n'est pas bon. Même sur le front C, de nombreuses alternatives apparaissent.

Réponse longue: make présente plusieurs failles qui le rendent à peine utilisable pour la compilation en C et inadapté à la compilation en Java. Vous pouvez le forcer à compiler Java, si vous le souhaitez, mais attendez-vous à rencontrer des problèmes, dont certains ne proposent pas de solution ou de solution de contournement appropriée. Voici quelques-uns:

Résolution de dépendance

make s'attend de manière inhérente à ce que les fichiers aient une dépendance d'arborescence, dans laquelle un fichier est le résultat de la création de plusieurs autres. Cela se retourne déjà en C lorsqu'il s'agit de fichiers d'en-tête. make nécessite la génération d'un fichier d'inclusion spécifique à make afin de représenter la dépendance d'un fichier C sur ses fichiers d'en-tête. Ainsi, une modification de ce dernier entraînerait la reconstruction de la version antérieure. Cependant, comme le fichier C lui-même n'est pas recréé (simplement reconstruit), make nécessite souvent de spécifier la cible sous la forme .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’existe aucun outil permettant de générer automatiquement des dépendances de classe au format make. La tâche ant de Depend peut, au lieu de cela, lire directement le fichier de classe, déterminer les classes qu'elle importe et supprimer le fichier de classe si l'une d'elles est obsolète. Sans cela, toute dépendance non triviale peut vous obliger à utiliser plusieurs générations de nettoyage, supprimant ainsi 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 les noms de fichiers de votre code source, cela peut poser problème dans make même si les espaces sont dans le chemin du fichier. Considérons, par exemple, si votre code source existe dans C:\My Documents\My Code\program\src. Cela suffirait pour casser make. En effet, make considère les noms de fichiers comme des chaînes. ant traite les chemins comme des objets spéciaux.

Analyse des fichiers pour la construction

make nécessite de définir explicitement les fichiers à créer pour chaque cible. ant permet de spécifier un dossier à analyser automatiquement pour les fichiers source. Cela peut sembler une commodité mineure, mais considérez que dans 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 la prise en charge de Java est en réalité la pire, n’est pas l’intention.

Les règles de construction dans make sont essentiellement de petits scripts bash. Même s'il existe un port de make vers 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 vient en deux variétés:

  1. MSYS qui essaie 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 non conçus spécialement pour elle.

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

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

En revanche, ant est construit en Java, peut s’exécuter partout et contient des outils internes, appelés "tâches", permettant de manipuler des fichiers et d’exécuter des commandes indépendamment de la plate-forme. Il est suffisamment polyvalent pour que vous puissiez réellement créer plus facilement un programme C sous Windows avec ant plutôt qu'avec make.

Et un dernier mineur:

Même les programmes C n'utilisent pas make en natif

Vous ne le remarquerez peut-être pas initialement, mais les programmes C ne sont généralement pas livrés avec un Makefile. Ils sont livrés avec un script de configuration CMakeLists.txt Ou bash, qui génère la valeur réelle Makefile. En revanche, la source d'un programme Java construit à l'aide de ant est livrée avec un script ant pré-construit. Un Makefile est le produit d’autres outils - C’est à quel point make ne convient pas à lui seul. ant est autonome et traite de tout ce dont vous avez besoin pour votre processus de génération Java, sans aucune exigence ou dépendance supplémentaire.

Lorsque vous exécutez ant sur 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.

4
SlugFiller

À moins que je ne sois personne, je suppose que personne n’utilise (mal) make pour Java est faux.

"Gestion de projets avec GNU Make" (disponible sous GFDL)) contient un chapitre complet consacré à l'utilisation de make avec des projets Java.

Comme il contient une longue liste (et, espérons-le 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/ )

4
mikyra

Ant est une amélioration de la configuration XML par rapport aux Makefiles et Maven est un outil de génération 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 ant.

3
Berlin Brown

ApacheAnt ne ressemble en rien à Make. Make concerne la description des dépendances entre fichiers et la création de fichiers. Ant concerne les dépendances entre les "tâches" et constitue en réalité un moyen de coller des scripts de construction ensemble.

cela peut vous aider AntVsMake

1
Venky Vungarala

Il était une fois, je travaillais sur un projet Java qui utilisait gmake. Mon souvenir est flou, mais IIRC nous a eu du mal à gérer la structure de répertoires de paquets que javac attend. Je me souviens également de la construction de JAR fichiers était un problème, sauf si vous aviez quelque chose de trivial.

1
carej

L'une des principales raisons est que Ant et Maven (et la plupart des outils Java ciblés, SCM, CI et IDE) sont écrits en Java par/pour Java développeurs. Cela facilite 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.

1
Chris Nava

Ant et Maven abordent le graphe de dépendance de construction et sa gestion sous un angle plus "moderne" ... Mais, comme le dit Oscar, ils ont créé leurs propres problèmes en tentant de résoudre les anciens problèmes de make.

0
John Weldon

Je n'ai jamais utilisé GNU Make pour les projets Java, mais je l'utilisais auparavant jmk . =). Malheureusement, il n'a pas été mis à jour depuis 2002.

Il comportait des fonctionnalités spécifiques à Java mais était suffisamment petit pour être inclus dans votre archive source sans augmenter de manière significative sa taille.

De nos jours, je suppose que tout Java) avec lequel je partage le code a Ant installé.

0
finnw