KasperskyOS Community Edition 1.3

Содержание

Сборка решения на базе KasperskyOS

Этот раздел содержит следующие сведения:

  • описание процесса сборки решения на базе KasperskyOS;
  • описания скриптов, библиотек и шаблонов сборки, поставляемых в KasperskyOS Community Edition;
  • сведения о том, как использовать динамические библиотеки в решении на базе KasperskyOS.

В этом разделе

Сборка образа решения

Общая схема сборки

Использование CMake из состава KasperskyOS Community Edition

Библиотеки CMake в составе KasperskyOS Community Edition

Сборка без использования CMake

Использование динамических библиотек

В начало
[Topic cmake_build_solution]

Сборка образа решения

Решение на базе KasperskyOS – системное ПО (включая ядро KasperskyOS и модуль безопасности Kaspersky Security Module) и прикладное ПО, интегрированные для работы в составе программно-аппаратного комплекса.

Подробнее см. "Структура и запуск решения на базе KasperskyOS".

Системные и прикладные программы

Программы по назначению делятся на два типа:

  • Системные программы создают инфраструктуру для прикладных программ (например, обеспечивают работу с аппаратурой, поддерживают механизм IPC, реализуют файловые системы и сетевые протоколы). Системные программы поставляются в составе KasperskyOS Community Edition. При необходимости вы можете разрабатывать собственные системные программы.
  • Прикладные программы предназначены для взаимодействия с пользователем решения и выполнения пользовательских задач. Прикладные программы отсутствуют в составе KasperskyOS Community Edition.

Сборка программ в процессе сборки решения

При сборке решения программы делятся на два типа:

  • Системные программы, поставляемые в составе KasperskyOS Community Edition в виде исполняемых файлов;
  • Системные или прикладные программы, требующие компоновки в исполняемый файл.

При этом программы, требующие компоновки, делятся на следующие типы:

  • Системные программы, реализующие IPC-интерфейс, для которого в составе KasperskyOS Community Edition поставляются готовые транспортные библиотеки.
  • Прикладные программы, реализующие собственный IPC-интерфейс. Для их сборки необходимо генерировать транспортные методы и типы с помощью компилятора NK.
  • Клиентские программы, не предоставляющие служб.

Сборка образа решения

В составе KasperskyOS Community Edition поставляются образ ядра KasperskyOS, а также исполняемые файлы некоторых системных программ и программ-драйверов, готовые к использованию в решении.

Специальная программа Einit, предназначенная для запуска всех остальных программ, а также модуль безопасности Kaspersky Security Module собираются под каждое конкретное решение и не поставляются в составе KasperskyOS Community Edition. Вместо этого в тулчейн KasperskyOS Community Edition включены утилиты для их сборки.

Общая пошаговая схема сборки описана в статье "Общая схема сборки". Сборку образа решения можно осуществлять:

В начало
[Topic cmake_solution_image]

Общая схема сборки

Для того чтобы собрать образ решения, необходимо выполнить следующие действия:

  1. Подготовить EDL-, CDL- и IDL-описания прикладных программ, а также файл init-описания (по умолчанию init.yaml) и файлы с описанием политики безопасности решения (по умолчанию security.psl).

    При сборке с CMake EDL-описание можно генерировать используя команду generate_edl_file().

  2. Для всех программ, кроме системных программ, поставляемых в составе KasperskyOS Community Edition, сгенерировать файлы *.edl.h.
  3. Для программ, реализующих собственный IPC-интерфейс, сгенерировать код транспортных методов и типов, используемых для формирования, отправки, приема и обработки IPC-сообщений.
  4. Собрать все программы, входящие в решение, при необходимости скомпоновав их с транспортными библиотеками системных или прикладных программ. Для сборки прикладных программ, реализующих собственный IPC-интерфейс, потребуются сгенерированный на шаге 3 код, содержащий транспортные методы и типы.
    • При сборке с CMake для этого используются стандартные команды сборки. Необходимые настройки кросс-компиляции производятся автоматически.
    • При сборке без CMake для этого необходимо вручную использовать кросс-компиляторы, входящие в состав KasperskyOS Community Edition.
  5. Собрать инициализирующую программу Einit.
    • При сборке с CMake программа Einit собирается в процессе сборки образа решения командами build_kos_qemu_image() и build_kos_hw_image().
    • При сборке без CMake для генерации кода программы Einit необходимо использовать утилиту einit. Программу Einit затем необходимо собрать с помощью кросс-компилятора, поставляемого в KasperskyOS Community Edition.
  6. Собрать модуль Kaspersky Security Module.
  7. Создать образ решения.

Пример 1

Для простейшего примера hello, входящего в состав KasperskyOS Community Edition, в котором содержится одна прикладная программа, не предоставляющая служб, схема сборки выглядит следующим образом:

Пример 2

Пример echo, входящий в состав KasperskyOS Community Edition, описывает простейший случай взаимодействия двух программ с помощью механизма IPC. Чтобы организовать такое взаимодействие, потребуется реализовать на сервере интерфейс с методом Ping и "поместить" службу Ping в новый компонент (например, Responder), а экземпляр этого компонента – в EDL-описание программы Server.

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

В начало
[Topic cmake_common_build_scheme]

Использование CMake из состава KasperskyOS Community Edition

Для автоматизации процесса подготовки образа решения нужно настроить систему сборки CMake. За основу можно взять параметры системы сборки, используемые в примерах из состава KasperskyOS Community Edition.

В файлах CMakeLists.txt используется стандартный синтаксис CMake, а также команды и макросы из библиотек, поставляемых в KasperskyOS Community Edition.

Рекомендованная структура директорий проекта

При создании решения на базе KasperskyOS рекомендуется использовать следующую структуру директорий в проекте:

  • В корне проекта создать корневой файл CMakeLists.txt, содержащий общие инструкции сборки для всего решения.
  • Исходный код каждой из разрабатываемых программ следует разместить в отдельной директории, в поддиректории src.
  • Создать файлы CMakeLists.txt для сборки каждой прикладной программы в соответствующих директориях.
  • Для генерации исходного кода программы Einit следует создать отдельную директорию einit, содержащую поддиректорию src, в которую следует поместить шаблоны init.yaml.in и security.psl.in.

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

  • Создать файл CMakeLists.txt для сборки программы Einit в директории einit.
  • Файлы EDL-, CDL- и IDL-описаний следует разместить в директории resources в корне проекта. (EDL-описание можно сгенерировать, используя команду generate_edl_file().)

Пример структуры директорий проекта

example$ tree . ├── CMakeLists.txt ├── hello │ ├── CMakeLists.txt │ ├── src │ │ ├── hello.c ├── einit │ ├── CMakeLists.txt │ ├── src │ │ ├── init.yaml.in │ │ ├── security.psl.in ├── resources │ ├── Hello.idl │ ├── Hello.cdl │ ├── Hello.edl

Сборка образа решения

Чтобы выполнить сборку образа решения, нужно использовать утилиту cmake (исполняемый файл toolchain/bin/cmake из состава KasperskyOS Community Edition).

Пример скрипта сборки:

build.sh

#!/bin/bash # Скрипт для запуска в корне проекта. # Сведения о параметрах запуска утилиты cmake можно # получить shell-командой cmake --help, а также из # официальной документации по CMake. export SDK_PREFIX="/opt/KasperskyOS-Community-Edition-<version>" export TARGET="aarch64-kos" export BOARD="RPI4_BCM2711" export CMAKE="$SDK_PREFIX/toolchain/bin/cmake" export BUILD="build" # Инициализация системы сборки $CMAKE \ -G "Unix Makefiles" \ -D CMAKE_BUILD_TYPE:STRING=Release \ -D CMAKE_TOOLCHAIN_FILE=$SDK_PREFIX/toolchain/share/toolchain-$TARGET-clang.cmake \ -D BOARD="$BOARD" \ -S . \ -B $BUILD # Сборка # Чтобы собрать образ решения для QEMU, нужно указать цель, заданную в # параметре NAME CMake-команды build_kos_qemu_image() в файле CMakeLists.txt # для сборки программы Einit. # Чтобы собрать образ решения для аппаратной платформы, нужно указать цель, # заданную в параметре NAME CMake-команды build_kos_hw_image() в файле # CMakeLists.txt для сборки программы Einit. # Чтобы собрать образ SD-карты для аппаратной платформы, нужно указать цель, # заданную в параметре IMAGE_NAME CMake-команды build_sd_image() в файле # CMakeLists.txt для сборки программы Einit. # Чтобы собрать образ решения для QEMU и запустить QEMU с этим образом, нужно # указать цель sim. $CMAKE --build $BUILD --target sim

В этом разделе

Корневой файл CMakeLists.txt

Файлы CMakeLists.txt для сборки прикладных программ

Файл CMakeLists.txt для сборки программы Einit

Шаблон init.yaml.in

Шаблон security.psl.in

В начало
[Topic cmake_using_sdk_cmake]

Корневой файл CMakeLists.txt

Корневой файл CMakeLists.txt содержит общие инструкции сборки для всего решения.

Корневой файл CMakeLists.txt должен содержать следующие команды:

  • cmake_minimum_required (VERSION 3.25) – указание минимальной поддерживаемой версии CMake.

    Для сборки решения на базе KasperskyOS требуется CMake версии не ниже 3.25.

    Требуемая версия CMake поставляется в составе KasperskyOS Community Edition и используется по умолчанию.

  • include (platform) – подключение CMake-библиотеки platform.
  • initialize_platform() – инициализация библиотеки platform.
  • project_header_default("STANDARD_GNU_17:YES" "STRICT_WARNINGS:NO") – установка флагов компилятора и компоновщика.
  • [Опционально] Подключение и настройка пакетов для поставляемых системных программ и драйверов, которые необходимо включить в решение:
    • Подключение пакета выполняется с помощью команды find_package().
    • После подключения пакета необходимо добавить директории, связанные с этим пакетом, в список директорий поиска с помощью команды include_directories().
    • Для некоторых пакетов также требуется установить значения свойств с помощью команды set_target_properties().

    CMake-описания системных программ и драйверов, поставляемых в составе KasperskyOS Community Edition, а также их экспортируемых переменных и свойств находятся в соответствующих файлах /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/lib/cmake/<имя программы>/<имя программы>-config.cmake

  • Сборка инициализирующей программы Einit должна быть выполнена с помощью команды add_subdirectory(einit).
  • Все прикладные программы, сборку которых необходимо выполнить, должны быть добавлены с помощью команды add_subdirectory(<имя директории программы>).

Пример корневого файла CMakeLists.txt

CMakeLists.txt

cmake_minimum_required(VERSION 3.25) project (example) # Инициализация библиотеки CMake для KasperskyOS SDK. include (platform) initialize_platform () # Установка флагов компилятора и компоновщика. project_header_default ("STANDARD_GNU_17:YES" "STRICT_WARNINGS:NO") # Подключение пакета, импортирующего компоненты для работы с виртуальной файловой системой. # Компоненты импортируются из файла: /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/lib/cmake/vfs/vfs-config.cmake find_package (vfs REQUIRED COMPONENTS ENTITY CLIENT_LIB) include_directories (${vfs_INCLUDE}) # Сборка прикладной программы Hello. add_subdirectory (hello) # Сборка инициализирующей программы Einit. add_subdirectory (einit)
В начало
[Topic cmake_lists_root]

Файлы CMakeLists.txt для сборки прикладных программ

Файл CMakeLists.txt для сборки прикладной программы должен содержать следующие команды:

  • include (platform/nk) – подключение библиотеки CMake для работы с компилятором NK.
  • project_header_default ("STANDARD_GNU_17:YES" "STRICT_WARNINGS:NO") – установка флагов компилятора и компоновщика.
  • EDL-описание класса процессов для программы можно сгенерировать, используя команду generate_edl_file().
  • Если программа предоставляет службы, используя механизм IPC, необходимо сгенерировать транспортный код:
    1. idl.h-файлы генерируются командой nk_build_idl_files()
    2. cdl.h-файлы генерируются командой nk_build_cdl_files()
    3. edl.h-файлы генерируются командой nk_build_edl_files()
  • add_executable (<имя программы> "<путь к файлу исходного кода программы>") – добавление цели для сборки программы.
  • add_dependencies (<имя программы> <имя цели сборки edl.h файла>) – добавление зависимости сборки программы от генерации edl.h-файла.
  • target_link_libraries (<имя программы> <список библиотек>) – определяет библиотеки, с которыми необходимо скомпоновать программу при сборке.

    Например, если программа использует файловый или сетевой ввод/вывод, то она должна быть скомпонована с транспортной библиотекой vfs::client.

    CMake-описания системных программ и драйверов, поставляемых в составе KasperskyOS Community Edition, а также их экспортированных переменных и свойств находятся в соответствующих файлах /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/lib/cmake/<имя программы>/<имя программы>-config.cmake

  • Для автоматического добавления описаний IPC-каналов в файл init.yaml при сборке решения необходимо определить свойство EXTRA_CONNECTIONS и присвоить ему значение с описаниями нужных IPC-каналов.

    Обратите внимание на отступы в начале строк в свойстве EXTRA_CONNECTIONS. Эти отступы необходимы для корректной подстановки значений в файл init.yaml и должны соответствовать требованиям к его синтаксису.

    Пример создания IPC-канала между процессами Client и Server:

    set_target_properties (Client PROPERTIES EXTRA_CONNECTIONS " - target: Server id: server_connection")

    В результате, при сборке решения, описание этого IPC-канала будет автоматически добавлено в файл init.yaml на этапе обработки макросов шаблона init.yaml.in.

  • Для автоматического добавления списка аргументов функции main() и словаря переменных окружения в файл init.yaml при сборке решения, необходимо определить свойства EXTRA_ARGS и EXTRA_ENV и присвоить им соответствующие значения.

    Обратите внимание на отступы в начале строк в свойствах EXTRA_ARGS и EXTRA_ENV. Эти отступы необходимы для корректной подстановки значений в файл init.yaml и должны соответствовать требованиям к его синтаксису.

    Пример передачи программе Client аргумента "-v" функции main() и переменной окружения VAR1 со значением VALUE1:

    set_target_properties (Client PROPERTIES EXTRA_ARGS " - \"-v\"" EXTRA_ENV " VAR1: VALUE1")

    В результате, при сборке решения, описание аргумента функции main()и значение переменной окружения будут автоматически добавлены в файл init.yaml на этапе обработки макросов шаблона init.yaml.in.

