Чому ніхто не використовує make для Java?


162

Майже про кожен проект Java, який я бачив, або використовує Maven або Ant. Вони є прекрасними інструментами, і я думаю, що майже будь-який проект може їх використовувати. Але що коли-небудь траплялося зробити ? Він використовується для різноманітних проектів, що не є Java, і може легко працювати з Java. Звичайно, вам доведеться завантажити make.exe, якщо ви використовуєте Windows, але Ant і Maven також не постачаються разом із JDK.

Чи є якийсь фундаментальний недолік з make при використанні з Java? Це лише тому, що Мураха та Мейвен написані на Яві?


37
Якщо ви переміщуєте речі і більше не просто викликаєте компілятор (і навіть тоді), специфічні для платформи речі дуже незручні в обробці make. А наявність файлу makefile, який працює лише в одній системі, не дуже приємно для мови на платформі.
Joey

Вбік, Gradle є новим гравцем у просторі Java, як і Gant (меншою мірою). Мейвен або Мураха - хибна дихотомія.
Майкл Пасха

@ Майкл Пасха, помилковою дихотомією буде Maven / Ant проти Make. Справжньою дихотомією, якщо я вас правильно читаю, буде Gradle / Maven / Gant / Ant проти Make. Але це важко сказати :)
Dan Rosenstark

Відповіді:


192

Принциповою проблемою із Make and 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 не має великої прямої підтримки для роботи з ієрархіями файлів.

Зробити також не дуже добре для визначення того, які файли застаріли, на рівні колекції.

Що стосується Ant, він перегляне і підсумує всі застарілі файли, а потім скомпілює їх за один раз. Make просто зателефонує у компілятор Java на кожен окремий файл. Зробити НЕ для цього потрібно достатньо зовнішнього інструментарію, щоб дійсно показати, що Зробити не зовсім до цього завдання.

Ось чому піднялися такі альтернативи, як Мураха та Мейвен.


6
Тож для того, щоб використовувати make у величезному проекті Java, потрібно було б підтримувати список всіх змінених файлів .java, а потім в кінці викликати javac? Це для мене звучить менш ідеально. Це найкраща відповідь, яку я бачив досі.
Користувач1

32
Я обожнюю це. По суті, ви говорите, мурашник був потрібен, щоб вирішити той факт, що javac занадто повільний.
cmcginty

25
Ні. Javac не є повільним, якщо використовувати його так, як було призначено для використання. Це просто повільно, якщо ви використовуєте його для складання одного файлу за один раз.
Stephen C

7
@Casey javac не надто повільний. JVM занадто повільний, щоб почати.
Thorbjørn Ravn Andersen

7
GNU Make принаймні має $?автоматичну змінну, яка розширюється на "всі необхідні умови, ніж цілі". Існує також особливість правил шаблону з декількома цілями, які запускали рецепт лише один раз, щоб оновити всі .classфайли. Об'єднайте це з яким - то розумним використанням файлу / текстові функції , такі як $(wildcard), $(shell), $(eval)і ви можете навчити Makefile , щоб виявити збірки цілі , розкидану по вашій схемі директорій.
Tanz87

33

Поважна makeпрограма досить добре обробляє окремо складені мови, такі як C та C ++. Ви компілюєте модуль, він використовує #includeдля витягування в текст інших файлів, що включають, і записує один об'єктний файл як вихід. Компілятор - це дуже одноразова система з окремим кроком зв’язування для прив’язки об'єктних файлів до виконуваного двійкового файлу.

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

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


7
Це виглядає як більше відповіді "зробити проти явака", ніж відповіді "зробити проти мурашки" / "maven". Виходячи з вашої відповіді, чому хтось не міг просто використовувати make + javac (даючи javac цілий пакет або "модуль" одночасно, тому круглі залежності приховані від make)? Чи забезпечили б мураха чи мавен якусь користь від такого підходу?
Лоранс Гонсалвс

1
@Laurence: Ви можете одночасно надати javac цілий пакет, але потім він перекомпілює все, що знаходиться в цьому пакеті (оскільки саме так ви і сказали). Це правда, що компілятор Java є досить швидким, але це ще швидше, якщо ви дозволите йому визначити, які класи є мінімальним, необхідним для перекомпіляції після чогось змінити.
Грег Хьюгілл

Ви маєте на увазі сказати javac лише складати ваш "основний" клас, а потім мати автоматично створювати речі, від яких залежить? Востаннє я перевірив (правда, мабуть, у 1.4), що було жахливо ненадійним. -Xdepend був трохи кращим (але повільніше і все-таки зламаним), і вони зняли цей прапор у 1.3.
Лоуренс Гонсалвс

4
Крім того, це все ще не пояснює, чому я використовую Ant або Maven, а не просто прямий javac ...
Laurence Gonsalves

28

Питання заснований на невірному припущенні: нетривіальне число розробників робить використання make. Див. Інструменти побудови Java: Мураш проти Мейвена . Щодо того, чому розробник не користувався б make: багато розробників або ніколи не використовували make, або використовували його і ненавиділи його вогнем, який горять гарячіше тисячі сонців. Як такі, вони використовують альтернативні інструменти.


