Почему никто не использует make для Java?
Вопрос
Практически каждый Java-проект, который я видел, использует либо Maven, либо Ant.Это прекрасные инструменты, и я думаю, что их может использовать практически любой проект.Но что вообще случилось с сделать?Он используется для множества проектов, отличных от Java, и может легко обрабатывать Java.Конечно, вам нужно загрузить make.exe если вы используете Windows, но Ant и Maven также не поставляются с JDK.
Есть ли какой-то фундаментальный недостаток в make при использовании с Java?Это только потому, что Ant и Maven написаны на Java?
Решение
Фундаментальная проблема с Make и Java заключается в том, что Make работает исходя из предпосылки, что вы должны указать зависимость, а затем правило для разрешения этой зависимости.
С basic 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.
Другие советы
Достопочтенный make
программа достаточно хорошо обрабатывает отдельно скомпилированные языки, такие как C и C ++.Вы компилируете модуль, он использует #include
извлекает текст из других включенных файлов и записывает один объектный файл в качестве выходных данных.Компилятор в значительной степени представляет собой одноразовую систему с отдельным этапом компоновки для привязки объектных файлов к исполняемому двоичному файлу.
Однако в Java компилятор должен фактически скомпилировать другие классы, которые вы импортируете с помощью import
.Хотя можно было бы написать что-то, что сгенерировало бы все необходимые зависимости из исходного кода Java, так что make
если бы классы создавались в правильном порядке по одному за раз, это все равно не обрабатывало бы такие случаи, как циклические зависимости.
Компилятор Java также может быть более эффективным, кэшируя скомпилированные результаты других классов при компиляции дополнительных классов, которые зависят от результатов уже скомпилированных.Такого рода автоматическая оценка зависимостей на самом деле невозможна с make
один.
Вопрос основан на неверном предположении:нетривиальное количество разработчиков делай использование make
.Видишь Инструменты сборки Java:Муравей противМавен.Что касается того, почему разработчик не стал бы использование make
:многие разработчики либо никогда не использовали make
, или использовал его и возненавидел с огнем, который горит жарче тысячи солнц.Таким образом, они используют альтернативные инструменты.
На самом деле, make может обрабатывать перекомпиляцию одной командой всех устаревших файлов java.Измените первую строку, если вы не хотите компилировать все файлы в каталоге или хотите установить определенный порядок...
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+=$$<)
Все остальные ответы о технических достоинствах каждого из них верны. Ant
и Maven
могут лучше подходить для Java, чем make, или, как указывает Хэнк Гей, они могут и не подходить :)
Однако вы спросили, имеет ли значение, что Ant и Maven написаны на Java.Хотя в StackOverflow мы не рассматриваем такие мысли (закрыто!не связанный с программированием!и т.д.), КОНЕЧНО, ЭТО ЧАСТЬ ДЕЛА.В rails мы используем Rake, ребята из C используют make, а в Java мы используем Ant и Maven.Хотя это правда, что разработчики Ant или Maven будут присматривать за разработчиком Java, возможно, лучше, чем другие, возникает и другой вопрос:на чем вы пишете муравьиные задачи?Ява.Если вы разработчик Java, это легко подойдет.
Так что да, часть этого заключается в использовании инструментов, написанных на том языке, на котором вы работаете.
Ant и более поздние версии Maven были разработаны для решения некоторых головных болей, вызванных Make
(создавая новые в процессе ) Это просто эволюция.
...Вскоре после этого несколько проектов Java с открытым исходным кодом поняли, что Ant может решить проблемы, которые у них были с Makefile....
От http://ant.apache.org/faq.html#history
Решают ли они что-нибудь или просто создают дополнительный формат для изучения - это субъективная тема.Правда в том, что это в значительной степени история каждого нового изобретения:Создатель говорит, что это решает множество проблем, а первоначальные пользователи говорят, что это достоинства.
Главное преимущество, которым он обладает, - это возможность интеграции с java.
Я предполагаю, что похожая история была бы с rake
например.
Одна из основных проблем, решаемых Maven (и Ant-настройками с поддержкой Ivy) поверх make, - это автоматическое разрешение зависимостей и загрузка ваших файлов зависимостей.
Я думаю, что наиболее вероятным объяснением является то, что несколько факторов препятствовали использованию make в сообществе Java в критический период времени (конец 1990-х):
- Поскольку Java охватывает множество платформ, Java-программисты в целом не были столь сведущи в инструментах Unix, как программисты, обычно ограниченные средой Unix (например, программисты на C и Perl).Обратите внимание, что это В ЦЕЛОМ.Без сомнения, есть и были одаренные Java-программисты с глубоким пониманием Unix.
- Следовательно, они были менее искусны в make и не знали, как эффективно использовать make.
- Хотя возможно написать короткий и простой Makefile, который эффективно компилирует Java, требуется особая осторожность, чтобы сделать это независимым от платформы способом.
- Следовательно, появился аппетит к встроенно независимому от платформы инструменту сборки.
- Именно в этой среде были созданы Ant и более поздний Maven.
Короче говоря, хотя make, безусловно, можно использовать для проектов Java, был момент, когда представилась возможность сделать его фактическим инструментом сборки Java.Этот момент прошел.
Сценарии Make, как правило, изначально зависят от платформы.Предполагается, что Java не зависит от платформы.Поэтому наличие системы сборки, которая работает только на одной платформе для мультиплатформенной исходной базы, является своего рода проблемой.
Если я не никто, предположение, что никто не использует make для java, неверно.
"Управление проектами с помощью GNU Make" (доступно в GFDL) содержит полную главу, посвященную использованию make
с java-проектами.
Поскольку он содержит длинный (и, надеюсь, справедливый) список плюсов и минусов использования make вместо других инструментов, возможно, вы захотите ознакомиться с ним.(см.: http://oreilly.com/catalog/make3/book/)
Короткий ответ:Потому что make
это нехорошо.Даже на C-фронте вы видите, как появляется множество альтернатив.
Длинный ответ: make
имеет несколько недостатков, которые делают его едва пригодным для компиляции C и вообще непригодным для компиляции Java.Вы можете принудительно скомпилировать Java, если хотите, но ожидайте столкнуться с проблемами, некоторые из которых не имеют подходящего решения или обходного пути.Вот несколько:
Разрешение зависимостей
make
по своей сути ожидает, что файлы будут иметь древовидную зависимость друг от друга, в которой один файл является результатом построения нескольких других.Это уже приводит к обратным результатам в C при работе с заголовочными файлами. make
требуется make
-конкретный включаемый файл, который должен быть сгенерирован для представления зависимости файла C от его файлов заголовков, поэтому изменение последнего приведет к перестройке предыдущего.Однако, поскольку сам файл C не создается заново (просто перестраивается), make часто требует указания целевого объекта как .PHONY
.К счастью, GCC поддерживает автоматическую генерацию этих файлов.
В Java зависимость может быть циклической, и в Java нет инструмента для автоматической генерации зависимостей классов make
формат. ant
's Depend
вместо этого task может напрямую прочитать файл класса, определить, какие классы он импортирует, и удалить файл класса, если какой-либо из них устарел.Без этого любая нетривиальная зависимость может привести к тому, что вы будете вынуждены использовать повторные чистые сборки, лишая вас любого преимущества использования инструмента сборки.
Пробелы в именах файлов
Хотя ни Java, ни C не поощряют использование пробелов в именах файлов вашего исходного кода, в make
это может быть проблемой, даже если в пути к файлу есть пробелы.Рассмотрим, например, существует ли ваш исходный код в C:\My Documents\My Code\program\src
.Этого было бы достаточно, чтобы сломать make
.Это происходит потому, что make
обрабатывает имена файлов как строки. ant
рассматривает пути как особые объекты.
Сканирование файлов для сборки
make
требуется явно указать, какие файлы должны быть созданы для каждой цели. ant
позволяет указать папку, которая должна автоматически проверяться на наличие исходных файлов.Это может показаться незначительным удобством, но учтите, что в Java для каждого нового класса требуется новый файл.Добавление файлов в проект может быстро стать большой проблемой.
И самая большая проблема с make
:
make зависит от POSIX
Девиз Java - "компилировать один раз, запускать везде".Но ограничивать эту компиляцию системами на основе POSIX, в которых поддержка Java на самом деле наихудшая, не входит в наши намерения.
Встроить правила в make
по существу, они малы bash
Скрипты.Даже несмотря на то, что существует порт make
для Windows, чтобы он работал должным образом, он должен быть связан с портом bash
, который включает в себя уровень эмуляции POSIX для файловой системы.
Это бывает двух видов:
MSYS
который пытается ограничить перевод POSIX путями к файлам и, следовательно, может иметь неприятные ошибки при запуске внешних инструментов, не созданных специально для него.cygwin
который обеспечивает полную эмуляцию POSIX.Однако результирующие программы, как правило, по-прежнему полагаются на этот уровень эмуляции.
По этой причине в Windows стандартный инструмент сборки даже не make
вообще, а скорее MSBuild
, который также является инструментом на основе XML, в принципе более близким к ant
.
По контрасту, ant
построен на Java, может запускаться везде и содержит внутренние инструменты, называемые "задачи", для работы с файлами и выполнения команд независимым от платформы способом.Он достаточно универсален, чтобы вам действительно было проще создавать программы на C в Windows с помощью ant
чем использовать make
.
И еще один, последний, незначительный:
Даже программы на C не используют make изначально
Возможно, поначалу вы этого не заметите, но программы на C обычно не поставляются с Makefile
.Они поставляются с CMakeLists.txt
, или a bash
сценарий настройки, который генерирует фактический Makefile
.Напротив, исходный код Java-программы, созданной с использованием ant
поставляется с ant
готовый сценарий.A Makefile
является продуктом других инструментов - Вот сколько make
непригоден для самостоятельной сборки. ant
является автономным и имеет дело со всем, что вам нужно для вашего процесса сборки Java, без каких-либо дополнительных требований или зависимостей.
Когда ты бежишь ant
на любой платформе это просто работает (tm).Ты не можешь получить это с помощью make
.Это невероятно зависит от платформы и конфигурации.
Ant - это усовершенствование, ориентированное на конфигурацию XML, по сравнению с Makefiles, а Maven - это усовершенствование инструмента построения зависимостей по сравнению с Ant.Некоторые проекты используют все три.Я думаю, что проекты JDK раньше использовали смесь makefile и ant.
Одна из главных причин заключается в том, что и Ant, и Maven (и большинство инструментов SCM, CI и IDE, ориентированных на Java) написаны на java разработчиками java / for java.Это упрощает интеграцию в вашу среду разработки и позволяет другим инструментам, таким как IDE и серверы CI, интегрировать части библиотек ant / maven в инфраструктуру сборки / развертывания.
Когда-то давно я работал над Java-проектом, в котором использовался gmake.Мои воспоминания смутны, но IIRC нам было трудно разобраться со структурой каталогов пакетов, которую ожидает javac.Я также помню, что создание JAR-файлов было непростой задачей, если только у вас не было чего-то тривиального.
ApacheAnt - это совсем не то, что Make.Make - это описание зависимостей между файлами и способов создания файлов.Ant - это о зависимостях между "задачами", и на самом деле это скорее способ склеивания сценариев сборки вместе.
это может помочь вам AntVsMake - Создать
Ant и Maven подходят к построению графика зависимостей и управлению им с более "современной" точки зрения...Но, как говорит Оскар, они создали свои собственные проблемы, пытаясь решить старые проблемы с помощью make.
Я никогда не использовал GNU Make для Java-проектов, но раньше я использовал jmk.К сожалению, он не обновлялся с 2002 года.
Он обладал некоторой функциональностью, специфичной для Java, но был достаточно мал, чтобы включить его в ваш исходный архив без существенного увеличения его размера.
В настоящее время я просто предполагаю, что у любого разработчика Java, с которым я делюсь кодом, установлен Ant.