Пример файла CMakeLists.txt для сборки простой прикладной программы

CMakeLists.txt

project (hello) # Подключение CMake-библиотеки nk для работы с компилятором NK (nk-gen-c). include (platform/nk) # Установка флагов компилятора и компоновщика. project_header_default ("STANDARD_GNU_17:YES" "STRICT_WARNINGS:NO") # Задаем имя проекта, в который входит программа. set (LOCAL_MODULE_NAME "example") # Задаем имя программы. set (TASK_NAME "Hello") # Обратите внимание на содержание шаблонов init.yaml.in и security.psl.in # В них имена программ задаются как ${LOCAL_MODULE_NAME}.${TASK_NAME} # Задаем цели, которые будут использованы для создания генерируемых файлов программы. set (TASK_IDL_TARGET ${TASK_NAME}_idl) set (TASK_CDL_TARGET ${TASK_NAME}_cdl) set (TASK_EDL_TARGET ${TASK_NAME}_edl) # Добавляем цель сборки idl.h-файла. nk_build_idl_files (${TASK_IDL_TARGET} NK_MODULE ${LOCAL_MODULE_NAME} IDL "../resources/Hello.idl" ) # Добавляем цель сборки cdl.h-файла. nk_build_cdl_files (${TASK_CDL_TARGET} IDL_TARGET ${TASK_IDL_TARGET} NK_MODULE ${LOCAL_MODULE_NAME} CDL "../resources/Hello.cdl" ) # Добавляем цель сборки EDL-файла. Переменная EDL_FILE экспортируется # и содержит путь до сгенерированного EDL-файла. generate_edl_file (${TASK_NAME} PREFIX ${LOCAL_MODULE_NAME} ) # Добавляем цель сборки edl.h-файла. nk_build_edl_files (${TASK_EDL_TARGET} NK_MODULE ${LOCAL_MODULE_NAME} EDL ${EDL_FILE} ) # Определяем цель для сборки программы. add_executable (${TASK_NAME} "src/hello.c") # Библиотеки, с которыми программа компонуется при сборке. target_link_libraries (${TASK_NAME} PUBLIC vfs::client # Программа использует файловый ввод/вывод # и должна быть подключена как клиент к VFS ) # Добавление к цели Hello зависимости от цели Hello_edl. # Генерация edl.h-файла должна произойти ранее сборки цели Hello. add_dependencies (${TASK_NAME} ${TASK_EDL_TARGET})
В начало
[Topic cmake_lists_applied]

Файл CMakeLists.txt для сборки программы Einit

Файл CMakeLists.txt для сборки инициализирующей программы Einit должен содержать следующие команды:

  • include (platform/image) – подключение библиотеки CMake, содержащей скрипты сборки образа решения.
  • project_header_default ("STANDARD_GNU_17:YES" "STRICT_WARNINGS:NO") – установка флагов компилятора и компоновщика.
  • Настройка пакетов системных программ и драйверов, которые необходимо включить в решение.
    • Подключение пакета выполняется с помощью команды find_package ().
    • Для некоторых пакетов также требуется установить значения свойств с помощью команды set_target_properties ().

    CMake-описания системных программ и драйверов, поставляемых в составе KasperskyOS Community Edition, а также их экспортированных переменных и свойств находятся в соответствующих файлах /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/lib/cmake/<имя программы>/<имя программы>-config.cmake

  • Для автоматического добавления описаний IPC-каналов между процессами системных программ в файл init.yaml при сборке решения необходимо добавить эти каналы в свойство EXTRA_CONNECTIONS для соответствующих программ.

    Обратите внимание на отступы в начале строк в свойстве EXTRA_CONNECTIONS. Эти отступы необходимы для корректной подстановки значений в файл init.yaml и должны соответствовать требованиям к его синтаксису.

    Например, программа VFS по умолчанию не имеет канала для соединения с программой Env. Чтобы описание такого канала автоматически добавилось в файл init.yaml при сборке решения, необходимо добавить следующий вызов в файл CMakeLists.txt для сборки программы Einit:

    set_target_properties (vfs_entity::entity PROPERTIES EXTRA_CONNECTIONS " - target: env.Env id: {var: ENV_SERVICE_NAME, include: env/env.h}"

    В результате, при сборке решения, описание этого IPC-канала будет автоматически добавлено в файл init.yaml на этапе обработки макросов шаблона init.yaml.in.

  • Для автоматического добавления списка аргументов функции main() и словаря переменных окружения в файл init.yaml при сборке решения, необходимо определить свойства EXTRA_ARGS и EXTRA_ENV и присвоить им соответствующие значения.

    Обратите внимание на отступы в начале строк в свойствах EXTRA_ARGS и EXTRA_ENV. Эти отступы необходимы для корректной подстановки значений в файл init.yaml и должны соответствовать требованиям к его синтаксису.

    Пример передачи программе VfsEntity аргумента "-f fstab" функции main() и переменной окружения ROOTFS со значением ramdisk0,0 / ext2 0:

    set_target_properties (vfs_entity::entity PROPERTIES EXTRA_ARGS " - \"-f\" - \"fstab\"" EXTRA_ENV " ROOTFS: ramdisk0,0 / ext2 0")

    В результате, при сборке решения, описание аргумента функции main() и значение переменной окружения будут автоматически добавлены в файл init.yaml на этапе обработки макросов шаблона init.yaml.in.

  • set(ENTITIES <полный список программ, входящих в решение>) – определение переменной ENTITIES со списком исполняемых файлов всех программ, входящих в решение.
  • Одна или несколько команд для сборки образа решения:
    • build_kos_hw_image() – создает цель сборки образа решения для аппаратной платформы.
    • build_sd_image() – создает цель сборки образа SD-карты для запуска решения на аппаратной платформе.
    • build_kos_qemu_image() – создает цель сборки образа решения для QEMU.

Пример файла CMakeLists.txt для сборки программы Einit

CMakeLitsts.txt

project (einit) # Подключение библиотеки, содержащей скрипты сборки образа решения. include (platform/image) include (${KL_SDK_ROOT_PATH}/common/build-sd-image.cmake) # Установка флагов компилятора и компоновщика. project_header_default ("STANDARD_GNU_17:YES" "STRICT_WARNINGS:NO") # Определение переменной CONNECTIONS_CFG_FILE, содержащей путь к шаблону init.yaml.in. set (CONNECTIONS_CFG_FILE "src/init.yaml.in") # Определение переменной SECURITY_PSL, содержащей путь к шаблону security.psl.in. set (SECURITY_PSL "src/security.psl.in") # Настройка программы VFS. # По умолчанию программе VFS не сопоставляется программа, реализующая блочное устройство. # Если необходимо использовать блочное устройство, например ata из компонента ata, # необходимо задать это устройство в переменной blkdev::entity_REPLACEMENT # Больше информации об экспортированных переменных и свойств программы VFS # см. в /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/lib/cmake/vfs/vfs-config.cmake # find_package(ata) # set_target_properties (vfs_entity::entity PROPERTIES blkdev::entity_REPLACEMENT ata::entity) # В простейшем случае не нужно взаимодействовать с диском, # поэтому мы устанавливаем значение переменной blkdev::entity_REPLACEMENT равным пустой строке set_target_properties (vfs_entity::entity PROPERTIES blkdev::entity_REPLACEMENT "") # Определение переменной ENTITIES со списком исполняемых файлов программ # Важно включить все программы, входящие в проект, кроме программы Einit. # Обратите внимание на то, что имя исполняемого файла программы должно # совпадать с названием цели, указанной в add_executable() в CMakeLists.txt для сборки этой программы. set(ENTITIES vfs_entity::entity Hello ) # Создание цели сборки с именем kos-image, которая является образом решения для аппаратной платформы. build_kos_hw_image (kos-image EINIT_ENTITY EinitHw CONNECTIONS_CFG ${CONNECTIONS_CFG_FILE} SECURITY_PSL ${SECURITY_PSL} IMAGE_FILES ${ENTITIES} ) # Создание цели сборки с именем sd-image, которую можно использовать для создании образа SD-карты # для запуска решения на аппаратной платформе. build_sd_image (sd-image KOS_IMAGE_TARGET kos-image ) # Создание цели сборки с именем kos-qemu-image, которая является образом решения для QEMU. build_kos_qemu_image (kos-qemu-image EINIT_ENTITY EinitQemu CONNECTIONS_CFG ${CONNECTIONS_CFG_FILE} SECURITY_PSL ${SECURITY_PSL} IMAGE_FILES ${ENTITIES} )
В начало
[Topic cmake_lists_einit]

Шаблон init.yaml.in

Шаблон init.yaml.in используется для автоматической генерации части файла init.yaml перед сборкой программы Einit средствами CMake.

Использование шаблона init.yaml.in позволяет не добавлять описания системных программ и IPC-каналов для соединения с ними в файл init.yaml вручную.

Шаблон init.yaml.in должен содержать следующие данные:

  • Корневой ключ entities.
  • Список всех прикладных программ, входящих в решение.
  • Для прикладных программ, использующих механизм IPC, необходимо указать список IPC-каналов, соединяющих эту программу с другими программами.

    IPC-каналы, соединяющие эту программу с другими прикладными программами указываются вручную или в файле CMakeLists.txt этой программы с помощью свойства EXTRA_CONNECTIONS.

    Для указания списка IPC-каналов, соединяющих эту программу с системными программами, входящими в состав KasperskyOS Community Edition, используются следующие макросы:

    • @INIT_<имя программы>_ENTITY_CONNECTIONS@ – при сборке заменяется на список IPC-каналов со всеми системными программами, с которыми скомпонована прикладная программа. Поля target и id заполняются в соответствии с файлами connect.yaml из состава KasperskyOS Community Edition, расположенными в /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include/<имя системной программы>).

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

    • @INIT_<имя программы>_ENTITY_CONNECTIONS+@ – при сборке добавляет список IPC-каналов со всеми системными программами, с которыми скомпонована прикладная программа, к списку IPC-каналов, заданному вручную. Этот макрос не добавляет корневой ключ connections.

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

  • Макросы @INIT_<имя программы>_ENTITY_CONNECTIONS@ и @INIT_<имя программы>_ENTITY_CONNECTIONS+@ также добавляют список соединений для каждой программы, заданный в свойстве EXTRA_CONNECTIONS при сборке этой программы.
  • Если необходимо передать программе аргументы функции main(), заданные в свойстве EXTRA_ARGS при сборке этой программы, то необходимо использовать следующие макросы:
    • @INIT_<имя программы>_ENTITY_ARGS@ – при сборке заменяется на список аргументов функции main(), заданный в свойстве EXTRA_ARGS. Этот макрос добавляет корневой ключ args.
    • @INIT_<имя программы>_ENTITY_ARGS+@ – при сборке добавляет список аргументов функции main(), заданный в свойстве EXTRA_ARGS, к списку аргументов заданному вручную. Этот макрос не добавляет корневой ключ args.
  • Если необходимо передать программе значения переменных окружения, заданные в свойстве EXTRA_ENV при сборке этой программы, то необходимо использовать следующие макросы:
    • @INIT_<имя программы>_ENTITY_ENV@ – при сборке заменяется на словарь переменных окружения и их значений, заданный в свойстве EXTRA_ENV. Этот макрос добавляет корневой ключ env.
    • @INIT_<имя программы>_ENTITY_ENV+@ – при сборке добавляет словарь переменных окружения и их значений, заданный в свойстве EXTRA_ENV, к переменным заданным вручную. Этот макрос не добавляет корневой ключ env.
  • Макрос @INIT_EXTERNAL_ENTITIES@, который при сборке заменяется на список системных программ, с которыми скомпонована прикладная программа, и их IPC-каналов, аргументов функции main() и значений переменных окружения.

Пример шаблона init.yaml.in

init.yaml.in

entities: - name: ping.Client connections: # Программа "Client" может обращаться к "Server". - target: ping.Server id: server_connection @INIT_Client_ENTITY_CONNECTIONS+@ @INIT_Client_ENTITY_ARGS@ @INIT_Client_ENTITY_ENV@ - name: ping.Server @INIT_Server_ENTITY_CONNECTIONS@ @INIT_EXTERNAL_ENTITIES@

