Предлагаем вашему вниманию перевод поста Никиты Прокопова, разрабочика с 15-летним стажем.

image Обычно, начиная проект на Java (или любой другой проект), вы не хотите заново изобретать колесо. Вы де-факто выбираете систему сборки, структуру папок, окружение и т.д. То, что использует весь остальной мир.

Тем не менее, и Skija, и JWM сделаны с помощью скриптов Python вместо более традиционных Ant/Maven/Gradle/SBT. Почему? Давайте узнаем!

Maven


Когда мы только начинали Skija, я использовал Maven, потому что хорошо его знал. Очень скоро мы столкнулись с ограничениями Maven: это очень жесткая система. Он хорошо работает на стандартных проектах, но когда вам нужно что-то дополнительное, он становится препятствием.

А у нас был очень нестандартный проект. Skija — это проект 50/50 из Java и C++. Мы создаем нативные артефакты и упаковываем их в JAR-файлы. У нас есть несколько разных JAR, собранных из одного источника (по одному на платформу). Мы также предварительно обрабатываем исходники Java с помощью Lombok перед их компиляцией.

Забавный факт: единственной IDE, которая поддерживает одновременную разработку на Java и C++, является Android Studio. Нет, мы не были готовы пойти на эту жертву.


С каждым усложнением я упорно боролся за то, чтобы все работало с Maven. Но его негибкость делала простые вещи чрезвычайно сложными. Например, я не мог контролировать, какие файлы из каталога должны попасть в JAR, а какие нет. Я не мог указать в каком каталоге их искать.

В конце концов, я сдался. Было до смешного сложно добиться тривиальных вещей. Например, нужно генерировать/изменять XML-файл на лету, чтобы передать переменные среды. Или я не мог запретить Maven запускать тесты, когда мне это не нужно.

Gradle


Мы даже не пробовали Gradle в проекте Skija, но я видел, как мои коллеги используют его в реальной жизни. Gradle — это в основном магия: вы пишете «подсказки» системе сборки, и тогда, надеетесь, в нужное время произойдет то, что нужно. Он также полон значений по умолчанию и условностей, поэтому многие детали неявны. Вы должны знать их, чтобы догадаться, что произойдет, но вы не можете погуглить их, потому что там нет кода.

Make


Мы попробовали Make, но мне не удалось заставить его компилировать Java инкрементально. Он может обрабатывать отдельные файлы, но javac требует, чтобы вы сначала собрали все новые классы, а затем вызвали его один раз. Он также в некотором роде зависит от Bash (или других скриптов) для вещей, которые он напрямую не поддерживает, см. ниже.

Bash


Мы пробовали Bash, но Bash — это ужасный, ужасный язык. Переменные работают не так, как вы ожидаете, в вашем скрипте есть значительные отступы, пробелы в строках особенные, и в довершение всего есть небольшие различия в утилитах CLI, которые вы должны использовать с Bash. У нас уже были проверки ОС для sed и xargs, потому что они по-разному работают на macOS/Linux, а мы едва написали 200 строк Bash.

Bash также не был достаточно кроссплатформенным. Самым простым способом заставить его работать на Windows была установка Git (Да, Git! Я знаю!), но тогда компиляция C++ начинала вести себя странно, потому что он не мог понять, должен ли он создавать двоичные файлы Windows или Linux.

И снова мне стало казаться, что это слишком много усилий для такой простой вещи. Я просто хотел вызвать cmake и javac и переместить несколько файлов. Не слишком ли многого я прошу?

Babashka


Будучи верным кложуристом, я попробовал Babashka. Это интерпретатор Clojure с некоторыми дополнительными “батарейками” и смехотворно быстрым временем запуска. Другими словами, идеально подходит для написания сценариев.

Babashka почти справилась. Она была императивной, делала именно то, что я хотел, самым простым способом. Она была кросс-платформенной. Конечно, это было немного натянуто (JetBrains не славится своей любовью к Clojure, и другим людям, которые хотели принять участие в проекте, пришлось бы его изучать), но я был в отчаянии и готов был попробовать все.

Babashka также была быстрой. Я не упомянул об этом ранее, но, вызывая javac/cmake напрямую, вы можете получить инкрементную перестройку Java и C++ и новую версию приложения за время, которое требуется Maven/Gradle только для пробуждения. Это разница между 1 секундой и 3-5 секундами, но когда вы делаете это несколько раз в минуту (да, я люблю часто испытывать вещи), это становится важным и очень заметным.

Так что же было не так? К сожалению, “батареек” там точно не было. Работа с файлами (каталог по умолчанию, родительский, список дочерних файлов и т.д.) Была немного громоздкой, вызов внешних процессов также был сложным. Я поймал себя на том, что пытаюсь улучшить удобство использования некоторых функций, но тогда они не будут переносимыми, мне придется копировать реализацию всякий раз, когда я двигаюсь вперед, и т. д.

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

