Краткий ответ: потому что 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 для файловой системы.
Это бывает двух разновидностей:
MSYS
, который пытается ограничить преобразование POSIX путями к файлам и поэтому может иметь неприятные ошибки при запуске внешних инструментов, специально не предназначенных для него.
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
. Это невероятно зависит от платформы и конфигурации.