При сборке программы Einit из этого шаблона будет сгенерирован следующий файл init.yaml:

init.yaml

entities: - name: ping.Client connections: # Программа "Client" может обращаться к "Server" - target: ping.Server id: server_connection - target: kl.VfsEntity id: {var: _VFS_CONNECTION_ID, include: vfs/defs.h} args: - "-v" env: VAR1: VALUE1 - name: ping.Server connections: - target: kl.VfsEntity id: {var: _VFS_CONNECTION_ID, include: vfs/defs.h} - name: kl.VfsEntity path: VFS args: - "-f" - "fstab" env: ROOTFS: ramdisk0,0 / ext2
В начало
[Topic cmake_yaml_templates]

Шаблон security.psl.in

Шаблон security.psl.in используется для автоматической генерации части файла security.psl перед сборкой программы Einit средствами CMake.

Файл security.psl содержит часть описания политики безопасности решения.

Использование шаблона security.psl.in позволяет не добавлять EDL-описания системных программ в файл security.psl вручную.

Шаблон security.psl.in должен содержать описание политики безопасности решения, созданное вручную, включая следующие декларации:

  • установка глобальных параметров политики безопасности решения;
  • включение PSL-файлов в описание политики безопасности решения;
  • включение EDL-файлов прикладных программ в описание политики безопасности решения;
  • создание объектов моделей безопасности;
  • привязка методов моделей безопасности к событиям безопасности;
  • создание профилей аудита безопасности.

Для автоматического включения системных программ, необходимо использовать макрос @INIT_EXTERNAL_ENTITIES@.

Пример шаблона security.psl.in

security.psl.in

execute: kl.core.Execute use nk.base._ use EDL Einit use EDL kl.core.Core use EDL Client use EDL Server @INIT_EXTERNAL_ENTITIES@ /* Запуск программ разрешен */ execute { grant () } /* Отправка и получение запросов, ответов и ошибок разрешены. */ request { grant () } response { grant () } error { grant () } /* Обращения по интерфейсу безопасности игнорируются. */ security { grant () }
В начало
[Topic cmake_psl_templates]

Библиотеки CMake в составе KasperskyOS Community Edition

Этот раздел содержит описание библиотек, поставляемых в KasperskyOS Community Edition и предназначенных для автоматизации сборки решения на базе KasperskyOS.

В этом разделе

Библиотека platform

Библиотека nk

Библиотека image

Библиотека build_sd_image

Библиотека kpa

В начало
[Topic cmake_libs]

Библиотека platform

Библиотека platform содержит следующие команды:

  • initialize_platform() – команда для инициализации библиотеки platform.

    Команда initialize_platform() может вызываться с параметром FORCE_STATIC, который включает принудительную статическую компоновку исполняемых файлов:

    • По умолчанию, если тулчейн в составе KasperskyOS SDK поддерживает динамическую компоновку, то команда initialize_platform() делает так, что для сборки всех исполняемых файлов, заданных через CMake-команды add_executable(), флаг -rdynamic используется автоматически.
    • При вызове initialize_platform (FORCE_STATIC) в корневом файле CMakeLists.txt тулчейн, поддерживающий динамическую компоновку, выполняет статическую компоновку исполняемых файлов.

    Команда initialize_platform() может вызываться с параметром NO_NEW_VERSION_CHECK, который отключает проверку наличия обновлений SDK и передачу версии SDK на сервер "Лаборатории Касперского".

    Чтобы отключить проверку наличия обновлений SDK и передачу данных версии SDK на сервер Kaspersky при сборке решения используйте следующий вызов: initialize_platform(NO_NEW_VERSION_CHECK). Подробнее о политике предоставления данных см. "Предоставление данных".

  • project_static_executable_header_default() – команда для включения принудительной статической компоновки исполняемых файлов, заданных через последующие CMake-команды add_executable() в одном файле CMakeLists.txt. Тулчейн, поддерживающий динамическую компоновку, выполняет статическую компоновку этих исполняемых файлов.
  • platform_target_force_static() – команда для включения принудительной статической компоновки исполняемого файла, заданного через CMake-команду add_executable(). Тулчейн, поддерживающий динамическую компоновку, выполняет статическую компоновку этого исполняемого файла. Например, если вызываются CMake-команды add_executable(client "src/client.c") и platform_target_force_static(client), то для программы client выполняется статическая компоновка.
  • project_header_default() – команда для указания флагов компиляции.

    Параметры команды задаются в виде пар, состоящих из флага компиляции и его значения: "FLAG_1:VALUE_1" "FLAG_2:VALUE_2" ... "FLAG_N:VALUE_N". CMake-библиотека platform преобразует эти пары в параметры компилятора.

При использовании команд initialize_platform(FORCE_STATIC), project_static_executable_header_default() и platform_target_force_static() могут возникать ошибки компоновки, если статический вариант требуемых библиотек отсутствует (например, не собран или не поставлен в составе KasperskyOS SDK). Но даже при наличии статического варианта требуемых библиотек эти ошибки могут возникать из-за того, что при использовании команд initialize_platform(FORCE_STATIC), project_static_executable_header_default() и platform_target_force_static() система сборки по умолчанию может выполнять поиск динамического варианта требуемых библиотек, а не статического, как ожидается. Чтобы избежать ошибок, нужно, во-первых, обеспечить наличие статического варианта требуемых библиотек, во-вторых, настроить систему сборки на поиск статических библиотек (для некоторых библиотек этой возможности может не быть) либо явно задавать компоновку со статическими библиотеками.

Примеры настройки системы сборки на поиск статических библиотек:

set (fmt_USE_STATIC ON) find_package (fmt REQUIRED) set (fdn_USE_STATIC ON) find_package (fdn REQUIRED) set (sqlite_wrapper_USE_STATIC ON) find_package (sqlite_wrapper REQUIRED)

Пример, в котором явно задана компоновка со статической библиотекой:

target_link_libraries(${PROJECT_NAME} PUBLIC logger::logger-static)

Подробнее об использовании динамических библиотек см. "Использование динамических библиотек".

Эти команды используются в файлах CmakeLists.txt для программы Einit и прикладных программ.

В начало
[Topic cmake_platform_lib]

Библиотека nk

Этот раздел содержит описание команд и макросов CMake-библиотеки для работы с компилятором NK.

В этом разделе

generate_edl_file()

nk_build_idl_files()

nk_build_cdl_files()

nk_build_edl_files()

Генерация транспортного кода для разработки на языке C++

В начало
[Topic cmake_nk_lib]

generate_edl_file()

Команда объявлена в файле /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/nk2.cmake.

generate_edl_file(NAME ...)

Команда генерирует EDL-файл с описанием класса процессов.

Параметры:

  • NAME – имя создаваемого EDL-файла. Обязательный параметр.
  • PREFIX – в этом параметре необходимо указать имя класса процессов, исключив из него имя EDL-файла. Например, если имя класса процессов, для которого создается EDL-файл, определено как kl.core.NameServer, то в параметре PREFIX необходимо передать значение kl.core.
  • EDL_COMPONENTS – имя компонента и его экземпляра, которые будут включены в EDL-файл. Например: EDL_COMPONENTS "env: kl.Env". Для включения нескольких компонентов нужно использовать несколько параметров EDL_COMPONENTS.
  • SECURITY – квалифицированное имя метода интерфейса безопасности, который будет включен в EDL-файл.
  • OUTPUT_DIR – директория, где будет создан EDL-файл. По умолчанию ${CMAKE_CURRENT_BINARY_DIR}.

В результате работы команды переменная EDL_FILE экспортируется и содержит путь до сгенерированного EDL-файла.

Пример вызова:

generate_edl_file(${ENTITY_NAME} EDL_COMPONENTS "env: kl.Env")

Пример использования команды см. в статье "Файлы CMakeLists.txt для сборки прикладных программ".

В начало
[Topic cmake_generate_edl]

nk_build_idl_files()

Команда объявлена в файле /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/nk2.cmake.

nk_build_idl_files(NAME ...)

Команда создает CMake-цель для генерации .idl.h-файлов для одного или нескольких заданных IDL-файлов при помощи компилятора NK.

Параметры:

  • NAME – имя CMake-цели для сборки .idl.h-файлов. Если цель еще не создана, то она будет создана с помощью add_library() с указанным именем. Обязательный параметр.
  • NOINSTALL – если указана эта опция, то файлы будут только сгенерированы в рабочей директории, но не будут установлены в глобальные директории: ${CMAKE_BINARY_DIR}/_headers_ ${CMAKE_BINARY_DIR}/_headers_/${PROJECT_NAME}.
  • NK_MODULE – в этом параметре необходимо указать имя пакета, исключив из него имя IDL-файла. Например, если в IDL-описании имя пакета задано как kl.core.NameServer, то в параметре NK_MODULE необходимо передать значение kl.core.
  • WORKING_DIRECTORY – рабочая директория для вызова компилятора NK, по умолчанию: ${CMAKE_CURRENT_BINARY_DIR}.
  • DEPENDS – дополнительные цели сборки, от которых зависит IDL-файл.

    Для добавления нескольких целей нужно использовать несколько параметров DEPENDS.

  • IDL – путь к IDL-файлу, для которого генерируется idl.h-файл. Обязательный параметр.

    Для добавления нескольких IDL-файлов нужно использовать несколько параметров IDL.

    Если один IDL-файл импортирует другой IDL-файл, то генерацию idl.h-файлов нужно производить в порядке, необходимом для соблюдения зависимостей (сначала самые вложенные).

  • NK_FLAGS – дополнительные флаги для NK компилятора.

Пример вызова:

nk_build_idl_files (echo_idl_files NK_MODULE "echo" IDL "resources/Ping.idl" NK_FLAGS "--extended-errors" "--trace-client-ipc=headers")

Пример использования команды см. в статье "Файлы CMakeLists.txt для сборки прикладных программ".

В начало
[Topic cmake_build_idl]

nk_build_cdl_files()

Команда объявлена в файле /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/nk2.cmake.

nk_build_cdl_files(NAME ...)

Команда создает CMake-цель для генерации .cdl.h-файлов для одного или нескольких заданных CDL-файлов при помощи компилятора NK.

Параметры:

  • NAME – имя CMake-цели для сборки .cdl.h-файлов. Если цель еще не создана, то она будет создана с помощью add_library() с указанным именем. Обязательный параметр.
  • NOINSTALL – если указана эта опция, то файлы будут только сгенерированы в рабочей директории, но не установлены в глобальные директории: ${CMAKE_BINARY_DIR}/_headers_ ${CMAKE_BINARY_DIR}/_headers_/${PROJECT_NAME}.
  • IDL_TARGET – цель сборки .idl.h-файлов для IDL-файлов, содержащих описания служб, предоставляемых компонентами, описанными в CDL-файлах.
  • NK_MODULE – в этом параметре необходимо указать имя компонента, исключив из него имя CDL-файла. Например, если в CDL-описании имя компонента задано как kl.core.NameServer, то в параметре NK_MODULE необходимо передать значение kl.core.
  • WORKING_DIRECTORY – рабочая директория для вызова компилятора NK, по умолчанию: ${CMAKE_CURRENT_BINARY_DIR}.
  • DEPENDS – дополнительные цели сборки, от которых зависит CDL-файл.

    Для добавления нескольких целей нужно использовать несколько параметров DEPENDS.

  • CDL – путь к CDL-файлу, для которого генерируется .cdl.h-файл. Обязательный параметр.

    Для добавления нескольких CDL-файлов нужно использовать несколько параметров CDL.

  • NK_FLAGS – дополнительные флаги для NK компилятора.

Пример вызова:

nk_build_cdl_files (echo_cdl_files IDL_TARGET echo_idl_files NK_MODULE "echo" CDL "resources/Ping.cdl")

Пример использования команды см. в статье "Файлы CMakeLists.txt для сборки прикладных программ".

В начало
[Topic cmake_build_cdl]

nk_build_edl_files()

Команда объявлена в файле /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/nk2.cmake.

nk_build_edl_files(NAME ...)

Команда создает CMake-цель для генерации .edl.h-файла для одного заданного EDL-файла при помощи компилятора NK.

Параметры:

  • NAME – имя CMake-цели сборки .edl.h-файла. Если цель еще не создана, то она будет создана с помощью add_library() с указанным именем. Обязательный параметр.
  • NOINSTALL – если указана эта опция, то файлы будут только сгенерированы в рабочей директории, но не установлены в глобальные директории: ${CMAKE_BINARY_DIR}/_headers_ ${CMAKE_BINARY_DIR}/_headers_/${PROJECT_NAME}.
  • CDL_TARGET – цель сборки .cdl.h-файлов для CDL-файлов, содержащих описания компонентов EDL-файла, для которого выполняется сборка.
  • IDL_TARGET – цель сборки .idl.h-файлов для IDL-файлов, содержащих описания интерфейсов EDL-файла, для которого выполняется сборка.
  • NK_MODULE – в этом параметре необходимо указать имя класса процессов, исключив из него имя EDL-файла. Например, если в EDL-описании имя класса процессов задано как kl.core.NameServer, то в параметре NK_MODULE необходимо передать значение kl.core.
  • WORKING_DIRECTORY – рабочая директория для вызова компилятора NK, по умолчанию: ${CMAKE_CURRENT_BINARY_DIR}.
  • DEPENDS – дополнительные цели сборки, от которых зависит EDL-файл.

    Для добавления нескольких целей нужно использовать несколько параметров DEPENDS.

  • EDL – путь к EDL файлу, для которого генерируется edl.h-файл. Обязательный параметр.
  • NK_FLAGS – дополнительные флаги для NK компилятора.