Python


Представьте Python. Он кроссплатформенный. Его быстро вызывать. В отличие от Bash, это настоящий язык программирования. Это один из самых популярных языков на планете. Стандартная библиотека выглядит довольно хорошо: она оптимизирована как для написания сценариев, так и для программирования. Все необходимые “батарейки” есть: по сей день все мои скрипты сборки зависят только от стандартной библиотеки Python и от нуля внешних зависимостей.

С самого начала я был невероятно счастлив. Контраст с Maven был разительным: если я хотел переместить какие-то файлы в папку, я просто писал одну строку для их копирования. Если я хотел запустить тест, я писал одну строку, вызывающую java. Больше никакой борьбы с настройками по умолчанию. Никаких больше «декларативных» подсказок, которые могут сделать или не сделать то, что вам нужно.

Легкие вещи были легкими, сложные вещи… ну, вот в чем дело. У нас не было никаких сложных вещей, это просто скрипт сборки!

Вы можете задаться вопросом, а как насчет задач, специфичных для java?

Например, как загрузить зависимости maven? Ну, это простой urllib.request (мы рассматривали и vendoring). Как построить classpath? С помощью конкатенации строк, "a.jar" + ":" + "b.jar". Как вы создаете jar? Вызывая утилиту jar, ту, которая поставляется с JVM. Я думаю, что в какой-то момент мы даже архивировали файлы напрямую с помощью zipfile.ZipFile, не уверен, почему мы изменили это. О, и мы также создаем pom.properties/pom.xml в Python на лету.

Подождите, правда? Да, правда. Это не так уж и сложно! «Настоящие» Java-разработчики могут возразить, что это «неправильный» способ делать вещи, потому что ответственность, разделение проблем, вы не должны писать этот код, он уже реализован, ля-ля-ля. Но эй, это три строчки кода, Maven сделает это не лучше, чем мой скрипт на Python, а конечный результат тот же. Если генерация pom.properties — это цена, которую я должен заплатить, чтобы не трогать Maven, я с радостью заплачу!

Оглядываясь назад, Python — это очевидный выбор. Это идеальный клей. На нем можно писать сценарии. Ему все равно, на каком языке написана остальная часть вашей системы. В нем есть все “батарейки”. Он быстрый и кроссплатформенный. Google уже давно это понял, потому что (я предполагаю) в Google много склеивания. Теперь это понял и я.

Заключение


Если вы играете по общим правилам, вы получаете вознаграждение в виде интеграции, поддержки, простоты настройки. Если у вас много программистов или огромный проект, вы получаете преимущества стандартизации.

Но есть накладные расходы, и эти накладные расходы ненулевые. Я бы сказал, что для небольших или нестандартных проектов имеет смысл написать несколько собственных скриптов, а не вкладывать деньги и бороться с существующими системами сборки, которые не были разработаны для вашего случая использования. Вы также выиграете в производительности.

Что касается лучшего языка сценариев, пожалуйста, не используйте Bash. Я знаю, это заманчиво, это всего лишь «две строчки кода». Все всегда начинается с малого, пока однажды не вырастает в непортируемый, неподдерживаемый беспорядок. На самом деле, Bash настолько прост и настолько естественен, чтобы просто начать его использовать, что мне пришлось ввести очень строгое правило: никогда не использовать Bash. Просто. Не использовать.

Но Python — это здорово. Используйте Python! Или Ruby, Ruby тоже может быть хорош. Только, пожалуйста, не используйте версию 2.7, это уже даже не смешно.

Если хотите, можете взглянуть на наши скрипты.

===
Никита занимается всякими полезными open-source штуками: Fira Code, AnyBar, DataScript и Rum. Его можно поддержать на Patreon и получить ранний доступ к его статьям.




image

Вакансии
НПП ИТЭЛМА всегда рада молодым специалистам, выпускникам автомобильных, технических вузов, а также физико-математических факультетов любых других высших учебных заведений.

У вас будет возможность разрабатывать софт разного уровня, тестировать, запускать в производство и видеть в действии готовые автомобильные изделия, к созданию которых вы приложили руку.

В компании организован специальный испытательный центр, дающий возможность проводить исследования в области управления ДВС, в том числе и в составе автомобиля. Испытательная лаборатория включает моторные боксы, барабанные стенды, температурную и климатическую установки, вибрационный стенд, камеру соляного тумана, рентгеновскую установку и другое специализированное оборудование.

Если вам интересно попробовать свои силы в решении тех задач, которые у нас есть, пишите в личку.