10
Ми його використовуємо, а вогонь гарячіший за тисячу і одну сонечку.
реклами

4
@reccles: Це просто ненависть до будівництва інженерії чи домогтися себе? Як би краще було Ant, Maven чи щось інше (тобто зробити поганим інструментом для свого класу)?
Користувач1

5
@ User1 makeмає багато "функцій", які, можливо, мали сенс під час написання, але зараз більше схожі на помилки, наприклад, у певних місцях ви повинні використовувати символ TAB, а не пробіли. Така річ, мабуть, не турбує людей, які насправді мають досвід make, але решта нас ганяють.
Хенк Гей

4
@HankGuy: нехай ваш редактор турбується про цю деталь. Якщо ваш редактор не зможе правильно обробити параметри простору вкладки <->, знайдіть новий редактор, і ви будете набагато щасливішими. Але ви праві, говорячи про те, що багато функцій застаріли, як те, як обробляються динамічні залежності ( make dependхтось?)
Д.Шоулі

3
@ User1 Це масштаб проекту, який ми будуємо. У нас штатний працівник, який підтримує створення файлів та створення залежностей. Використовуючи maven, я виявив, що це більш керовано. Тепер сказав, що і мавен не був ідеальним. Ніщо не наштовхує на думку, ніж намагатися розібратися, які параметри XML потрібні для складання, яка трохи відрізняється від встановленої установки.
згадує

28

Насправді, 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+=$$<)

4
Приємно! Я шукав щось подібне. Якщо універсальна класика працює добре, не потрібно використовувати різний інструмент побудови для кожної мови. Дякую!
rsp

17

Усі інші відповіді про технічні достоїнства кожного є вірними. Antі Mavenможе підходити більше до Java, ніж робити, або, як вказує Хенк Гей, вони можуть не робити :)

Однак ви запитали, чи не має значення, що Мураха та Мейвен написані на Яві. Хоча в StackOverflow такі думки не враховуються (закриті! Не пов'язані з програмуванням! І т. Д.), КУРСУ, ЩО ЧАСТИНА ЧОГО. На рейках ми використовуємо Rake, C чуваки використовують make, а на Java використовуємо Ant та Maven. Хоча це правда, що розробники Ant або Maven будуть піклуватися про розробника Java, можливо, краще за інших, є також інше питання: у що ви пишете завдання Ant? Java. Якщо ви розробник Java, це легко підходить.

Так, так, частина цього полягає у використанні інструментів, написаних мовою, яку ви використовуєте.


7
Мураха також виникла в той час, коли спільнота Java була насичена XML. (Що не означає, що XML не має місця.)
Laurence Gonsalves

3
@Laurence Gonsalves, це так правда. Але, будь ласка, ми не говоримо про примхи тут, так :) Я тоді навчав Java dev, і ВСЕ було XML. Тепер це ще XML, але нікого не цікавить.
Дан Розенстарк

1
Коментар інструментарію цікавий. makeпоходить з фонового режиму UNIX, тому інструментарій виконується за допомогою написання корисних компактних утиліт та конвеєрного з'єднання. Ось чому більша частина зшивання виконується за допомогою команд оболонки.
Д.Шоулі

2
@D. Шоулі, все стосується makeі невеликих утиліт Unix. GIT - теж дитина цього процесу. В особистій записці я б не сказав, що це не краще. Але це величезна зміна парадигми для програмістів Java. Мураха набагато більше співзвучний явським способам мислення.
Дан Розенстарк

12

Мураха і пізніше Мейвен були покликані вирішити деякі головні болі, викликані Make (створюючи нові в процесі). Це просто еволюція.

... Незабаром після цього кілька проектів Java з відкритим кодом зрозуміли, що Ant може вирішити проблеми, які вони мали із Makefiles ....

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

Чи вирішують вони щось, або просто створюють додатковий формат для навчання - це суб'єктивна тема. Правда полягає в тому, що в значній мірі історія кожного нового винаходу: творець каже, що він вирішує багато проблем, а початкові користувачі кажуть, що це чесноти.

Основна перевага, яку вона має, - це можливість інтегруватися з java.

Я думаю, подібна історія була б, rakeнаприклад.


4
Це не дуже конкретно. Які головні болі, викликані гримом, вирішує Мейвен?
Лоранс Гонсалвс

1
@Gonsalves: Ну, це один із суб'єктивних аспектів кожної нової технології, творець альтернативи каже, що вона вирішує багато проблем, а творці заміненої технології кажуть, що це не дефекти, а чесноти тощо. Я думаю, що в цій конкретній ситуації була інтеграція java та крос-компіляція поза
рамками