Примеры вызова:

nk_build_edl_files (echo_server_edl_files CDL_TARGET echo_cdl_files NK_MODULE "echo" EDL "resources/Server.edl") nk_build_edl_files (echo_client_edl_files NK_MODULE "echo" EDL "resources/Client.edl" NK_FLAGS "--extended-errors")

Пример использования команды см. в статье "Файлы CMakeLists.txt для сборки прикладных программ".

В начало
[Topic cmake_build_edl]

Генерация транспортного кода для разработки на языке C++

Для генерации транспортных прокси-объектов и стабов с помощью генератора nkppmeta при сборке решения используются CMake-команды add_nk_idl(), add_nk_cdl() и add_nk_edl().

В этом разделе

add_nk_idl()

add_nk_cdl()

add_nk_edl()

В начало
[Topic cmake_cpp]

add_nk_idl()

Команда объявлена в файле /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/nk2.cmake.

add_nk_idl(NAME IDL_FILE ...)

Команда создает CMake-цель для генерации заголовочного файла *.idl.cpp.h для заданного IDL-файла при помощи компилятора nkppmeta. Также команда создает библиотеку, содержащую транспортный код для заданного интерфейса. Для компоновки с этой библиотекой необходимо использовать команду bind_nk_targets().

Генерируемые заголовочные файлы содержат представление на языке C++ для интерфейса и типов данных, описанных в IDL-файле, а также методы, необходимые для использования прокси-объектов и стабов.

Параметры:

  • NAME – имя CMake-цели. Обязательный параметр.
  • IDL_FILE – путь к IDL-файлу. Обязательный параметр.
  • NK_MODULE – в этом параметре необходимо указать имя пакета, исключив из него имя IDL-файла. Например, если в IDL-описании имя пакета задано как kl.core.NameServer, то в параметре NK_MODULE необходимо передать значение kl.core.
  • LANG – в этом параметре необходимо указать значение CXX.

Пример вызова:

add_nk_idl (ANIMAL_IDL "${CMAKE_SOURCE_DIR}/resources/Animal.idl" NK_MODULE "example" LANG "CXX")
В начало
[Topic add_nk_idl]

add_nk_cdl()

Команда объявлена в файле /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/nk2.cmake.

add_nk_cdl(NAME CDL_FILE ...)

Команда создает CMake-цель для генерации файла *.cdl.cpp.h для заданного CDL-файла при помощи компилятора nkppmeta. Команда также создает библиотеку, содержащую транспортный код для заданного компонента. Для компоновки с этой библиотекой необходимо использовать команду bind_nk_targets().

Файл *.cdl.cpp.h содержит дерево вложенных компонентов и служб, предоставляемых компонентом, описанным в CDL-файле.

Параметры:

  • NAME – имя CMake-цели. Обязательный параметр.
  • CDL_FILE – путь к CDL-файлу. Обязательный параметр.
  • NK_MODULE – в этом параметре необходимо указать имя компонента, исключив из него имя CDL-файла. Например, если в CDL-описании имя компонента задано как kl.core.NameServer, то в параметре NK_MODULE необходимо передать значение kl.core.
  • LANG – в этом параметре необходимо указать значение CXX.

Пример вызова:

add_nk_cdl (CAT_CDL "${CMAKE_SOURCE_DIR}/resources/Cat.cdl" NK_MODULE "example" LANG "CXX")
В начало
[Topic add_nk_cdl]

add_nk_edl()

Команда объявлена в файле /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/nk2.cmake.

add_nk_edl(NAME EDL_FILE ...)

Команда создает CMake-цель для генерации файла *.edl.cpp.h для заданного EDL-файла при помощи компилятора nkppmeta. Также команда создает библиотеку, содержащую транспортный код для серверной или клиентской программы. Для компоновки с этой библиотекой необходимо использовать команду bind_nk_targets().

Файл *.edl.cpp.h содержит дерево вложенных компонентов и служб, предоставляемых классом процессов, описанным в EDL-файле.

Параметры:

  • NAME – имя CMake-цели. Обязательный параметр.
  • EDL_FILE – путь к EDL-файлу. Обязательный параметр.
  • NK_MODULE – в этом параметре необходимо указать имя класса процессов, исключив из него имя EDL-файла. Например, если в EDL-описании имя класса процессов задано как kl.core.NameServer, то в параметре NK_MODULE необходимо передать значение kl.core.
  • LANG – в этом параметре необходимо указать значение CXX.

Пример вызова:

add_nk_edl (SERVER_EDL "${CMAKE_SOURCE_DIR}/resources/Server.edl" NK_MODULE "example" LANG "CXX")
В начало
[Topic add_nk_edl]

Библиотека image

Этот раздел содержит описание команд и макросов CMake-библиотеки image , входящей в состав KasperskyOS Community Edition и содержащей скрипты сборки образа решения.

В этом разделе

build_kos_qemu_image()

build_kos_hw_image()

В начало
[Topic cmake_image_lib]

build_kos_qemu_image()

Команда объявлена в файле /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/image.cmake.

build_kos_qemu_image(NAME ...)

Команда создает CMake-цель сборки образа решения для QEMU.

Параметры:

  • NAME – имя CMake-цели для сборки образа решения. Обязательный параметр.
  • PERFCNT_KERNEL – использовать ядро со счетчиками производительности, если оно доступно в составе KasperskyOS Community Edition.
  • EINIT_ENTITY – имя исполняемого файла, из которого будет запускаться программа Einit.
  • EXTRA_XDL_DIR – дополнительные директории для включения при сборке программы Einit.
  • CONNECTIONS_CFG – путь до файла init.yaml или шаблона init.yaml.in.
  • SECURITY_PSL – путь до файла security.psl или шаблона security.psl.in.
  • KLOG_ENTITY – цель сборки системной программы Klog, отвечающей за аудит безопасности. Если цель не указана – аудит не выполняется.
  • QEMU_FLAGS – дополнительные флаги для запуска QEMU.
  • IMAGE_BINARY_DIR_BIN – директория для финального образа и других артефактов, по умолчанию совпадает с CMAKE_CURRENT_BINARY_DIR.
  • NO_AUTO_BLOB_CONTAINER – не включать в образ решения программу BlobContainer, необходимую для работы с динамическими библиотеками в разделяемой памяти. Подробнее см. "Включение системной программы BlobContainer в решение на базе KasperskyOS".
  • PACK_DEPS, PACK_DEPS_COPY_ONLY, PACK_DEPS_LIBS_PATH, PACK_DEPS_COPY_TARGET – параметры, задающие способ добавления динамических библиотек в образ решения.
  • GINGER_ENABLE – включить (GINGER_ENABLE TRUE) или выключить (GINGER_ENABLE FALSE) шаблонизатор Ginger.
  • GINGER_DEFINITIONS – набор переменных, используемых при раскрытии PSL-шаблонов Ginger. Например, GINGER_DEFINITIONS "foo=bar baz=quux USE_DYNLD" задает переменную foo со значением bar, переменную baz со значением quux и переменную USE_DYNLD со значением TRUE. Переменная USE_DYNLD имеет значением TRUE, поскольку переменные, используемые при раскрытии PSL-шаблонов Ginger, по умолчанию имеют значение TRUE.
  • GINGER_DUMP_DIR – путь к директории, где будут сохранены PSL-файлы, полученные из PSL-шаблонов Ginger. Эти PSL-файлы нужны только для того, чтобы проверить, что получилось в результате раскрытия PSL-шаблонов Ginger, и не используются для генерации исходного кода модуля безопасности Kaspersky Security Module. (При генерации исходного кода модуля безопасности PSL-шаблоны Ginger раскрываются в памяти независимо от того, используется параметр GINGER_DUMP_DIR или нет.) Имена PSL-файлов формируются на основе абсолютных путей к PSL-шаблонам Ginger. Например, PSL-файл foo!bar!baz.psl соответствует PSL-шаблону Ginger, расположенному по пути /foo/bar/baz.psl.
  • IMAGE_FILES – исполняемые файлы прикладных и системных программ (кроме программы Einit) и любые другие файлы для добавления в образ ROMFS.

    Для добавления нескольких программ или файлов можно использовать несколько параметров IMAGE_FILES.

  • <пути до файлов> – свободные параметры, тоже что IMAGE_FILES.

Пример вызова:

build_kos_qemu_image ( kos-qemu-image EINIT_ENTITY EinitQemu CONNECTIONS_CFG "src/init.yaml.in" SECURITY_CFG "src/security.cfg.in" IMAGE_FILES ${ENTITIES})

Пример использования команды см. в статье "Файлы CMakeLists.txt для сборки программы Einit".

В начало
[Topic cmake_build_qemu]

build_kos_hw_image()

Команда объявлена в файле /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/image.cmake.

build_kos_hw_image(NAME ...)

Команда создает CMake-цель сборки образа решения для аппаратной платформы.

Параметры:

  • NAME – имя CMake-цели для сборки образа решения. Обязательный параметр.
  • PERFCNT_KERNEL – использовать ядро со счетчиками производительности, если оно доступно в составе KasperskyOS Community Edition.
  • EINIT_ENTITY – имя исполняемого файла, из которого будет запускаться программа Einit.
  • EXTRA_XDL_DIR – дополнительные директории для включения при сборке программы Einit.
  • CONNECTIONS_CFG – путь до файла init.yaml или шаблона init.yaml.in.
  • SECURITY_PSL – путь до файла security.psl или шаблона security.psl.in.
  • KLOG_ENTITY – цель сборки системной программы Klog, отвечающей за аудит безопасности. Если цель не указана – аудит не выполняется.
  • IMAGE_BINARY_DIR_BIN – директория для финального образа и других артефактов, по умолчанию CMAKE_CURRENT_BINARY_DIR.
  • NO_AUTO_BLOB_CONTAINER – не включать в образ решения программу BlobContainer, необходимую для работы с динамическими библиотеками в разделяемой памяти. Подробнее см. "Включение системной программы BlobContainer в решение на базе KasperskyOS".
  • PACK_DEPS, PACK_DEPS_COPY_ONLY, PACK_DEPS_LIBS_PATH, PACK_DEPS_COPY_TARGET – параметры, задающие способ добавления динамических библиотек в образ решения.
  • GINGER_ENABLE – включить (GINGER_ENABLE TRUE) или выключить (GINGER_ENABLE FALSE) шаблонизатор Ginger.
  • GINGER_DEFINITIONS – набор переменных, используемых при раскрытии PSL-шаблонов Ginger. Например, GINGER_DEFINITIONS "foo=bar baz=quux USE_DYNLD" задает переменную foo со значением bar, переменную baz со значением quux и переменную USE_DYNLD со значением TRUE. Переменная USE_DYNLD имеет значением TRUE, поскольку переменные, используемые при раскрытии PSL-шаблонов Ginger, по умолчанию имеют значение TRUE.
  • GINGER_DUMP_DIR – путь к директории, где будут сохранены PSL-файлы, полученные из PSL-шаблонов Ginger. Эти PSL-файлы нужны только для того, чтобы проверить, что получилось в результате раскрытия PSL-шаблонов Ginger, и не используются для генерации исходного кода модуля безопасности Kaspersky Security Module. (При генерации исходного кода модуля безопасности PSL-шаблоны Ginger раскрываются в памяти независимо от того, используется параметр GINGER_DUMP_DIR или нет.) Имена PSL-файлов формируются на основе абсолютных путей к PSL-шаблонам Ginger. Например, PSL-файл foo!bar!baz.psl соответствует PSL-шаблону Ginger, расположенному по пути /foo/bar/baz.psl.
  • IMAGE_FILES – исполняемые файлы прикладных и системных программ (кроме программы Einit) и любые другие файлы для добавления в образ ROMFS.

    Для добавления нескольких программ или файлов можно использовать несколько параметров IMAGE_FILES.

  • <пути до файлов> – свободные параметры, тоже что IMAGE_FILES.

Пример вызова:

build_kos_hw_image ( kos-image EINIT_ENTITY EinitHw CONNECTIONS_CFG "src/init.yaml.in" SECURITY_CFG "src/security.cfg.in" IMAGE_FILES ${ENTITIES})

Пример использования команды см. в статье "Файлы CMakeLists.txt для сборки программы Einit".

В начало
[Topic cmake_build_hw]

Библиотека build_sd_image

Библиотека build_sd_image входит в состав KasperskyOS SDK и содержит команду build_sd_image(). Эта команда объявлена в файле /opt/KasperskyOS-Community-Edition-<version>/common/build-sd-image.cmake.

build_sd_image(IMAGE_NAME ...)

Команда создает CMake-цель сборки образа SD-карты для запуска решения на аппаратной платформе.

