${habrauser}, Привет!

Продолжаю здесь рассказывать о внутренних процессах игрового фреймворка Oriol Engine, разработка которого до сих пор идёт, и мы не собираемся останавливаться. (⌐■_■)

На Хабре я уже писал о решении проблемы кросс-компиляции шейдеров в данном фреймворке — ShaderPack. Ну а сегодняшняя наша тема будет именно о сборке проектов с помощью Oriol Engine и о том, что в этот момент происходит на его стороне.

Почему же мы не оставили процесс сборки на пользователя? Мол, у тебя есть игровой проект на Oriol, настрой самостоятельно какой-нибудь там CMake и продолжай работу дальше. Да, интегрировать инородную систему сборки можно и сейчас, но согласитесь, что намного приятнее, когда этот процесс автоматизирован. И всё, что от тебя требуется, — это ввести всего лишь одну команду для сборки.

Создание проекта

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

1. Сперва вводим команду для создания базовой структуры проекта:

ol -c Test

2. Выбираем один из предложенных шаблонов лицензии (MIT, Apache, GPL):

Выбор шаблона лицензии при создании проекта в Oriol
Выбор шаблона лицензии при создании проекта в Oriol

После выполнения сея махинаций мы успешно создаём базовую структуру Oriol проекта:

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

Всё вроде бы понятно, но что же за такой интересный файлик Oriol.ol?

Вот тут давайте поподробнее:

Файл Oriol.ol является конфигурационным файлом для фреймворка. Он содержит название, описание, версии, пути к главным папкам. Его содержимое выглядит примерно так:

@Info
{
    name: Test
    description: "Game on Oriol Engine"
    version: 1.0.0
    engine_v: 0.0.1
}

@Paths
{
    assets: "Assets"
    build: "Build"
    sources: "Sources"
}

Что за странный синтаксис? Нет, это не JSON, это специальный формат хранения данных FPL (Fast Parsing Language). Он лёгок для разбора и имеет всё необходимое для фреймворка Oriol. Можно было взять JSON, но желание организовать содержимое конфига как можно красивее преобладало )

Немного про FPL

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

Секции:

Основа любого FPL-кода — это секции, некие блоки со своим именем, содержащие пары "ключ-значение" и вложенные подсекции. Секция объявляется с помощью символа "@".

@имя_секции 
{  
    ключ: значение  
    вложенная: @подсекция { ... }  
}  

Типы данных:

FPL поддерживает такие типы данных как:

  • Строки: "текст" или 'текст'

  • Числа: 123, 3.14, -5

  • Булевы значения: true, false

  • Массивы: [значение1, значение2]

  • Null: null

Комментарии:

Последнее, что можно отметить, - это комментарии. Здесь они обозначаются с помощью символа "#".

# Это комментарий  
@server 
{  
    port: 8080  # Порт сервера  
}  

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

Итак, а теперь про процесс сборки C++ проекта с помощью Oriol Engine. После команды:

ol -b

Фреймворк начинает искать конфигурационный файл Oriol.ol, составляет список всех исходников проекта из папки и её подпапок, которая находится в значении ключа Sources секции Paths (в ближайшем будущем в планах добавить что-то типа .gitignore для конфигурационного файла, чтобы он не использовал конкретные файлы), подключает Oriol API, генерирует Makefile проекта с помощью компонента MakeFusion и вызывает GCC для сборки. В принципе, ничего сложного. Вот схема:

Схема сборки проекта
Схема сборки проекта

Однако, большую сложность предоставлял именно обдумывание самой концепции сборки, а не её реализации.

Конец

Да, на этом, в принципе, всё. Если у вас есть какие-нибудь вопросы, то смело задавайте их, а если есть желание как-то поддержать проект, то можете поставить звёздочку на GitHub)

P.S.: Компонент BuildSys на сегодняшний день требует небольшой доработки, поэтому у вас может сразу и не заработать.

Оставлю ссылку на систему сборки Oriol здесь:

https://github.com/Anagar-Games/Oriol_Engine/tree/main/Oriol/Oriol_Dev/BuildSys

Спасибо за прочтение )

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


  1. vasille
    08.11.2025 09:31

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


  1. NeoCode
    08.11.2025 09:31

    ИМХО, если уж система сборки, то никаких других систем сборок и их артефактов (makefile) быть не должно. А то из всех этих обёрток вокруг обёрток неизбежно получается какой-то монстр: скрипт, генерирующий скрипт для скрипта, который в свою очередь тоже что-то генерирует.


  1. Jijiki
    08.11.2025 09:31

    я себе тоже сделал минимальный комплекс с трек моушн( в теории уже могу бежать на мид или грабить караваны на проходе ), и вижу какого этого, хочу пожелать вам успехов. )

    у меня Cmake с плюшками, мне почему-то понравилось при билде выводить версии библиотек

    Скрытый текст
    message(STATUS "Start checking versions")
    #
    
    # Проверка версии assimp
    find_package(assimp REQUIRED)
    
    if (assimp_FOUND)
        message(STATUS "ASSIMP version: ${assimp_VERSION}")
        # Or, if ASSIMP_VERSION is not directly available, you might find other version-related variables
        # message(STATUS "Assimp Library: ${assimp_LIBRARIES}")
        # message(STATUS "Assimp Include Dirs: ${assimp_INCLUDE_DIRS}")
    else()
        message(FATAL_ERROR "ASSIMP not found!")
    endif()
    
    # Проверка версии GLM
    find_package(glm REQUIRED)
    if("${glm_VERSION}" VERSION_LESS "1.0.2")
      message(STATUS "GLM version: ${glm_VERSION}")
      add_definitions(-DGLM_ENABLE_EXPERIMENTAL)
    else()
      message(WARNING "GLM version: ${GLM_VERSION}")
    endif()
    
    # Проверка версии freetype2
    find_package(Freetype REQUIRED)
    if("${FREETYPE_VERSION_STRING}" VERSION_LESS "1000008.0.2")
      message(STATUS "FREETYPE version: ${FREETYPE_VERSION_STRING}")
    else()
      #message(WARNING "FREETYPE version: ${FREETYPE_VERSION_STRING}")
      message(FATAL_ERROR "FREETYPE not found!")
    endif()
    
    # Проверка версии glew
    find_package(GLEW REQUIRED)
    if("${GLEW_VERSION}" VERSION_LESS "1000008.0.2")
      message(STATUS "GLEW version: ${GLEW_VERSION}")
    else()
      #message(WARNING "GLEW version: ${GLEW_VERSION}")
      message(FATAL_ERROR "GLEW not found!")
    endif()
    
    # Проверка версии glfw3
    find_package(glfw3 REQUIRED)
    if("${glfw3_VERSION}" VERSION_LESS "1000008.0.2")
      message(STATUS "GLFW3 version: ${glfw3_VERSION}")
    else()
      #message(WARNING "GLFW3 version: ${glfw3_VERSION}")
      message(FATAL_ERROR "GLFW3 not found!")
    endif()
    
    #
    message(STATUS "End checking versions")

    тут конечно немного грязные трюки вытащенные из lsp, зато при билде наглядно, мелоч а приятно )

    вообще показалось, что симейк удобный, вот бы они еще скрыли все это и просто как-то всё минимальными командами настраивалось


  1. Gargoni
    08.11.2025 09:31

    А json много редакторов поддерживает, там и форматирование и проверка синтаксиса.