16/06/2022

Система сборки. Ant, Maven, Gradle

Система сборки. Ant, Maven, Gradle

Что такое система сборки

Система сборки – это программное обеспечение, обеспечивающее автоматизацию сборки проекта. Конфигурационный файл для системы сборки описывается в текстовом виде. Как следствие, быстрее можно начать проект, за счет того, что что все типовые задачи заключаются в копировании уже готовых сниппетов. Это гораздо быстрее, более гибко, мобильно, и, главное, читаемо, чем вводить то же самое например, через UI диалоги IDE. Ну и в промышленных проектах это более удобно.

Инструменты сборки могут делать

  • компиляцию кода - поддерживают определенный компилятор или несколько
  • запуск тестов и определение покрытия
  • статический анализ
  • сборка архивов с бинарными файлами, исходными кодами, документацией
  • построение отчетов
  • скачивание и обеспечение доступа нужных зависимостей

Польза от инструмента сборки

  • Уменьшение числа рутинных ошибок
  • уменьшение времени сборки проекта
  • можно хранить историю сборок и анализировать ошибки
  • уменьшение затрат на разработку и улучшение качества

Нет автоматизации сборки

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

$ javac MyClass.java

Shell скрипт

С таким подходом можно большие проекты легко собирать можно использовать условную логику можно разделить сборку на стадии: clean.sh, compile.sh, test.sh

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

if test ! -e .nuget; then
    mkdir .nuget
    cp $cachedir/nuget.exe .nuget/nuget.exe
fi

Make (1977 год)

Такая утилита появилась под Unix. Make использует специальный формат для описания билда и называется Make-file. Типичный Make-file содержит название стадий, зависимость стадий. Но основное содержание это такие же команды операционной системы. Команды выполняются запуском make + название стадии: make install, make noopt и т.д.

noopt:
    $(MAKE) OPTIMIZATION="-O0"

valgrind:
    $(MAKE) OPTIMIZATION="-O0" MALLOC="libc"

src/help.h:
    @../utils/generate-command-help.rb > help.h

install: all
    @mkdir -p $(INSTALL_BIN)
    $(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(INSTALL_BIN)
    $(REDIS_INSTALL) $(REDIS_BENCHMARK_NAME) $(INSTALL_BIN)
    $(REDIS_INSTALL) $(REDIS_CLI_NAME) $(INSTALL_BIN)

Преимущества:

  • определяет единый формат сборки

Недостатки:

  • платформозависимый так как внутри также находятся команды операционной системы
  • в makefile используется табуляция и она не видна в текстовых файлах если в такой файл вставить пробел то такой файл становится неправильным и make не может с ним работать
  • нет поддержки нюансов определенного языка: задач, параметров, плагинов) make работает для любого языка

Apache Ant (2000 год)

Первый инструмент сборки разработанный на java и для java. Имеет конфигурационный файл формата build.xml.

Содержит описание названий стадий, зависимости стадий и могут содержать java - специфичные вещи. Например, как собирать java код (javac), classpath и т.д.

<target name="compile" depends="init" description="Compile the source">
    <javac srcdir="${src.main}" destdir="${build.compile}" classpathref="lib.path.id" includeantruntime="true"/>
</target>

<target name="test-compile" depends="compile" description="Compile tests source">
    <javac srcdir="${src.test}" destdir="${build.test-compile}" classpathref="lib.path.id" includeantruntime="true">
        <classpath>
            <pathelement location="${build.compile}"/>
        </classpath>
    </javac>
</target>

Запускается командой:

$ ant clean compile

Преимущества:

  • поддержка java-специфичных задач
  • переносима между платформами
  • это первая сисетма которая позвоила писать под нее расширения плагины
  • позволяет запускать параметризованные билды можно хранить в отдельной секции некоторые параметры; например, версии используемых библиотек и потом замена версии будет означать просто замену библиотеки у вас в билде

Недостатки:

  • нет конвенций версионирования кода можно версионировать продукт, как заблагорасудится
  • нет конвенций по расположению кода открыв проект на ant'e вы можете ожидать, что код будет где угодно; обычно их кладут в одну и туже папку, но это не гарантируется;
  • нет автоматического управления зависимостями (их кладут в lib/) если у вас используется какая-нибудь библиотека, то она будет лежать прямо в проекте в папке lib в виде jar файлов, а в большом проекте таких файлов библиотек будет много
  • произвольный набор целей(нет жизненного цикла) цели можно называть как угодно и приходится разбираться какая цель что делает
  • императивный стиль описания билда билд состоит из последовательности действий, которые нужно выполнить чтобы собрать проект это плохо
  • ant не поддерживает junit 4

Apache Ivy (2004 год)

Эта библиотека решает проблему Ant - авоматическое управление зависимостями. Конфигурационный файл имеет формат ivy.xml. Написан на Java.

<ivy-module version="1.0">
    <info organisation="ru.yandex.qatools.allure" module="allure-testng-ant"/>
    <dependencies>
        <dependency org="ru.yandex.qatools.allure" name="allure-testng-adaptor" rev="1.4.0"/>
        <dependency org="org.aspectj" name="aspectjweaver" rev="1.7.4"/>
    </dependencies>
</ivy-module>

Можно в конфигурационном файле указать название зависимости: организация, имя, версия и все библиотеки скачаются с интернета.

Apache Maven (2004 год)

Имеет конфигурационный файл pom.xml (Project Object Model). Написан на Java.

Запускается подобно Ant'у командой:

$ mvn clean compile
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.0</version>
    <configuration>
        <source>${compiler.version}</source>
        <target>${compiler.version}</target>
    </configuration>
</plugin>

Преимущества:

  • Конвенции по расположению кода, тестов, ресурсов мы точно знаем где и в какой директории лежат исходные коды, тесты и т.д.
  • четкий жизненый цикл: цели предопределены есть цель для компиляции тестирования отчетов а можно и свои цели создавать
  • имеет четкий способ чтобы поделиться кодом с другими - удаленные репозитории зависимостей это сервера на который закачиваются готовые пакеты с скомпилированным кодом, с исходными кодами, документацией и другие участники разработки могут их оттуда забрать
  • понятный механизм хранения зависимостей - локальный репозиторий это каталог у вас на файловой системе в который сохраняются копии скомпилированных бинарных файлов, документации и т.д. - копия удаленного репозитория
  • правила версионирования кода Мавен вводит понятия релизов и snapshot'ов и как версии должны меняться одна от другой
  • поддерживает многомодульные проекты можно разбивать большой проект на небольшие кусочки/модули которые могут собираться по отдельности и распространяться, передаваться версионироваться по отдельности
  • описывает подход декларативно говорит не в какой последовательности мы должны выполнить шаги а то что мы хотим получить на выходе
  • модульная структура(поддержка плагинов) даже простые действия делают плагины: есть плагин для компиляции, плагин для тестирования и т.д.

Gradle (2009 год)

Написан на Groovy. Использует в качестве файлов конфигурации файлы использующие DSL(Domain Specific Language) на Groovy. Файл называется build.gradle. Команда для запуска аналогична Ant, Maven:

$ gradle clean compile

Возможности Gradle:

  • поддерживает основные воможности Maven;
  • инкрементальная компиляция умеет собирать только те исходные коды которые изменились
  • использует теже удаленные репозитории как и мавен
  • эмулирует жизненный цикл мавена, но можно задавать и свои цели
  • поддерживает плагины, но они не совместимы с Maven