Параметры:

  • IMAGE_NAME – имя CMake-цели для сборки образа SD-карты для запуска решения на аппаратной платформе. Обязательный параметр.
  • KOS_IMAGE_TARGET – имя CMake-цели для сборки образа решения для аппаратной платформы, который будет добавлен в образ SD-карты.
  • KOS_COPY_PATH – путь к директории, в которую будет скопирован образ решения для аппаратной платформы перед добавлением в образ SD-карты.
  • IMAGE_FS – путь к корневой директории файловой системы, которая будет использоваться для образа SD-карты. Значение по умолчанию: ${CMAKE_BINARY_DIR}/hdd.
  • OUTPUT_IMAGE_NAME – имя образа SD-карты.
  • DISK_SIZE – размер создаваемого образа SD-карты в мегабайтах. Значение по умолчанию: 1024 МБ.
  • PARTITION_CMD – набор параметров, которые будут использоваться для создания и настройки разделов в образе SD-карты. Разделяйте параметры знаком пробела.

Пример вызова:

include (${KL_SDK_ROOT_PATH}/common/build-sd-image.cmake) set (IMAGE_FS "${CMAKE_BINARY_DIR}/hdd") set (IMAGE_PART1_FS "${IMAGE_FS}/part1") set (IMAGE_PART2_FS "${IMAGE_FS}/part2") set (DISK_IMAGE hdd.img) build_sd_image (sd-image KOS_IMAGE_TARGET kos-image KOS_COPY_PATH ${IMAGE_PART1_FS} IMAGE_FS ${IMAGE_FS} DISK_SIZE 512 OUTPUT_IMAGE_NAME ${DISK_IMAGE} PARTITION_CMD -p1 ${IMAGE_PART1_FS} -%1 50 -f1 fat32 -p2 ${IMAGE_PART2_FS} -%2 50 -f2 ext4)
В начало
[Topic cmake_build_sd]

Библиотека kpa

Этот раздел содержит описание команд CMake-библиотеки kpa, предназначенной для сборки KPA-пакетов.

В этом разделе

add_kpa_package()

add_kpa_component()

В начало
[Topic cmake_kpa_lib]

add_kpa_package()

Команда объявлена в файле /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/kpa.cmake.

add_kpa_package(KPA_TARGET_NAME ...)

Команда создает CMake-цель для сборки KPA-пакета. При сборке этой цели автоматически создается манифест KPA-пакета и сам KPA-пакет, в который включаются все компоненты, добавленные к этой цели с помощью CMake-команды add_kpa_component().

Параметры:

  • KPA_TARGET_NAME – имя CMake-цели. Обязательный параметр.
  • MANIFEST_V – версия манифеста KPA-пакета. Обязательный параметр. Должен иметь значение "2".
  • VERSION – версия KPA-пакета. Значение по умолчанию: PROJECT_VERSION.
  • ID – идентификатор KPA-пакета. Значение по умолчанию: KPA_TARGET_NAME.
  • DEVELOPER_ID – идентификатор разработчика. Значение по умолчанию: "unspecified".
  • DONT_VERIFY – если задан, не будет выполняться проверка наличия всех компонентов KPA-пакета, указанных в его манифесте и отсутствия неуказанных компонентов, а также расчет контрольных сумм компонентов KPA-пакета и сравнение их с указанными в манифесте KPA-пакета.

Свойства создаваемой CMake-цели:

  • KPA_OUTPUT_DIR – директория для размещения KPA-пакета.
  • KPA_OUTPUT_NAME – имя файла .kpa без расширения. Значение по умолчанию: ${DEVELOPER_ID}.${ID}.

Пример вызова:

include (platform/kpa) add_kpa_package (Hello.kpa ALL ID "hello" DEVELOPER_ID test_dev MANIFEST_V "2") set_target_properties(Hello.kpa PROPERTIES KPA_OUTPUT_NAME "hello")
В начало
[Topic cmake_kpa_package]

add_kpa_component()

Команда объявлена в файле /opt/KasperskyOS-Community-Edition-<version>/toolchain/share/cmake/Modules/platform/kpa.cmake.

add_kpa_component(PACKAGE_NAME MODE ...)

Команда добавляет компонент в указанную CMake-цель сборки KPA-пакета. Эту команду можно вызывать несколько раз для одной цели сборки KPA-пакета. Цель сборки KPA-пакета создается командой add_kpa_package().

Параметры:

  • PACKAGE_NAME – имя CMake-цели сборки KPA-пакета. Обязательный параметр.
  • MODE – тип компонента. Обязательный параметр. Возможны следующие значения:
    • LIBRARY – компонент является динамической библиотекой. Необходимо указать полный путь к файлу или имя CMake-цели. При установке KPA-пакета помещается в директорию /<имя_пакета>/lib.
    • FILES – компонент является файлом. Необходимо указать полный путь к файлу. При установке KPA-пакета помещается в директорию /<имя_пакета>/res.
    • DIRECTORY – компонент является директорией с файлами. Необходимо указать полный путь к директории. При установке KPA-пакета помещается в директорию /<имя_пакета>/res.
    • RUN_CONFIGURATION – компонент является конфигурацией запуска программы. Необходимо указать следующие параметры:
      • ID – уникальный в рамках KPA-пакета идентификатор конфигурации запуска программы. Обязательный параметр.
      • NAME – имя конфигурации запуска. Обязательный параметр.
      • TYPE – тип конфигурации запуска: "gui" – процесс с графическим пользовательским интерфейсом или "service" – процесс-служба. Обязательный параметр.
      • PATH – полный путь к исполняемому файлу компонента после установки KPA-пакета относительно директории /<имя_пакета>.
      • EIID – класс безопасности программы. Обязательный параметр.
      • PRIMARY – указывает, является эта конфигурация запуска первичной при старте программы.
      • AUTORUN – указывает, является ли эта конфигурация запускаемой автоматически.
      • ARGS – список аргументов командной строки для запуска программы в виде массива строк.
      • ENV – список переменных окружения для запуска программы.
    • RESOURCE – используется для добавления произвольных данных в KPA-пакет. Необходимо указать следующие параметры:
      • полный путь к файлу или директории, содержащей данные. Обязательный параметр
      • В параметре TYPE указать тип данных: "res", "bin", "lib" или "manifestLocale". Обязательный параметр. Подробнее см. "Список объектов components".
      • Опционально, в параметре DIRECTORY_PATH указать путь к директории, в которую данные будут помещены после установки KPA-пакета, относительно директории /<имя_пакета>/res.

Примеры вызова:

include (platform/kpa) # Добавление исполняемого файла программы add_kpa_component(Hello.kpa RESOURCE ".build/aarch64-kos-debug/hello/Hello" TYPE "bin" DIRECTORY_PATH "bin/") # Добавление конфигурации запуска программы add_kpa_component(Hello.kpa RUN_CONFIGURATION "app" NAME "Hello app" TYPE "service" EIID "hello.Hello" PATH "bin/Hello")
В начало
[Topic cmake_kpa_component]

Сборка без использования CMake

Этот раздел содержит описание скриптов, утилит, компиляторов и шаблонов сборки, поставляемых в KasperskyOS Community Edition.

Эти инструменты можно использовать:

  • в других системах сборки;
  • для выполнения отдельных шагов сборки;
  • для изучения особенностей сборки и написания собственной системы сборки.

Общая схема сборки образа решения приведена в статье "Общая схема сборки".

В этом разделе

Инструменты для сборки решения

В начало
[Topic cmake_no_cmake_build]

Инструменты для сборки решения

Этот раздел содержит описание скриптов, утилит, компиляторов и шаблонов сборки, поставляемых в KasperskyOS Community Edition.

В этом разделе

Утилиты и скрипты сборки

Кросс-компиляторы

В начало
[Topic solution_build_tools]

Утилиты и скрипты сборки

В состав KasperskyOS Community Edition входят следующие утилиты и скрипты сборки:

  • nk-gen-c

    Компилятор NK (nk-gen-c) генерирует транспортный код на основе IDL-, CDL- и EDL-описаний. Транспортный код нужен для формирования, отправки, приема и обработки IPC-сообщений.

  • nk-psl-gen-c

    Компилятор nk-psl-gen-c генерирует исходный код модуля безопасности Kaspersky Security Module на языке C на основе описания политики безопасности решения и IDL-, CDL-, EDL-описаний. Также компилятор nk-psl-gen-c позволяет генерировать исходный код тестов политики безопасности решения на языке C на основе тестов политики безопасности решения на языке PAL.

  • einit

    Утилита einit позволяет автоматизировать создание кода инициализирующей программы Einit. Эта программа первой запускается при загрузке KasperskyOS и запускает остальные программы, а также создает IPC-каналы между ними.

  • makekss

    Скрипт makekss создает модуль безопасности Kaspersky Security Module.

  • makeimg

    Скрипт makeimg создает финальный загружаемый образ решения на базе KasperskyOS со всеми запускаемыми программами и модулем Kaspersky Security Module.

В начало
[Topic build_utilities_and_scripts]

nk-gen-c

Компилятор NK (nk-gen-c) генерирует транспортный код на основе IDL-, CDL-, EDL-описаний.

Компилятор nk-gen-c принимает IDL-, CDL- или EDL-файл и создает следующие файлы:

  • Файл *.*dl.h, содержащий транспортный код.
  • Файл *.*dl.nk.d, в котором перечислены зависимости созданного файла *.*dl.h от IDL- и CDL-файлов. Файл *.*dl.nk.d создается для системы сборки.

Синтаксис shell-команды для запуска компилятора nk-gen-c:

nk-gen-c -I <SYSROOT_INCLUDE_PATH> [-I <PATH>]... [-o <PATH>] [--types] [--interface] [--endpoints] [--client] [--server] [--extended-errors] [(--deprecated-no-extended-errors)] [--trace-client-ipc {headers|dump}] [--trace-server-ipc {headers|dump}] [--ipc-trace-method-filter <METHOD 1>[,<METHOD 2>]...] [-h|--help] [--version] <FILE>

Базовые параметры:

  • FILE

    Путь к IDL-, CDL- или EDL-файлу, для которого необходимо сгенерировать транспортный код.

  • -I <SYSROOT_INCLUDE_PATH>

    Путь к директории sysroot-*-kos/include из состава KasperskyOS SDK.

  • -I <PATH>

    Эти параметры нужно использовать, чтобы задать пути к директориям, содержащим IDL-, CDL-файлы, на которые ссылается файл, заданный через параметр FILE.

  • -o <PATH>

    Путь к существующей директории, в которую будут помещены созданные файлы. Если этот параметр не указан, созданные файлы будут помещены в текущую директорию.

  • -h|--help

    Выводит текст справки.

  • --version

    Выводит версию компилятора nk-gen-c.

  • --extended-errors

    Это параметр дает возможность использовать интерфейсные методы с одним или несколькими error-параметрами произвольных IDL-типов. (Клиент работает с error-параметрами как с выходными параметрами.)

    Если не указывать параметр --extended-errors, можно использовать интерфейсные методы только с одним error-параметром status IDL-типа UInt16, значение которого клиент получает через код возврата интерфейсного метода. Такой способ передачи error-параметров является устаревшим и перестанет поддерживаться в будущем, поэтому рекомендуется всегда указывать параметр --extended-errors.

  • --deprecated-no-extended-errors

    Этот параметр является параметром по умолчанию и дает возможность использовать интерфейсные методы только с одним error-параметром status IDL-типа UInt16, значение которого клиент получает через код возврата интерфейсного метода. Если параметр --deprecated-no-extended-errors не указан, и при этом не указан параметр --extended-errors, то также можно использовать этот способ передачи error-параметров, но будет выведено предупреждение о необходимости указать параметр --extended-errors либо параметр --deprecated-no-extended-errors. (Указать один из этих параметров нужно потому, что в будущем параметр --deprecated-no-extended-errors перестанет быть параметром по умолчанию, и без явного задания способа передачи error-параметров работа компилятора nk-gen-c будет завершаться с ошибкой.)

Выборочная генерация транспортного кода

Чтобы уменьшить объем генерируемого транспортного кода, можно использовать флаги выборочной генерации транспортного кода. Например, для программ, реализующих службы, можно использовать флаг --server, а для программ, использующих службы, можно использовать флаг --client.

Если ни один из флагов выборочной генерации транспортного кода не указан, компилятор nk-gen-c генерирует для заданного IDL-, CDL- или EDL-файла транспортный код со всеми возможными методами и типами.

Флаги выборочной генерации транспортного кода для IDL-файла:

  • --types

    Транспортный код включает типы, соответствующие IDL-типам из заданного IDL-файла, а также импортируемым в этот файл IDL-типам, которые используются в IDL-типах заданного IDL-файла. При этом типы, соответствующие импортируемым IDL-константам и псевдонимам импортируемых IDL-типов, не включаются в файл *.idl.h. Чтобы использовать типы, соответствующие импортируемым IDL-константам и псевдонимам импортируемых IDL-типов, нужно отдельно сгенерировать транспортный код для IDL-файлов, из которых осуществляется импорт.

  • --interface

    Транспортный код соответствует флагу --types, а также включает типы структур фиксированной части IPC-запросов и IPC-ответов для интерфейсных методов, сигнатуры которых указаны в заданном IDL-файле. Кроме того, транспортный код содержит константы с размерами арен IPC-сообщений.

  • --client

    Транспортный код соответствует флагу --interface, а также включает тип прокси-объекта, метод инициализации прокси-объекта и интерфейсные методы, указанные в заданном IDL-файле.

  • --server

    Транспортный код соответствует флагу --interface, а также включает типы и диспетчер (dispatch-метод), используемые для обработки IPC-запросов, соответствующих интерфейсным методам, указанным в заданном IDL-файле.

