Почему никто не использует make для Java? - PullRequest
149 голосов
/ 05 февраля 2010

Почти в каждом Java-проекте, который я видел, используется Maven или Ant. Они прекрасные инструменты, и я думаю, что любой проект может использовать их. Но что случилось с make ? Он используется для различных не-Java проектов и может легко обрабатывать Java. Конечно, вам нужно скачать make.exe, если вы используете Windows, но Ant и Maven также не поставляются с JDK.

Есть ли какой-то фундаментальный недостаток в make при использовании с Java? Это только потому, что Ant и Maven написаны на Java?

Ответы [ 17 ]

180 голосов
/ 05 февраля 2010

Основная проблема 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.

31 голосов
/ 05 февраля 2010

Достойная программа make достаточно хорошо обрабатывает отдельно скомпилированные языки, такие как C и C ++. Вы компилируете модуль, он использует #include для извлечения текста из других включаемых файлов и записывает один объектный файл в качестве вывода. Компилятор очень похож на систему за один раз, с отдельным шагом связывания для связывания объектных файлов в исполняемый двоичный файл.

Однако в Java компилятор должен скомпилировать других классов, которые вы импортируете с помощью import. Хотя можно было бы написать что-то, что сгенерировало все необходимые зависимости из исходного кода Java, так что make будет создавать классы в правильном порядке по одному, это все равно не будет обрабатывать такие случаи, как циклические зависимости. *

Компилятор Java также может быть более эффективным, кэшируя скомпилированные результаты других классов при компиляции других классов, которые зависят от результатов уже скомпилированных. Этот вид автоматической оценки зависимостей на самом деле невозможен только с make.

28 голосов
/ 05 февраля 2010

Вопрос основан на неверном предположении: нетривиальное число разработчиков do use make.См. Инструменты сборки Java: Ant vs. Maven .Что касается того, почему разработчик не использовал бы make: многие разработчики либо никогда не использовали make, либо использовали его и ненавидели его с огнем, который горит сильнее тысячи солнц.Поэтому они используют альтернативные инструменты.

20 голосов
/ 06 декабря 2013

На самом деле, 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+=$$<)
17 голосов
/ 05 февраля 2010

Все остальные ответы о технических достоинствах каждого из них верны. Ant и Maven могут лучше подходить для Java, чем make, или, как указывает Хэнк Гэй, они не могут:)