2
[Посилаючись на вашу редакцію відповіді, а не на ваш останній коментар] Це все ще не пояснює, які проблеми були вирішені, лише те, що творці мурахи стверджують, що проблеми вирішені ...: - / Моє враження, що мураха спочатку створив для бути більш простою альтернативою Make. З часом люди виявили, що цього не вистачає, і тому вони додали функції, поки Ant не став настільки ж складним, як виготовлення, але з вбудованими бінутілами (в значній мірі покладаються на зовнішні інструменти, такі як cp, rm тощо), і звичайно, є синтаксис XML
Лоранс Гонсалвс

2
Так, але коли найкращий творець нової альтернативи може зробити, це сказати "це вирішує проблеми, які старі мали", не кажучи насправді, які ці проблеми, це не так корисно для тих, хто розглядає, який варіант використовувати. Чи вирішує Мураш проблеми, які у мене є, або це вирішує речі, які я не вважаю проблемами, вводячи нові проблеми для мене?
Лоранс Гонсальвес

9

Однією з найважливіших проблем, яку вирішили Maven (і налаштування мурашок, що підтримуються Ivy), є автоматизоване вирішення залежностей та завантаження ваших банок залежностей.


6

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

  1. Оскільки Java охоплює декілька платформ, програмісти Java взагалі не були настільки спритні в інструментах Unix, як програмісти, як правило, обмежені в середовищі Unix (наприклад, програмісти C і Perl). Зауважте, що це ЗАГАЛЬНО. Без сумніву, є і були обдаровані Java-програмісти з глибоким розумінням Unix.
  2. Отже, вони були менш вмілі у виконанні і не знали, як ефективно використовувати make.
  3. Хоча можна написати короткий і простий Makefile, який ефективно компілює Java, для цього потрібна додаткова обережність, незалежна від платформи.
  4. Отже, з'явився апетит до інструменту побудови, незалежно від платформи.
  5. Саме в цьому середовищі були створені Мураш і пізніше Мейвен.

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


5

Зробити сценарії, як правило, залежать від платформи. Java повинна бути платформою незалежною. Тому наявність системи побудови, яка працює лише на одній платформі для багатоплатформенної вихідної бази, є проблемою.


5

Коротка відповідь: Тому що make це не добре. Навіть на передній панелі С ви бачите багато альтернатив.

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

Розв’язання залежності

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

У Java залежність може бути круговою, і немає інструменту для автоматичного генерування залежностей класів у makeформаті. ant«S 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 не використовують натур

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

Коли ви працюєте antна будь-якій платформі, це просто працює (тм). З цим не можна погодитися make. Це неймовірно залежить від платформи та конфігурації.


4

Якщо я не хтось, припущення, що ніхто не (помилково) використовує make for java, є помилковим.

"Управління проектами за допомогою GNU Make" (доступне під GFDL) містить повну главу, присвячену використанню makeпроектів java.

Оскільки він містить довгий (і, сподіваємось, справедливий) список плюсів і мінусів використання make, а не інших інструментів, які ви можете поглянути там. (див .: http://oreilly.com/catalog/make3/book/ )


Це точне резюме? make (в різних ароматах) є корисним для Java, але з деяким болем. Ant та Mavenjmake ?) Роблять якісь особливі речі, які потрібні / подобаються Java, щоб зробити проекти Java швидшими та простішими. Вони також можуть використовуватися для більш незалежного від платформи процесу збирання для проектів, які не є Java, але більш налаштовані на Java.
Філ Перрі

3

Ant - це поліпшення конфігурації XML порівняно з Makefiles, а Maven - це поліпшення інструменту побудови залежності над Ant. У деяких проектах використовуються всі три. Я думаю, що проекти JDK використовували суміш мафік та мурашок.


1

Однією з головних причин є те, що і Ant, і Maven (і більшість інструментів SCM, CI та IDE, орієнтованих на java) написані на Java розробниками / для розробників Java. Це спрощує інтеграцію у ваше середовище розробки та дозволяє іншим інструментам, таким як сервери IDE та CI, інтегрувати частини бібліотек ant / maven в інфраструктуру збирання / розгортання.


1

Колись я працював над проектом Java, який використовував gmake. Мій спогад туманний, але IIRC нам важко було працювати зі структурою каталогу пакунків, яку очікує javac. Я також пам’ятаю, що складати файли JAR було клопотом, якщо у вас не було щось тривіальне.


1

ApacheAnt - це не що інше, як Make. Make - це опис залежностей між файлами та способів побудови файлів. Мураха - це залежність між "завданнями", і це справді більше спосіб склеювання складання сценаріїв разом.

це може допомогти вам AntVsMake


Мені дуже хотілося б дізнатися про причини протистоянь.
hagello

0

Ент і Мейвен підходять до складання графіка залежності побудови та управління ним з більш «сучасного» погляду ... Але, як каже Оскар, вони створили власні проблеми, намагаючись вирішити старі проблеми з make.


0

Я ніколи не використовував GNU Make для проектів Java, але використовував jmk . На жаль, він не оновлювався з 2002 року.

Він мав певну функціональність для Java, але був досить малим, щоб включати у свій вихідний тарбол, не збільшуючи істотно його розмір.

Сьогодні я просто припускаю, що будь-який розробник Java, з яким я ділюся кодом, встановив Ant.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.