Флаги выборочной генерации транспортного кода для CDL- или EDL-файла:

  • --types

    Транспортный код включает типы, соответствующие IDL-типам, которые используются в параметрах методов служб, предоставляемых компонентом (для заданного CDL-файла) или классом процессов (для заданного EDL-файла).

  • --endpoints

    Транспортный код соответствует флагу --types, а также включает типы структур фиксированной части IPC-запросов и IPC-ответов для методов служб, предоставляемых компонентом (для заданного CDL-файла) или классом процессов (для заданного EDL-файла). Кроме того, транспортный код содержит константы с размерами арен IPC-сообщений.

  • --client

    Транспортный код соответствует флагу --types, а также включает типы структур фиксированной части IPC-запросов и IPC-ответов для методов служб, предоставляемых компонентом (для заданного CDL-файла) или классом процессов (для заданного EDL-файла). Кроме того, транспортный код содержит константы с размерами арен IPC-сообщений, а также типы прокси-объектов, методы инициализации прокси-объектов и методы служб, предоставляемых компонентом (для заданного CDL-файла) или классом процессов (для заданного EDL-файла).

  • --server

    Транспортный код соответствует флагу --types, а также включает типы и диспетчеры (dispatch-методы), используемые для обработки IPC-запросов, соответствующих службам, предоставляемым компонентом (для заданного CDL-файла) или классом процессов (для заданного EDL-файла). Кроме того, транспортный код содержит константы с размерами арен IPC-сообщений, а также типы стабов, методы инициализации стабов и типы структур фиксированной части IPC-запросов и IPC-ответов для методов служб, предоставляемых компонентом (для заданного CDL-файла) или классом процессов (для заданного EDL-файла).

Вывод диагностических данных об отправке и приеме IPC-сообщений

Транспортный код может формировать диагностические данные об отправке и приеме IPC-сообщений и выводить эти данные через стандартный вывод ошибок. Чтобы генерировать транспортный код с такими возможностями, нужно использовать следующие параметры:

  • --trace-client-ipc {headers|dump}

    Код вывода диагностических данных исполняется непосредственно перед выполнением системного вызова Call() и сразу после его выполнения. Если указано значение headers, диагностические данные включают идентификатор метода службы (MID), идентификатор службы (RIID), размер фиксированной части IPC-сообщения в байтах, содержимое дескриптора арены IPC-сообщения, размер арены IPC-сообщения в байтах и размер использованной части арены IPC-сообщения в байтах. Если указано значение dump, диагностические данные дополнительно включают содержимое фиксированной части и арены IPC-сообщения в шестнадцатеричном представлении.

    При использовании этого параметра нужно указать флаг выборочной генерации транспортного кода --client либо не указывать флаги выборочной генерации транспортного кода.

  • --trace-server-ipc {headers|dump}

    Код вывода диагностических данных исполняется непосредственно перед вызовом функции, реализующей интерфейсный метод, и сразу после выполнения этой функции, то есть при вызове диспетчера (dispatch-метода) в промежутке между выполнением системных вызовов Recv() и Reply(). Если указано значение headers, диагностические данные включают идентификатор метода службы (MID), идентификатор службы (RIID), размер фиксированной части IPC-сообщения в байтах, содержимое дескриптора арены IPC-сообщения, размер арены IPC-сообщения в байтах и размер использованной части арены IPC-сообщения в байтах. Если указано значение dump, диагностические данные дополнительно включают содержимое фиксированной части и арены IPC-сообщения в шестнадцатеричном представлении.

    При использовании этого параметра нужно указать флаг выборочной генерации транспортного кода --server либо не указывать флаги выборочной генерации транспортного кода.

  • --ipc-trace-method-filter <METHOD 1>[,<METHOD 2>]...

    Вывод диагностических данных выполняется, если только вызваны заданные интерфейсные методы. В качестве значения METHOD можно использовать имя интерфейсного метода либо конструкцию <имя пакета>:<имя интерфейсного метода>. Имя пакета и имя интерфейсного метода указаны в IDL-файле.

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

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

В начало
[Topic nkgenc]

nk-psl-gen-c

Компилятор nk-psl-gen-c генерирует исходный код модуля безопасности Kaspersky Security Module на языке C на основе описания политики безопасности решения и IDL-, CDL-, EDL-описаний. Этот код используется скриптом makekss.

Компилятор nk-psl-gen-c также позволяет генерировать исходный код тестов политики безопасности решения на языке C на основе тестов политики безопасности решения на языке PAL.

Синтаксис shell-команды для запуска компилятора nk-psl-gen-c:

nk-psl-gen-c {-I|--include-dir} <SYSROOT_INCLUDE_DIR> [{-I|--include-dir} <DIR>]... [{-o|--output} <FILE>] [--out-tests <FILE>] [{-t|--tests} <ARG>] [{-a|--audit} <FILE>] [--enable-preprocessor] [--preprocessor-definition=<VAR_NAME>[=<VAR_VALUE>]]... [--preprocessor-dump-dir <DIR>] [-h|--help] [--version] <INPUT>

Параметры:

  • INPUT

    Путь к верхнеуровневому файлу описания политики безопасности решения. Как правило, это файл security.psl.

  • {-I|--include-dir} <SYSROOT_INCLUDE_DIR>

    Путь к директории sysroot-*-kos/include из состава KasperskyOS SDK.

  • {-I|--include-dir} <DIR>

    Эти параметры нужно использовать, чтобы задать пути к директориям с IDL-, CDL-, EDL-файлам, относящимися к решению, а также пути к директориям, которые содержат вспомогательные файлы из состава KasperskyOS SDK (common, toolchain/include).

  • {-o|--output} <FILE>

    Путь к файлу, в который будет сохранен исходный код модуля безопасности Kaspersky Security Module и опционально исходный код тестов политики безопасности решения. Путь должен включать существующие директории.

  • --out-tests <FILE>

    Путь к файлу, в который будет сохранен исходный код тестов политики безопасности решения.

  • {-t|--tests} <ARG>

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

    • skip – исходный код тестов не генерируется. Это значение используется по умолчанию, если параметр {-t|--tests} <ARG> не указан.
    • generate – исходный код тестов генерируется. Если исходный код тестов генерируется, то рекомендуется использовать параметр --out-tests <FILE>, иначе исходный код тестов будет сохранен в одном файле с исходным кодом модуля безопасности Kaspersky Security Module, что может привести к ошибкам при сборке.
  • {-a|--audit} <FILE>

    Путь к файлу, в который будет сохранен исходный код декодера аудита на языке C.

  • --enable-preprocessor

    Включает шаблонизатор Ginger.

  • --preprocessor-definition=<VAR_NAME>[=<VAR_VALUE>]

    Эти параметры нужно использовать, чтобы задать переменные, используемые при раскрытии PSL-шаблонов Ginger. Например, --preprocessor-definition=foo=bar задает переменную foo со значением bar, а --preprocessor-definition=USE_DYNLD задает переменную USE_DYNLD со значением TRUE. Переменная USE_DYNLD имеет значение TRUE, поскольку переменные, используемые при раскрытии PSL-шаблонов Ginger, по умолчанию имеют значение TRUE.

  • --preprocessor-dump-dir <DIR>

    Путь к директории, где будут сохранены PSL-файлы, полученные из PSL-шаблонов Ginger. Эти PSL-файлы нужны только для того, чтобы проверить, что получилось в результате раскрытия PSL-шаблонов Ginger, и не используются для генерации исходного кода модуля безопасности Kaspersky Security Module. (При генерации исходного кода модуля безопасности PSL-шаблоны Ginger раскрываются в памяти независимо от того, используется параметр --preprocessor-dump-dir <DIR> или нет.) Имена PSL-файлов формируются на основе абсолютных путей к PSL-шаблонам Ginger. Например, PSL-файл foo!bar!baz.psl соответствует PSL-шаблону Ginger, расположенному по пути /foo/bar/baz.psl.

  • -h|--help

    Выводит текст справки.

  • --version

    Выводит версию компилятора nk-psl-gen-c.

В начало
[Topic nkpslgenc]

einit

Утилита einit позволяет автоматизировать создание кода инициализирующей программы Einit.

Утилита einit принимает описание инициализации решения (по умолчанию файл init.yaml), а также EDL-, CDL- и IDL-описания, и создает файл с исходным кодом инициализирующей программы Einit. Программу Einit затем необходимо собрать с помощью кросс-компилятора языка C, поставляемого в KasperskyOS Community Edition.

Синтаксис использования утилиты einit:

einit -I PATH -o PATH [--help] FILE

Параметры:

  • FILE

    Путь к файлу init.yaml.

  • -I PATH

    Путь к директории, содержащей вспомогательные файлы (включая EDL-, CDL- и IDL-описания), необходимые для генерации инициализирующей программы. По умолчанию эти файлы располагаются в директории /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/include.

  • -o, --out-file PATH

    Путь к создаваемому .c файлу с кодом инициализирующей программы.

  • -h, --help

    Отображает текст справки.

В начало
[Topic einit_tool]

makekss

Скрипт makekss создает модуль безопасности Kaspersky Security Module.

Скрипт вызывает компилятор nk-psl-gen-c для генерации исходного кода модуля безопасности и затем компилирует полученный код, вызывая компилятор C, поставляемый в KasperskyOS Community Edition.

Скрипт создает модуль безопасности из описания политики безопасности решения.

Синтаксис использования скрипта makekss:

makekss --target=ARCH --module=PATH --with-nk="PATH" --with-nktype="TYPE" --with-nkflags="FLAGS" [--output="PATH"][--help][--with-cc="PATH"][--with-cflags="FLAGS"] FILE

Параметры:

  • FILE

    Путь к верхнеуровневому файлу описания политики безопасности решения.

  • --target=ARCH

    Архитектура процессора, для которой производится сборка.

  • --module=-lPATH

    Путь к библиотеке ksm_kss. Этот ключ передается компилятору C для компоновки с этой библиотекой.

  • --with-nk=PATH

    Путь к компилятору nk-psl-gen-c, который будет использоваться для генерации исходного кода модуля безопасности. По умолчанию компилятор расположен в /opt/KasperskyOS-Community-Edition-<version>/toolchain/bin/nk-psl-gen-c.

  • --with-nktype="TYPE"

    Указывает на тип компилятора NK, который будет использоваться. Для использования компилятора nk-psl-gen-c, необходимо указать тип psl.

  • --with-nkflags="FLAGS"

    Параметры, с которыми вызывается компилятор nk-psl-gen-c.

    Компилятору nk-psl-gen-c потребуется доступ ко всем EDL- CDL- и IDL-описаниям. Для того, чтобы компилятор nk-psl-gen-c мог найти эти описания, нужно передать пути к расположению этих описаний в параметре --with-nkflags, используя параметр -I компилятора nk-psl-gen-c.

  • --output=PATH

    Путь к создаваемому файлу модуля безопасности.

  • --with-cc=PATH

    Путь к компилятору C, который будет использоваться для сборки модуля безопасности. По умолчанию используется компилятор, поставляемый в KasperskyOS Community Edition.

  • --with-cflags=FLAGS

    Параметры, с которыми вызывается компилятор C.

  • -h, --help

    Отображает текст справки.

В начало
[Topic makekss]

makeimg

Скрипт makeimg создает финальный загружаемый образ решения на базе KasperskyOS со всеми исполняемыми файлами программ и модулем Kaspersky Security Module.

Скрипт принимает список файлов, включая исполняемые файлы всех программ, которые нужно добавить в ROMFS загружаемого образа, и создает следующие файлы:

  • образ решения;
  • образ решения без таблиц символов (.stripped);
  • образ решения с отладочными таблицами символов (.dbg.syms).

Синтаксис использования скрипта makeimg:

makeimg --target=ARCH --sys-root=PATH --with-toolchain=PATH --ldscript=PATH --img-src=PATH --img-dst=PATH --with-init=PATH [--with-extra-asflags=FLAGS][--with-extra-ldflags=FLAGS][--help] FILES

Параметры:

  • FILES

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

    Модуль безопасности (ksm.module) нужно указывать явно, иначе он не будет включен в образ решения. Программу Einit указывать не нужно, так как она будет включена в образ решения автоматически.

  • --target=ARCH

    Архитектура, для которой производится сборка.

  • --sys-root=PATH

    Путь к корневой директории sysroot. По умолчанию эта директория расположена в /opt/KasperskyOS-Community-Edition-<version>/sysroot-*-kos/.

  • --with-toolchain=PATH

    Путь к набору вспомогательных утилит, необходимых для сборки решения. По умолчанию эти утилиты расположены в /opt/KasperskyOS-Community-Edition-<version>/toolchain/.

  • --ldscript=PATH

    Путь к скрипту компоновщика, необходимому для сборки решения. По умолчанию этот скрипт расположен в /opt/KasperskyOS-Community-Edition-<version>/libexec/aarch64-kos/.

  • --img-src=PATH

    Путь к заранее скомпилированному ядру KasperskyOS. По умолчанию ядро расположено в /opt/KasperskyOS-Community-Edition-<version>/libexec/aarch64-kos/.

  • --img-dst=PATH

    Путь к создаваемому файлу образа.

  • --with-init=PATH

    Путь к исполняемому файлу инициализирующей программы Einit.

  • --with-extra-asflags=FLAGS

    Дополнительные флаги для ассемблера AS.

  • --with-extra-ldflags=FLAGS

    Дополнительные флаги для компоновщика LD.

  • -h, --help

    Отображает текст справки.