Однако вы спросили, имеет ли значение, что Ant и Maven написаны на Java. Хотя в StackOverflow мы не учитываем такие мысли (закрытые! Не связанные с программированием! На рельсах мы используем Rake, C dudes используют make, а в Java - Ant и Maven. Хотя разработчики Ant или Maven действительно будут заботиться о Java-разработчике, возможно, лучше, чем другие, есть еще один вопрос: для чего вы пишете задачи Ant? Джава. Если вы Java-разработчик, это легко.

Так что, да, частью этого является использование инструментов, написанных на том языке, на котором вы работаете.

12 голосов
/ 05 февраля 2010

Муравей и позже Maven были разработаны для решения некоторых головных болей, вызванных Make (при создании новых в процессе). Это просто эволюция.

... Вскоре после этого несколько Java-проектов с открытым исходным кодом поняли, что Ant может решить проблемы, которые у них возникли с Makefiles ....

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

Субъективно ли они решают что-то или просто создают дополнительный формат для изучения? Правда в том, что в значительной степени история каждого нового изобретения: создатель говорит, что он решает множество проблем, а первоначальные пользователи говорят, что это достоинства.

Основное преимущество, которое он имеет, - это возможность интеграции с Java.

Полагаю, похожая история была бы с rake, например.

9 голосов
/ 05 февраля 2010

Одной из основных проблем, решаемых Maven (и настройками Ant с поддержкой Ivy) над make, является автоматическое разрешение зависимостей и загрузка ваших файлов зависимостей.

6 голосов
/ 03 марта 2013

Я думаю, что наиболее вероятное объяснение состоит в том, что несколько факторов препятствовали использованию make в сообществе Java в критический период времени (конец 1990-х годов):

  1. Поскольку Java охватывает несколько платформ, программисты на Java в целом не были настолько хороши в инструментах Unix, как программисты, обычно ограниченные средой Unix (например, программисты на C и Perl). Обратите внимание, что это в общем. Без сомнения, есть и были одаренные Java-программисты с глубоким пониманием Unix.
  2. Следовательно, они были менее искусны в make и не знали, как эффективно использовать make.
  3. Несмотря на то, что можно написать короткий и простой Makefile, который эффективно компилирует Java, требуется дополнительная осторожность, не зависящая от платформы.
  4. Следовательно, появился аппетит к не зависящему от платформы инструменту сборки.
  5. Именно в этой среде были созданы Муравей, а затем и Мавен.

Короче говоря, хотя make наверняка можно использовать для проектов Java, был момент, когда он стал инструментом де-факто для сборки Java. Этот момент прошел.

5 голосов
/ 07 февраля 2010

Создание сценариев, как правило, зависит от платформы. Предполагается, что Java не зависит от платформы. Поэтому наличие системы сборки, которая работает только на одной платформе для многоплатформенной исходной базы, является своего рода проблемой.

4 голосов
/ 02 марта 2016

Краткий ответ: потому что make нехорошо. Даже на фронте C вы видите много альтернатив.

Длинный ответ: make имеет несколько недостатков, которые делают его едва пригодным для компиляции C и вообще непригодным для компиляции Java. Вы можете заставить его скомпилировать Java, если хотите, но можете столкнуться с проблемами, некоторые из которых не имеют подходящего решения или обходного пути. Вот некоторые из них:

Разрешение зависимостей

make по своей природе ожидает, что файлы будут иметь древовидную зависимость друг от друга, в которой один файл является результатом построения нескольких других. Это уже имеет неприятные последствия в C при работе с заголовочными файлами. make требует, чтобы make -специфичный включаемый файл был сгенерирован для представления зависимости файла C от его заголовочных файлов, поэтому изменение последнего вызовет перестраивание предшествующего файла. Однако, поскольку сам файл C не воссоздается (просто перестраивается), make часто требует указать цель как .PHONY. К счастью, GCC поддерживает автоматическое создание этих файлов.

В Java зависимость может быть циклической, и нет инструмента для автоматического создания зависимостей классов в формате make. Задача ant Depend может вместо этого непосредственно прочитать файл класса, определить, какие классы он импортирует, и удалить файл класса, если какой-либо из них устарел. Без этого любая нетривиальная зависимость может привести к тому, что вы будете вынуждены использовать повторные чистые сборки, что лишает вас преимуществ использования инструмента сборки.

Пробелы в именах файлов

Хотя ни 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 для файловой системы.

Это бывает двух разновидностей:

  1. MSYS, который пытается ограничить преобразование POSIX путями к файлам и поэтому может иметь неприятные ошибки при запуске внешних инструментов, специально не предназначенных для него.

  2. cygwin, который обеспечивает полную эмуляцию POSIX. Получающиеся программы, однако, имеют тенденцию полагаться на этот слой эмуляции.

По этой причине в Windows стандартный инструмент сборки вообще не make, а скорее MSBuild, который также является инструментом на основе XML, в принципе ближе к ant.

В отличие от этого, ant построен на Java, может работать везде и содержит внутренние инструменты, называемые «задачами», для манипулирования файлами и выполнения команд независимо от платформы. Он достаточно универсален, так что вы можете на самом деле легче создавать C-программу в Windows, используя ant, чем make.

.

И еще один минор:

Даже программы на C не используют make изначально

Возможно, вы изначально этого не замечали, но программы на C обычно не поставляются с Makefile. Они поставляются с конфигурационным скриптом CMakeLists.txt или bash, который генерирует фактический Makefile. Напротив, источник Java-программы, созданной с использованием ant, поставляется с предварительно созданным сценарием ant. Makefile - это продукт других инструментов - вот почему make не подходит для самостоятельной сборки. ant является автономным и работает со всем необходимым для процесса сборки Java, без каких-либо дополнительных требований или зависимостей.

Когда вы запускаете ant на любой платформе, он просто работает (тм). Вы не можете получить это с make. Это невероятно зависит от платформы и конфигурации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...