Skip to content

Latest commit

 

History

History
executable file
·
217 lines (182 loc) · 14.2 KB

README.ru.md

File metadata and controls

executable file
·
217 lines (182 loc) · 14.2 KB

bastard

testing

bastard

Пакетный менеджер на CMake

Набор CMake утилит для обеспечения работы с зависимостями проекта.

Требования

  • CMake >= 3.10
  • git
  • python3 (опционально для git hooks)

Интеграция

  • Скопировать и подключить файл bastard_setup.cmake:
cmake_minimum_required(VERSION 3.10)
include(cmake/bastard_setup.cmake)
bastard_setup()
project(${BASTARD_PACKAGE_NAME})
  • Запустить cmake
cd build && cmake ..

Начнется инициализация проекта. Пакетный менеджер будет выгружен в каталог .deps как обычная зависимость. Далее по описанию из bastard.toml будут выгружены зависимости пакета и сгенерированы цели для сборки.

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

Описание секций

  • [package]

    • name: str Имя пакета (уникально в рамках сборки)
    • authors: list[str] Список авторов
    • autogen-defines: bool Автогенерация defines из опций (с префиксом)
    • version: str Версия пакета
    • lang: str Язык по-умолчанию для всех целей пакета c90|c99|c++98|c++11|c++14|c++17|c++20
    • system: [str] Общая спецификация платформы (обычно Unix | Windows | Generic)
    • processor: [str] Общая спецификация процессора (экв. CMAKE_SYSTEM_PROCESSOR)
  • [dependencies] Базовые зависимости

    • <package>: str Имя зависимой библиотеки
      • git: str Ссылка на репозиторий
      • tag: str Конкретный тег
      • branch: str Конкретная ветка
      • rev: str Конкретный хэш коммита
      • links: list[str] Указание нескольких библиотек для линковки
      • path: str Путь к локальной зависимости проекта
      • interface: str Путь к директории с исходниками для генерации цели
      • system: [str] Спецификация платформы для зависимости
      • processor: [str] Спецификация процессора для зависимости
  • [dev-dependencies] Зависимости для разработки

    • Аналогично секции [dependencies]
  • [sys-dependencies] Системные зависимости

    • <package>: str Имя системного пакета (например Thread, Boost)
    • components: list[str] Список компонентов для find_package()
    • links: list[str] Список библиотек для линковки
  • [lib] Описание цели библиотеки

    • name: str Имя цели библиотеки
    • lang: str Используемый язык (см. package.lang)
    • type: str Тип библиотеки static|shared|interface
    • include: [str] Маска для включения файлов относительно каталога lib
    • exclude: [str] Маска для исключения файлов относительно каталога lib
  • [[bin]] Описание цели/целей бинарника

    • name: str Имя цели (или путь к каталогу по-умолчанию, если не определен path)
    • path: str Путь к файлу/директории для сборки
    • lang: str Используемый язык (см. package.lang)
    • include: [str] Маска для включения файлов относительно каталога lib
    • exclude: [str] Маска для исключения файлов относительно каталога lib
    • include и exclude относительно bin/name либо bin директории
    • console: bool Является ли приложение консольным (по-умолчанию true)
  • [[test]] Описание цели/целей бинарника для тестирования

    • Аналогично [bin]
  • [[example]] Описание цели/целей бинарника для примеров

    • Аналогично [bin]
  • [options] Описание cmake переменных для целей

    • <package> = { <name>=<value> }
  • [defines.<public|private>] Описание defines для целей

    • <package> = { <name>=<value> }

Структура проекта

По-умолчанию если секции [lib] [[bin]] не указаны, то принимается legacy соглашение, когда все зависимости должны подключаются вручную в CMakeLists.txt. Для legacy режима возможно использовать любую структуру проекта, однако функциональность bastard ограничивается только выгрузкой зависимостей и настройкой опций. Если следовать соглашению по структуре проекта, то конфигурирование пакета будет происходить автоматически.

Под конфигурированием в данном случае понимается:

  • Генерация lib цели
  • Генерация bin целей
  • Линковка lib ко всем bin
  • Настройка доступа к заголовочным файлам
  • Подключение и линковка системных пакетов
  • Генерация и настройка тестов из папки tests
  • Генерация файла версии version.h
  • [future] Генерация и настройка примеров из папки examples
  • [future] Генерация и настройка бенчмарков из папки benchs

Структура пакета с библиотекой:

-- cmake
-- include/
---- mylib/
------ mylib.h
-- lib/
---- mylib.cpp
-- bastard.toml
-- CMakeLists.txt

Структура пакета с бинарниками:

-- cmake
-- bin
---- app1/
------ main.cpp
---- app2/
------ main.cpp
-- bastard.toml
-- CMakeLists.txt

Структура пакета с библиотекой и бинарниками:

-- cmake
-- bin
---- app1/
------ main.cpp
---- app2/
------ main.cpp
-- include/
---- mylib/
------ mylib.h
-- lib/
---- mylib.cpp
-- bastard.toml
-- CMakeLists.txt

Также допускается не использовать подкаталоги вида <include/package_name> и <bin/app_name> (а только include и bin). Это бывает удобно при сборке плагинов или одиночных приложений.

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

Зависимости только с заголовочными файлами можно подключать через атрибут interface = "/path/include". В таком случае будет создана цель интерфейсной библиотеки. Использование атрибута допустимо только для git зависимостей.

По умолчанию в качестве исходников подгружаются все файлы (по маске) из каталогов lib, bin, bin/name, include, include/name:

  • lib/*.cpp, lib/*.hpp, lib/*.c, lib/*.h, lib/*.ui, lib/*.qrc
  • bin/*.cpp, bin/*.hpp, bin/*.c, bin/*.h, bin/*.ui, bin/*.qrc
  • include/*.hpp, include/*.h

Для детальной настройки целей [[bin]] и [lib] можно использовать опции include и exclude. Разрешение имен для файлов происходит относительно целевых каталогов целей. Для цели [lib] нельзя настроить фильтрацию каталога include.

Кросплатформенная сборка

Для разделения функционала под разные платформы можно пользоваться описанием локальных зависимостей и системы:

[dependencies.boost_timer]
path = "specific/boost_timer"
system = ["Unix", "Windows"]
processor = "x86_64"

[dependencies.soft_timer]
path = "specific/soft_timer"
system = "Generic"
processor = ["TMS320C6414", "TMS320C5509A"]

В данном случае все файлы из каталога specific/boost_timer будут добавлены к сборке базовой цели для платформ Windows или Unix (процессоры x86_64). Для случая Generic платформы (процессоры TMS320C6414 или TMS320C5509A) используются файлы specific/soft_timer

  • Значения из system аналогичны проверке cmake флагов WIN32 и UNIX (для Windows и Unix соотв.), прочие значения проверяются на соответствие CMAKE_SYSTEM_NAME
  • Значения из processor полностью соответствуют CMAKE_SYSTEM_PROCESSOR из тулчейна

ВАЖНО: Нужно быть осторожным, при описании пересекающихся целей (модули с общими интерфейсами)

Версионирование

При указании версии пакета (в секции package) будет автоматически сгенерирован файл ${build_path}/include/${package_name}/version.h:

#ifndef __MYPACKAGE_VERSION_GUARD__
#define __MYPACKAGE_VERSION_GUARD__

#define MYPACKAGE_VERSION "1.2.3"
#define MYPACKAGE_VERSION_MAJOR (1)
#define MYPACKAGE_VERSION_MINOR (2)
#define MYPACKAGE_VERSION_PATCH (3)
#define MYPACKAGE_GIT_COMMIT "23498f"

#endif

Подключить файл к проекту (публичная область видимости):

#include <package_name/version.h>

Git Hooks

При конфигурировании менеджер автоматически размещает в каталоге .git/hooks/ скрипты вспомогательных хуков (но только при условии отсутствия пользовательских).

Автоматическая генерация тегов

При изменении version в toml файле генерируется post-commit хук, который автоматически добавит тег вида "vX.X.X" при каждом коммите. Поэтому важно периодически использовать команду git push --tags для обновления тегов на сервере.

Проверка clang-format

При наличии в корне проекта файла правил .clang-format, перед каждым коммитом будет вызван pre-commit хук. Для каждого staged файла с расширениями cpp, hpp, h, c, cxx, hxx вызывается clang-format и результат сравнивается с исходным. Если код не форматирован - коммит сделать нельзя. Чтобы обойти это ограничение - можно использовать файл .clang-format-ignore по аналогии с .gitignore. ВАЖНО: правила и файлы берутся из staged состояния, локальные правки не влияют на результат.

FAQ

  • При первом запуске cmake зависимости обновляются автоматически
  • Без доступа к сети можно разместить зависимости в каталог .deps вручную
  • Версии при генерации lock файла берутся из .deps зависимостей
  • Для обновления зависимостей необходимо удалить пакет из .deps, удалить .lock и перезапустить cmake (в клиенте для этого будет отдельная функция)
  • Имеет смысл добавлять bastard.lock под версионирование
  • Описывайте в секции [dev-dependencies] зависимости для разработки
  • Для пакетов библиотек лучше использовать конкретные версии зависимостей (tag)
  • После выгрузки все зависимости используются как локальные (каталог .deps)
  • Для сборки без доступа к репозиториям (на другой системе) удалите старый build
  • Многострочные атрибуты для toml временно не поодеживаются (пишите в одну строку)
  • SVN не поддерживается (и никогда не будет)
  • В любой непонятной ситуации удаляй build/.deps/bastard.lock