В начало
[Topic makeimg]

Кросс-компиляторы

В тулчейн из состава KasperskyOS SDK входит один или несколько компиляторов Clang, а также компилятор rustc. В директории toolchain/bin находятся следующие файлы:

  • исполняемые файлы компиляторов (например, clang-17, rustc);
  • исполняемые файлы компоновщиков (например, aarch64-kos-ld);
  • исполняемые файлы ассемблеров (например, aarch64-kos-as);
  • Bash-скрипты для компилятора Clang (например, aarch64-kos-clang, aarch64-kos-clang++).

Особенности работы компоновщика

При выполнении сборки исполняемого файла программы компоновщик по умолчанию связывает следующие библиотеки в указанном порядке:

  1. libc – стандартная библиотека языка C.
  2. libm – библиотека, реализующая математические функции стандартной библиотеки языка C.
  3. libvfs_stubs – библиотека, содержащая заглушки функций ввода/вывода (например, open, socket, read, write).
  4. libkos – библиотека для доступа к службам ядра KasperskyOS.
  5. libenv – библиотека подсистемы настройки окружения программ (переменных окружения, аргументов функции main и пользовательских конфигураций).
  6. libsrvtransport-u – библиотека поддержки IPC между процессами и ядром.
В начало
[Topic crosscompliers]

Использование динамических библиотек

В решении на базе KasperskyOS можно использовать динамические библиотеки (файлы *.so). По сравнению со статическими библиотеками (файлами *.a) динамические библиотеки дают следующие преимущества:

  • Экономия оперативной памяти.

    Несколько процессов могут использовать один экземпляр динамической библиотеки. Также исполняемый файл и динамические библиотеки в одном процессе могут использовать один экземпляр динамической библиотеки.

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

  • Удобство обновления ПО.

    Обновление динамической библиотеки распространяется на все зависимые от нее исполняемые файлы и динамические библиотеки без их повторной сборки.

  • Возможность реализовать механизм плагинов.

    Плагины для компонентов решения представляют собой динамические библиотеки.

  • Совместное использование кода и данных.

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

Динамические библиотеки поставляются в составе KasperskyOS Community Edition, а также могут быть созданы разработчиком решения на базе KasperskyOS. Работоспособность сторонних динамических библиотек не гарантируется.

В настоящее время из-за технических ограничений в решении на базе KasperskyOS нельзя использовать libc.so и libpthread.so.

В этом разделе

Условия, необходимые для использования динамических библиотек

Жизненный цикл динамической библиотеки

Включение системной программы BlobContainer в решение на базе KasperskyOS

Сборка динамических библиотек

Добавление динамических библиотек в решение на базе KasperskyOS

В начало
[Topic shared_libraries]

Условия, необходимые для использования динамических библиотек

Чтобы использовать динамические библиотеки в решении на базе KasperskyOS, нужно выполнить следующие условия:

  1. Процессы, использующие динамические библиотеки, должны иметь доступ к файловым системам, в которых хранятся файлы динамических библиотек. Доступ к файловым системам обеспечивается VFS, которая является отдельным процессом. VFS и другое ПО, с помощью которого VFS работает с накопителем (например драйвер накопителя), не должны использовать динамические библиотеки.
  2. Системная программа BlobContainer должна быть включена в решение.
  3. Исполняемые файлы, использующие динамические библиотеки, должны быть собраны с флагом -rdynamic (с динамической компоновкой).

    CMake-команда initialize_platform() делает так, что для сборки всех исполняемых файлов, заданных через CMake-команды add_executable(), этот флаг используется автоматически.

Если CMake-команда initialize_platform(FORCE_STATIC) указана в корневом файле CMakeLists.txt, то тулчейн выполняет статическую компоновку исполняемых файлов.

CMake-команда project_static_executable_header_default() влияет на сборку исполняемых файлов, заданных через последующие CMake-команды add_executable() в одном файле CMakeLists.txt. Тулчейн выполняет статическую компоновку этих исполняемых файлов.

CMake-команда platform_target_force_static() влияет на сборку одного исполняемого файла, заданного через CMake-команду add_executable(). Тулчейн выполняет статическую компоновку этого исполняемого файла.

Исполняемый файл, который собирается с флагом -rdynamic, компонуется со статической библиотекой, если динамическая библиотека не найдена. Например, если используется CMake-команда target_link_libraries(client -lm), исполняемый файл программы client компонуется со статической библиотекой libm.a, если динамическая библиотека libm.so не найдена.

В начало
[Topic shared_libraries_use_conditions]

Жизненный цикл динамической библиотеки

Жизненный цикл динамической библиотеки включает следующие стадии:

  1. Загрузка в память.

    Динамическая библиотека, скомпонованная с исполняемым файлом, загружается в разделяемую память при запуске процесса, созданного на основе этого исполняемого файла. Также процесс может загрузить динамическую библиотеку в разделяемую память вызовом функции dlopen() интерфейса POSIX. Динамическая библиотека может быть скомпонована с другими динамическими библиотеками, поэтому исполняемый файл зависит не только от непосредственно скомпонованной с ним динамической библиотеки, но и от всего графа зависимостей этой библиотеки. Динамическая библиотека загружается в разделяемую память совместно с всеми динамическими библиотеками, от которых зависит.

    Один экземпляр динамической библиотеки загружается в разделяемую память независимо от того, сколько процессов использует эту библиотеку. (Точнее, в разделяемую память загружается только часть динамической библиотеки, включающая код и доступные только на чтение данные. Другая часть динамической библиотеки загружается в память каждого процесса, который использует эту библиотеку.) Динамическая библиотека, от которой зависит нескольких других динамических библиотек, загружается в разделяемую память в единственном экземпляре.

    Если задать через переменную окружения LD_PRELOAD список динамических библиотек, то эти динамические библиотеки будут загружены в разделяемую память, даже если исполняемый файл не зависит от них. (Элементами списка должны быть абсолютные или относительные пути к динамическим библиотекам, разделенные двоеточием, например: LD_PRELOAD=libmalloc.so:libfree.so:/usr/somepath/lib/libfoo.so.) Функции, которые экспортируются динамическими библиотеками, указанными в LD_PRELOAD, замещают одноименные функции, которые экспортируются другими динамическими библиотеками. Это можно использовать для целей отладки, если требуется подменить функции, импортируемые из динамических библиотек.

    Загрузчик динамических библиотек выполняет поиск динамических библиотек в следующем порядке:

    1. По абсолютным путям, заданным через переменную окружения LD_LIBRARY_PATH.

      Пути должны быть разделены двоеточием, например: LD_LIBRARY_PATH=/usr/lib:/home/user/lib.

    2. По абсолютным путям, заданным в поле DT_RUNPATH или DT_RPATH секции .dynamic исполняемых файлов и динамических библиотек.

      При компоновке исполняемых файлов и динамических библиотек могут быть заданы пути, по которым загрузчик динамических библиотек будет выполнять поиск. (Это можно сделать, например, через свойство INSTALL_RPATH в CMake-команде set_target_properties().) Пути для поиска динамических библиотек сохраняются в поле DT_RUNPATH или DT_RPATH секции .dynamic. Это поле может быть как в исполняемых файлах, скомпонованных с динамическими библиотеки, так и в самих динамических библиотеках, скомпонованных с другими динамическими библиотеками.

    3. По пути /lib.

    Загрузчик динамических библиотек выполняет поиск в том же порядке, если в параметре filename функции dlopen() или в переменной окружения LD_PRELOAD указан относительный путь к динамической библиотеке. Если указан абсолютный путь, то загрузчик помещает динамическую библиотеку в разделяемую память без выполнения поиска.

  2. Использование процессом (процессами).
  3. Выгрузка из памяти.

    Динамическая библиотека выгружается из разделяемой памяти, когда все процессы, использующие эту библиотеку, завершились или вызвали функцию dlclose() интерфейса POSIX. Динамическая библиотека, скомпонованная с исполняемым файлом, не может быть выгружена из разделяемой памяти до завершения процесса, который был создан на основе этого исполняемого файла. Динамическая библиотека, скомпонованная с другими динамическими библиотеками, выгружается из разделяемой памяти после выгрузки всех библиотек, которые зависят от нее.

В начало
[Topic shared_libraries_lifecycle]

Включение системной программы BlobContainer в решение на базе KasperskyOS

Если в решении используются динамические библиотеки, то в это решение должна быть включена системная программ BlobContainer (исполняемый файл sysroot-aarch64-kos/bin/BlobContainer из состава KasperskyOS Community Edition).

Программа BlobContainer может быть включена в решение автоматически или вручную. Автоматическое включение этой программы в решение выполняется CMake-командами build_kos_qemu_image() и build_kos_hw_image(), если как минимум один исполняемый файл в решении скомпонован с динамической библиотекой. (Чтобы отключить автоматическое включение программы BlobContainer в решение, нужно добавить значение NO_AUTO_BLOB_CONTAINER в параметры CMake-команд build_kos_qemu_image() и build_kos_hw_image().) Если программы в решении работают с динамическими библиотеками, используя только интерфейс POSIX (функции dlopen(), dlsym(), dlerror(), dlclose()), то программу BlobContainer нужно включить в решение вручную.

VFS, работающая с файлами динамических библиотек, должна быть отдельным процессом. Нужно создать IPC-канал от процесса программы BlobContainer к процессу VFS.

Должны быть созданы IPC-каналы от процессов, использующих динамические библиотеки, к процессу программы BlobContainer. Эти IPC-каналы могут быть созданы как статически, так и динамически. Если статически созданный IPC-канал отсутствует, клиентская и серверная части программы BlobContainer пытаются создать IPC-канал динамически, используя сервер имен.

Если программа BlobContainer включена в решение автоматически, то макросы @INIT_EXTERNAL_ENTITIES@, @INIT_<имя программы>_ENTITY_CONNECTIONS@ и @INIT_<имя программы>_ENTITY_CONNECTIONS+@, используемые в файле init.yaml.in, автоматически создают в init-описании словари IPC-каналов, которые обеспечивают статическое создание IPC-каналов от процессов, созданных на основе исполняемых файлов, скомпонованных с динамическими библиотеками, к процессу программы BlobContainer. (Процесс программы BlobContainer получает имя kl.bc.BlobContainer, а IPC-каналы получают имя kl.BlobContainer.) При этом для процессов, которые работают с динамическими библиотеками, используя только интерфейс POSIX, словари IPC-каналов к процессу программы BlobContainer автоматически не создаются, и, чтобы требуемые IPC-каналы были созданы статически, нужно создать эти словари вручную (эти IPC-каналы должны иметь имя kl.BlobContainer).

Если программа BlobContainer включена в решение вручную, и требуется статически создать IPC-каналы от процессов, использующих динамические библиотеки, к процессу программы BlobContainer, то нужно вручную создать словари необходимых IPC-каналов в init-описании. По умолчанию IPC-канал к процессу программы BlobContainer имеет имя kl.BlobContainer, но это имя можно изменить через переменную окружения _BLOB_CONTAINER_BACKEND. Эту переменную нужно задать как для процесса BlobContainer, так и для процессов, использующих динамические библиотеки.

Переменная окружения _BLOB_CONTAINER_BACKEND задает не только имя статически создаваемых IPC-каналов к процессу программы BlobContainer, но и имя службы, публикуемое на сервере имен, которое используется для динамического создания IPC-каналов к процессу программы BlobContainer. Это удобно использовать, когда запущено одновременно несколько процессов программы BlobContainer (например, с целью изоляции собственных динамических библиотек от сторонних), и разные процессы, использующие динамические библиотеки, должны взаимодействовать через IPC с разными процессами программы BlobContainer. В таком случае для разных процессов программы BlobContainer нужно задать разные значения переменной окружения _BLOB_CONTAINER_BACKEND, а затем использовать эти значения для переменной окружения _BLOB_CONTAINER_BACKEND процессов, использующих динамические библиотеки, выбирая конкретное значение в зависимости того, с каким именно процессом программы BlobContainer требуется динамически создать IPC-канал.

Пример использования переменной окружения _BLOB_CONTAINER_BACKEND в файле init.yaml.in:

entities: - name: example.BlobContainer path: example_blob_container args: - "-v" env: _BLOB_CONTAINER_BACKEND: kl.custombc @INIT_example_blob_container_ENTITY_CONNECTIONS@ - name: client.Client path: client env: _BLOB_CONTAINER_BACKEND: kl.custombc @INIT_client_ENTITY_CONNECTIONS@ @INIT_EXTERNAL_ENTITIES@

Пример использования переменной окружения _BLOB_CONTAINER_BACKEND в CMake-командах:

set_target_properties (ExecMgrEntity PROPERTIES EXTRA_ENV " _BLOB_CONTAINER_BACKEND: kl.custombc") set_target_properties (dump_collector::entity PROPERTIES EXTRA_ENV " _BLOB_CONTAINER_BACKEND: kl.custombc")
В начало
[Topic shared_libraries_blobcontainer]

Сборка динамических библиотек

Чтобы выполнить сборку динамической библиотеки, нужно использовать следующую CMake-команду:

add_library(<имя цели сборки> SHARED <путь к файлу исходного кода библиотеки>...)

Также можно выполнить сборку динамической библиотеки следующей CMake-командой:

add_library(<имя цели сборки> <путь к файлу исходного кода библиотеки>...)

При этом shell-команду cmake нужно вызвать с параметром -D BUILD_SHARED_LIBS=YES. (Если вызвать shell-команду cmake без параметра -D BUILD_SHARED_LIBS=YES, будет выполнена сборка статической библиотеки.)

Пример:

#!/bin/bash ... cmake -G "Unix Makefiles" \ -D CMAKE_BUILD_TYPE:STRING=Debug \ -D CMAKE_TOOLCHAIN_FILE=$SDK_PREFIX/toolchain/share/toolchain-$TARGET.cmake \ -D BUILD_SHARED_LIBS=YES \ -B build \ && cmake --build build --target kos-image

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

Пример:

# Сборка статической библиотеки add_library(somelib_static STATIC src/somesrc.cpp) set_target_properties(somelib_static PROPERTIES OUTPUT_NAME "somelib") # Сборка динамической библиотеки add_library(somelib_shared SHARED src/somesrc.cpp) set_target_properties(somelib_shared PROPERTIES OUTPUT_NAME "somelib")

Динамическая библиотека может быть скомпонована с другими статическими и динамическими библиотеками CMake-командой target_link_libraries(). При этом статические библиотеки должны быть собраны с флагом -fPIC. Этот флаг применяется при сборке статической библиотеки, если используется следующая CMake-команда:

set_property(TARGET <имя цели сборки>... PROPERTY POSITION_INDEPENDENT_CODE ON)
В начало
[Topic shared_libraries_building]

Добавление динамических библиотек в решение на базе KasperskyOS

Чтобы добавить динамические библиотеки в решение на базе KasperskyOS, существует два способа: с автоматическим и ручным поиском динамических библиотек, от которых зависят программы решения.

Способ с автоматическим поиском динамических библиотек

Нужно использовать параметры PACK_DEPS_COPY_ONLY ON, PACK_DEPS_LIBS_PATH и PACK_DEPS_COPY_TARGET в CMake-командах build_kos_qemu_image() и build_kos_hw_image().

Динамические библиотеки, которые загружаются в память вызовом функции dlopen() интерфейса POSIX, не будут найдены автоматическим поиском.

Пример 1:

# В этом примере создается образ решения для аппаратной платформы. # В этот образ решения добавляется образ накопителя с динамическими # библиотеками. # Установка значений переменных set (IMAGE_FS ${CMAKE_BINARY_DIR}/hdd) set (LIBS_PATH "${IMAGE_FS}/lib") set (DISK_IMG ramdisk0.img) if (blob_container_ENTITY_FOUND) # Настройка программы BlobContainer set_target_properties (${blob_container_ENTITY} PROPERTIES DEPENDS_ON_ENTITY ${precompiled_vfsVfsRamFs} EXTRA_ENV " VFS_FILESYSTEM_BACKEND: client:kl.VfsRamFs") endif () # Создание образа накопителя с динамическими библиотеками # Образ накопителя будет создан после выполнения цели copylibs, # которая создается CMake-командой build_kos_hw_image(). add_custom_command (OUTPUT ${DISK_IMG} DEPENDS copylibs COMMAND ${KL_SDK_ROOT_PATH}/common/prepare_hdd_img.sh -d ${IMAGE_FS} -s 64 -f ext4 -img ${DISK_IMG} COMMENT "Creating disk image '${DISK_IMG}' from files in '${IMAGE_FS}' ...") # Создание образа решения для аппаратной платформы # Цель copylibs означает копирование автоматически найденных динамических # библиотек в директорию ${LIBS_PATH}. Эта директория будет включена # в образ накопителя. Поскольку значение ${DISK_IMG} указано в параметре # IMAGE_FILES, образ накопителя будет создан перед созданием образа решения, # а также будет включен в образ решения. build_kos_hw_image (kos-image ... IMAGE_FILES ${ENTITIES_LIST} ${DISK_IMG} PACK_DEPS_COPY_ONLY ON PACK_DEPS_LIBS_PATH ${LIBS_PATH} PACK_DEPS_COPY_TARGET copylibs)

Пример 2:

# В этом примере для запуска на QEMU создаются образ решения и # отдельный образ накопителя с динамическими библиотеками, # а для запуска на аппаратной платформе создается образ SD-карты, # в который добавляются образ решения и динамические библиотеки. # Установка значений переменных, используемых при сборке # для аппаратной платформы set (HW_IMAGE_FS "${CMAKE_BINARY_DIR}/hdd_hw") set (HW_LIBS_PATH "${HW_IMAGE_FS}/lib") # Установка значений переменных, используемых при сборке # для QEMU set (QEMU_IMAGE_FS "${CMAKE_BINARY_DIR}/hdd_qemu") set (QEMU_LIBS_PATH "${QEMU_IMAGE_FS}/lib") set (QEMU_DISK_IMAGE sdcard0.img) set (QEMU_FLAGS "-nic none -m 2048 -drive file=${QEMU_DISK_IMAGE},if=sd,format=raw") set (QEMU_DEPENDENCIES ${QEMU_DISK_IMAGE}) if (blob_container_ENTITY_FOUND) # Настройка программы BlobContainer set_target_properties (${blob_container_ENTITY} PROPERTIES DEPENDS_ON_ENTITY ${precompiled_vfsVfsSdCardFs} EXTRA_ENV " VFS_FILESYSTEM_BACKEND: client:kl.VfsSdCardFs") # Создание образа накопителя с динамическими библиотеками для QEMU add_custom_command (${QEMU_DISK_IMAGE} DEPENDS copylibs_qemu COMMAND ${KL_SDK_ROOT_PATH}/common/prepare_hdd_img.sh -d ${QEMU_IMAGE_FS} -s 64 -f fat32 -img ${QEMU_DISK_IMAGE} COMMENT "Creating disk image '${QEMU_DISK_IMAGE}' from files in '${QEMU_IMAGE_FS}' ...") # Создание образа решения для QEMU # Цель copylibs_qemu означает копирование автоматически найденных динамических # библиотек в директорию ${QEMU_LIBS_PATH}. Эта директория будет включена # в образ накопителя с динамическими библиотеками для QEMU. Значение ${QEMU_FLAGS} # содержит параметры -drive file=${QEMU_DISK_IMAGE},if=sd,format=raw, которые # требуются для использования на QEMU образа накопителя с динамическими # библиотеками. Значение ${QEMU_DEPENDENCIES} требуется, чтобы обеспечить # создание образа накопителя с динамическими библиотеками до создания образа # решения для QEMU. (Образ решения не будет включать образ накопителя с # динамическими библиотеками, но добавление этой зависимости целей # нужно, чтобы выполнить создание образа накопителя с динамическими библиотеками.) build_kos_qemu_image (kos-qemu-image ... QEMU_FLAGS "${QEMU_FLAGS}" QEMU_DEPENDENCIES "${QEMU_DEPENDENCIES}" PACK_DEPS_COPY_ONLY ON PACK_DEPS_LIBS_PATH "${QEMU_LIBS_PATH}" PACK_DEPS_COPY_TARGET copylibs_qemu IMAGE_FILES ${ENTITIES}) # Создание образа решения для аппаратной платформы # Цель copylibs_hw означает копирование автоматически найденных динамических # библиотек в директорию ${HW_LIBS_PATH}. Эта директория будет включена # в образ SD-карты, который создается CMake-командой build_sd_image(). build_kos_hw_image (kos-image ... PACK_DEPS_COPY_ONLY ON PACK_DEPS_LIBS_PATH "${HW_LIBS_PATH}" PACK_DEPS_COPY_TARGET copylibs_hw IMAGE_FILES ${ENTITIES}) # Образ решения для аппаратной платформы будет создан после копирования # автоматически найденных динамических библиотек в директорию ${HW_LIBS_PATH}. # (Образ решения не будет включать динамические библиотеки, но добавление # этой зависимости целей нужно, чтобы выполнить копирование до создания # образа SD-карты.) add_dependencies (kos-image copylibs_hw) # Создание образа SD-карты # Образ SD-карты будет создан на основе директории ${HW_IMAGE_FS}, # включающей образ решения для аппаратной платформы и директорию # с динамическими библиотеками. Образ SD-карты будет создан # после создания образа решения для аппаратной платформы. build_sd_image (sd-image KOS_IMAGE_TARGET kos-image IMAGE_FS ${HW_IMAGE_FS})

Способ с ручным поиском динамических библиотек

Нужно самостоятельно выполнить поиск динамических библиотек, от которых зависят программы решения. Это позволяет добавить в решение даже те динамические библиотеки, которые загружаются в память вызовом функции dlopen() интерфейса POSIX.

Пример 1:

# В этом примере создается образ решения, включающий, помимо # исполняемых файлов программ, динамическую библиотеку libm.so. # Настройка программы VFS set (VFS_SDCARD_ARGS "\ - -l - nodev /tmp ramfs 0 - -l - devfs /dev devfs 0 - -l - romfs /lib romfs ro") set_target_properties (${precompiled_vfsVfsSdCardFs} PROPERTIES EXTRA_ARGS ${VFS_SDCARD_ARGS}) if (blob_container_ENTITY_FOUND) # Настройка программы BlobContainer set_target_properties (${blob_container_ENTITY} PROPERTIES DEPENDS_ON_ENTITY ${precompiled_vfsVfsSdCardFs} EXTRA_ENV " VFS_FILESYSTEM_BACKEND: client:kl.VfsSdCardFs") endif () if(PLATFORM_SUPPORTS_DYNAMIC_LINKING) # Получение полного пути к динамической библиотеке libm.so find_file(LIBM_SO_FILE libm.so PATH_SUFFIXES lib REQUIRED) set(EXTRA_FILES ${LIBM_SO_FILE}) else() set(EXTRA_FILES) endif() # Создание образа решения для аппаратной платформы # Динамическая библиотека libm.so будет добавлена в # образ решения, поскольку значение ${EXTRA_FILES}, # указанное в параметре IMAGE_FILES, содержит полный # путь к этой библиотеке. build_kos_hw_image(kos-image ... IMAGE_FILES ${ENTITIES} ${EXTRA_FILES})

Пример 2:

# В этом примере для запуска на QEMU создаются образ решения и # отдельный образ накопителя с динамической библиотекой libm.so. # Установка значений переменных set (QEMU_FLAGS "-nic none -m 2048") set (QEMU_DEPENDENCIES) if (PLATFORM_SUPPORTS_DYNAMIC_LINKING) # Установка значений переменных set (IMAGE_FS "${CMAKE_BINARY_DIR}/hdd") set (LIBS_PATH "${IMAGE_FS}/lib") set (QEMU_DISK_IMAGE sdcard0.img) string (APPEND QEMU_FLAGS "-drive file=${QEMU_DISK_IMAGE},if=sd,format=raw") set (QEMU_DEPENDENCIES ${QEMU_DISK_IMAGE}) # Настройка программы BlobContainer set_target_properties (${blob_container_ENTITY} PROPERTIES DEPENDS_ON_ENTITY ${precompiled_vfsVfsSdCardFs} EXTRA_ENV " VFS_FILESYSTEM_BACKEND: client:kl.VfsSdCardFs") # Получение полного пути к динамической библиотеке libm.so find_file (LIBM_SO_FILE libm.so PATH_SUFFIXES lib REQUIRED) # Создание образа накопителя с динамической библиотекой libm.so add_custom_command (OUTPUT ${QEMU_DISK_IMAGE} COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBS_PATH} COMMAND ${CMAKE_COMMAND} -E copy ${LIBM_SO_FILE} ${LIBS_PATH} COMMAND ${KL_SDK_ROOT_PATH}/common/prepare_hdd_img.sh -d ${IMAGE_FS} -s 64 -f fat32 -img ${QEMU_DISK_IMAGE} COMMENT "Creating disk image '${QEMU_DISK_IMAGE}' from files in '${IMAGE_FS}' ...") endif () # Создание образа решения для QEMU # Значение ${QEMU_FLAGS} содержит параметры -drive file=${QEMU_DISK_IMAGE},if=sd,format=raw, # которые требуются для использования на QEMU образа накопителя с динамической # библиотекой libm.so. Значение ${QEMU_DEPENDENCIES} требуется, чтобы обеспечить # создание образа накопителя с динамической библиотекой libm.so до создания образа # решения для QEMU. (Образ решения не будет включать образ накопителя с # динамической библиотекой libm.so, но добавление этой зависимости целей # нужно, чтобы выполнить создание образа накопителя с динамической библиотекой libm.so.) build_kos_qemu_image (kos-qemu-image ... QEMU_FLAGS "${QEMU_FLAGS}" QEMU_DEPENDENCIES "${QEMU_DEPENDENCIES}" IMAGE_FILES ${ENTITIES})
В начало
[Topic shared_libraries_adding_to_solution]