Чтобы сгенерировать из этого файла презентацию в pdf, html или pptx, нужно воспользоваться утилитой Marp https://marp.app/ или одноимённым расширением VSCode https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode.

В сообществе часто спорят по поводу того чем является или не является ROS. ROS звучит буквально как операционная система для роботов, однако де-факто операционной системой не является. Как правило, все сходятся на том, что ROS включает в себя много разных сущностей - это и стандарт, и фреймворк, и формат взаимодействия приложений, и непосредственно программное обеспечение - стандартная библиотека, если хотите. Но конкретно в этом докладе я бы хотел поговорить о ROS в немного другом свете - как о системе сборки и дистрибьюции программного обеспечения, что тоже имеет место быть. Причём этот аспект я считаю весьма важным, потому что почти любое ROS-приложение в среднем на 95% состоит из подгруженного из пакетных репозиториев кода, из которых на долю ROS-экосистемы приходится меньшая часть.

Итак метод сборки и дострибьюции пакетов в ROS в значительной опирается на пакетных менеджер apt и пакетные базы debian/ubuntu (по статистике ros index 2100 пакетов представляют собой системные зависимости, предоставляемые операционной системой), а следовательно зависит от них. Многие пакеты ROS-экосистемы представляют в качестве рекомендуемого способа установки именно установку из своих репозиториев собранных заранее бинарных пакетов. Компиляция проектов их исходников редко практикуется и достаточно сложна. В целом, apt свойственны следующие проблемы.

Когда рассказываешь про nix часто у инженеров возникает прочная ассциация с Docker. А не решает ли Docker ту же самую проблему? Да, действительно, эти инструменты решают одну и ту же проблему, которую можно было бы кратко сформулировать так

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

Как добиться того, чтобы программа запущенная успешно на одном компьютере, была также успешно запущена на другом? Современные проекты представляют собой зачастую сложную комбинацию инструментов, библиотек и обеспечить воспроизводимость в этих условиях непросто. Классическое управление зависимостями в Linux-системах не позволяло добиться хорошей воспроизводимости. Docker появился во многом в ответ на эту проблему плохого управления зависимостями в операционной системе. Как это решил Docker?

Как мы знаем, Docker создаёт своеобразную песочницу вокруг вашего приложения и вы передаёте его вместе с ней, чтобы состояние машины пользователя не влияло на работоспособность. Идеальная картика выглядит так: на входе Dockerfile, на выходе Образ. Вроде всё круто

Но де-факто с одним и тем же докерфайлом вы можете получить кучу разных образов. Почему так происходит?

Если посмотреть вглубь, то можно обнаружить, что в типичном Docker-файле для ROS есть сразу несколько мест, которые сделают вашу сборку невоспроизводимой на другом компьютере: 1. hub.docker.com 2. apt-репозиторий 3. rosdep-репозиторий 3. файл, взятый по имени Но есть другие недостатки: 1. Возможность комбинировать зависимости (docker позволяет создавать контейнеры только наследуя от одного базового - нельзя добавить несколько базовых контейнеров) 2. Необходимость тянуть с собой все зависимости, даже если они представлены в системе

# Что предлагает Nix?

Именно эта идея и легла в основу диссертации автора nix под названием ___, где как раз и описывались недостатки классической системы использования динамических библиотек в unix-подобных системах. Данный подход получил название декларативным в противовес императивного.

nix использует функциональный язык программирования для описания процесса сборки. Тут можно сделать некоторое отступление о том, что ROS создан робототехниками для робототехников, а у них по прежнему был и остаётся доминирующим императивный подход к программированию, что обусловлено высокими требованиями к производительности и реальному времени исполнения. Собственно, императивная парадигма распространилась не только на сферу низкоуровневых программ, но и на управление операционной системой. Однако, сфера сборки ПО не требует гарантий реального времени или высокой производительности, в ней куда важнее как раз воспроизводимость, отсутствие неявных обращений к состоянию системы.

как выглядит типичное Nix-выражение. Это уравнение превращается в такой json-образный файл, где и прописаны все версии с хэшами конкретных зависимостей. Этот файл и является по сути инструкцией или чистой функцией, на выходе которой мы получаем конкретные артефакты в виде пакетов, бинарников, динамических библиотек и т.п.

А вот как это выглядит на диске. Заметьте, имя каждого пакета снабжается хэшом, который позволяет избежать коллизий при совпадении имён и даже совпадении имён и версий, а ещё даёт использовать несколько версий библиотеки одновременно. Откуда берётся этот хэш?

Собственно этот хэш и получается с помощью криптографической хэш-функции применённой ко всем входным зависимостям

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

# Текущее состояние nixpkgs