О компании ИТЭЛМА
Мы большая компания-разработчик automotive компонентов. В компании трудится около 2500 сотрудников, в том числе 650 инженеров.

Мы, пожалуй, самый сильный в России центр компетенций по разработке автомобильной электроники. Сейчас активно растем и открыли много вакансий (порядка 30, в том числе в регионах), таких как инженер-программист, инженер-конструктор, ведущий инженер-разработчик (DSP-программист) и др.

У нас много интересных задач от автопроизводителей и концернов, двигающих индустрию. Если хотите расти, как специалист, и учиться у лучших, будем рады видеть вас в нашей команде. Также мы готовы делиться экспертизой, самым важным что происходит в automotive. Задавайте нам любые вопросы, ответим, пообсуждаем.

Комментарии (12)


  1. tzlom
    28.10.2021 13:54
    +4

    И поэтому он не использует питон для сборки.
    Любая декларативная система на голову лучше императивной собиралки т.к. она может нормально оптимизировать процесс сборки.
    Ну и всякие там интеграции с IDE и прочие плюшки конечно надо велосипедить самому.


    1. ScratchBoom
      28.10.2021 16:06

      Любая декларативная система на голову лучше императивной собиралки т.к. она может нормально оптимизировать процесс сборки

      Но как сделать что-то не стандартное - так хоть увольняйся.


      1. tzlom
        28.10.2021 16:34
        +1

        Вариант изучить инструментарий и научиться им пользоваться не рассматривается? Те же make файлы, да они не современные и с хреновым user experience, однако я бы хотел увидеть задачу относящуюся к сборке проекта которую на них нельзя сделать.


        1. ScratchBoom
          28.10.2021 17:09

          ну мейк файл не такой уж и декларативный - из него можно на баше вызвать всё что угодно. А вот попробуйте с чистым мавеном что-то нетривиальное сделать.


          1. tzlom
            29.10.2021 00:39
            +2

            Из любой билд системы можно вызвать что угодно (обычно компилятор конечно), и это что угодно имеет не определённые побочные эффекты. Правда на декларативность самой системы сборки это не влияет.

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


  1. lorc
    28.10.2021 15:06

    У нас хоть и не Java, но проект большой и разнообразный, состоящий из сильно разных компонент (Yocto и Android вместе, как вам такое?). Поэтому мы тоже используем Python. Но немного в другой роли. Скрипт на питоне читает yaml файл с описанием сборки и генерирует по нему build.ninja. Нинджа же прекрасно отслеживает зависимости и запускает собственно сборщики. Каждой задаче - свой инструмент.


  1. SnowBearRu
    28.10.2021 17:49
    +1

    Забавный факт: единственной IDE, которая поддерживает одновременную разработку на Java и C++, является Android Studio

    NetBeans - нее ?

    Eclipse - тоже нее?


  1. sshikov
    28.10.2021 18:20
    +4

    Хм. У меня это все описание вызывает ровно одно воспоминание: «Чего только не сделают, чтобы не ходить на овощную базу» (с) анекдот советских времен. У мавена невесть сколько лет есть плагин, позволяющий выполнять код на груви изнутри, с доступом к модели проекта. В этом коде можно сделать все, вообще все. Все что вы будете или делаете в gradle, например.

    А дальше вопрос стоит просто: вы предпочитаете питон груви? Ну не вопрос, пишите тогда на питоне. Я же предпочту груви питону в 99% случаев. Поэтому у меня в мавене нестандартные задачи решаются сравнительно легко и просто. Надо процедурный код написать — пишем. Не надо — используем механизмы мавена. Пока на IDE наш процедурный код не влияет — интеграция с ней также хороша.


  1. gapel
    29.10.2021 09:04

    гм, а не хотите связку Jenkins + SCons попробовать?

    В Дженкинсе удобно распихать глобальные мазки и Ява. Плагинов море, Груви поддерживается.

    Сконс удобно допиливать на питоне, и настроить билд С++ можно гибко.

    Но это я так, спросить


  1. win32asm
    29.10.2021 09:54

    < del, предыдущий комментатор уже предложил scons >


  1. vba
    29.10.2021 12:42
    +1

    Но Python — это здорово

    Согласен, но его тоже можно превратить в раздутый кошмар, даже быстрее чем все перечисленные системы сборки.


  1. Beholder
    02.11.2021 12:00
    +3

    Мы даже не пробовали Gradle в проекте

    Ну и зря решили соригинальничать. Gradle хоть и может показаться сложным, но универсален. Да, там в нём надо разбираться, но магии никакой нет. Плагины можно писать прямо внутри проекта.


    А так чувствую, что если эту систему на Python продолжать развивать, то в итоге когда-нибудь получится аналог Gradle, с такой же "магией".