AuroraLinkingLibs
Описание приложения
Приложение является примером подключения библиотек различными способами на ОС Аврора. Основная цель - показать как подключать статические и динамические библиотеки во всех доступных системах сборки приложения под ОС Аврора. В приложении есть возможность проверки подключения трёх самостоятельно написанных библиотек: статической, динамической с явным связыванием и динамической с неявным связыванием.
Статус сборки:
Содержание
- Содержание
- Подробное описание
- Совместимость
- Особенности борки
- Информация о ветках
- Установка и сборка
- Скриншоты
- Варианты использования
- Структура проекта
- Правила использования и участие в разработке
Подробное описание
Существует три основных способа подключения любой библиотеки:
-
Взять исходники библиотеки и встроить в свой проект напрямую. Это самый простой способ, но в таком случае каждый раз библиотека будет пересобираться заново. А это может сильно уменьшить скорость сборки приложения.
-
Использовать статические библиотеки, которые компонуются во время компиляции приложения. Они находятся в файлах с расширением
*.a
-
Использовать динамические библиотеки, которые подключаются во время рантайма приложения. Они находятся в файлах с расширением
*.so
Далее будут показаны способы сбора и подключения библиотек для всех вышеописанных способов на двух системах сборки - qmake
и cmake
Создание библиотеки
Для примера сделаем одну и ту же библиотеку, содержащую единственную функцию, выводящую сумму двух чисел.
void print_add(int a, int b) {
qDebug() << a << " + " << b << " = " << a + b;
}
Далее нам нужны соответствующие файлы *.pro
и CMakeLists.txt
, которые будут конфигурировать соответственно qmake
и cmake
сборку соответственно.
Для qmake:
TEMPLATE = lib
TARGET = add
SOURCES += add.cpp \
HEADERS += add.h \
данный код соберёт динамическую библиотеку с файлом *.so
. Чтобы собрать статическую, нужно после указания таргета приписать конфиг:
TEMPLATE = lib
TARGET = add
CONFIG += staticlib
SOURCES += add.cpp \
HEADERS += add.h \
Чтобы собрать под таргет, нужно зайти в Aurora IDE, сделать фиктивный spec файл в директории rpm и запустить сборку. Сборка упадёт, но библиотека соберётся и получим необходимое.
Далее то же самое, но для cmake:
cmake_minimum_required(VERSION 3.0)
project(add)
# Find the Qt5 package
find_package(Qt5 COMPONENTS Core REQUIRED)
# Add the source files to the executable
add_library(add STATIC
add.cpp
add.h
)
# Include the header files
target_include_directories(add PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
# Link against the Qt5 libraries
target_link_libraries(add PRIVATE
Qt5::Core
)
Для динамической библиотеки заменить STATIC
на SHARED
Сборка библиотеки
Есть два способа собрать библиотеку: через IDE и через терминал
Сборка через IDE
-
В случае
qmake
достаточно написать фиктивный spec файл, в котором будет описание сборки rpm пакета. Запускаем сборку через IDE. Она провалится, т.к. в rpm загружать будет нечего, но библиотека соберётся. И мы получим желаемый*.a
или*.so
файл. -
В случае
cmake
такое не прокатит и нужно сделать шаблонное приложение, в котором соответственно эта библиотека будет подключена:
add_subdirectory(<директория библиотеки>)
Сборка через терминал
-
Сборка внутри определенного таргета. Заходим в docker/virtualbox по порту 2222 командой:
ssh -p 2222 -i "aurora-path"/vmshare/ssh/private_keys/sdk mersdk@localhost
где "aurora-path" - путь до директории установки Aurora SDK
-
Проверяем установленные таргеты:
sdk-assistant list
-
Под обычным пользователем заходим внутрь таргета
как пользователь :
sb2 -t AuroraOS-4.0.2.303-base-armv7hl -m sdk-build
как root:
sb2 -t "$target" -m sdk-install -R
Соответственно таргет AuroraOS-4.0.2.303-base-armv7hl меняем на нужный. Идём в каталог сборки и выполняем команды как будто собираем как на обычном линуксе.
-
Для
qmake
:mkdir build cd build qmake .. make
либо вызвать qmake конкретного таргета
qmake <название>.pro
-
Для
cmake
:mkdir build cd build cmake .. make
Подключение библиотеки в приложение
Разберём каждый из способов подключения библиотеки:
Сборка с исходниками
В таком случае можно просто скопировать файлы исходников библиотеки в проект и добавить их в таргет через add_executable
или SOURCE +=
для cmake
и qmake
соответственно.
Сборка с исходниками (альтернатива)
Можно прямо во время сборки вызвать билд библиотеки и подключить её. Для этого используются следующие команды:
-
Для
cmake
:add_subdirectory(<директория>)
-для вызова сборки в поддиректории
target_include_directories(${PROJECT_NAME} PRIVATE <директория> )
-для подключения заголовочных файлов из директории
target_link_libraries(${PROJECT_NAME} <название библиотеки> )
-для линковки файла статической библиотеки
-
Для
qmake
:SUBDIRS += "путь до директории"
-для вызова сборки в поддиректории
INCLUDEPATH += "путь до заголовочных файлов"
-для подключения заголовочных файлов из директории
LIBS += -L"путь до библиотеки" -l"название библиотеки"
-для линковки файла статической библиотеки
Добавление статической библиотеки.
Статическая библиотека имеет расширение .a
и подключается к проекту во время сборки. Для этого нужно:
-
Указать откуда брать объявления функций/классов Для cmake
include_directories
Для qmakeINCLUDEPATH +=
-
Указать откуда брать скомпилированные исходники библиотеки Для cmake
target_link_libraries
Для qmakeLIBS += -L$$OUT_PWD/../<путь до библиотеки> -l<название библиотеки>
Никаких требований больше нет, т.к. исходники библиотеки уже находятся внутри исполняемого файла
Динамическая библиотека
Динамическая библиотека подключается во время работы приложения. Есть два типа линковки динамической библиотеки: явное и неявное связывание.
Неявное связывание динамической библиотеки
Всё идентично статической библиотеки, но вместе с исполняемым файлом должен поставляться *.so
файл библиотеки
Для этого укажем в .spec
файле, чтобы копировалось в нужную директорию. Пример для библиотек mul
и sub
:
mkdir %{buildroot}/%{_datadir}/%{name}/lib/
cp -rf $PWD/mul/libmul.so* %{buildroot}/%{_datadir}/%{name}/lib/
cp -rf $PWD/sub/libsub.so* %{buildroot}/%{_datadir}/%{name}/lib/
%define __requires_exclude ^(libadd.*|libsub.*|libmul.*).*$
%define __provides_exclude_from ^%{_datadir}/%{name}/lib/.*$
В AuroraOS путь вида /usr/share/{название_пакета}/lib/*
является стандартным у необходимых для приложения библиотек.
Если по указанному пути библиотеки не будет, приложение не запустится
Явное связывание динамической библиотеки
Указывать пути для объявлений и для библиотек не обязательно. Подключается она при помощи класса QLibrary
. Пример:
QLibrary myLib("/usr/share/ru.auroraos.qmake_libraries/lib/libmul.so");
if (myLib.load()) {
typedef void (*MyFunction)(int, int);
MyFunction myFunction = (MyFunction) myLib.resolve("print_mul");
if (myFunction) {
qDebug() << "Function resolved successfully";
// Call the function
myFunction(2, 3);
} else {
qDebug() << "Failed to resolve function";
}
} else {
qDebug() << "Failed to load library";
}
Т.к. QLibrary
ищет нужную функцию по имени, нужно добавить в код библиотеки такую строку:
#define DLL_PUBLIC __attribute__ ((visibility("default")))
extern "C" DLL_PUBLIC <ваша функция>
Сделано это потому что из-за наличия перегрузки функций в C++ имя функции в библиотеке и фактическое имя, по которому будет искаться функция в so файле, будут отличаться. extern "C" указывает, что имя должно совпадать.
Для поиска библиотеки нужно указывать полный путь, но этого можно избежать, если добавить в ldconfig
нашу библиотеку.
Совместимость
Приложение корректно работает начиная с ОС Аврора 5.х.х и выше.
Особенности сборки
Данный проект содержит в себе два подпроекта, каждый из которых содержит идентичное приложение, но с разными системами сборки. В cmake_libraries сборка проекта осуществляется через файл CMakeLists.txt. В qmake_libraries сборка проекта осуществляется через файл ru.auroraos.qmake_libraries.pro
Информация о ветках
Установка и сборка
Проект собирается обычным образом с помощью Аврора SDK. Общая информациия о сборке - Информация о сборке
Скриншоты
Варианты использования
Вызов функции из библиотеки
- Нажать на один из вариантов, после которого выполнится функция из библиотеки и произойдёт переход на экран с результатом.
- После сообщения об успешном выполнении можно вернуться назад
Изучение способов подключения библиотек
По исходникам данного проекта можно разобраться как подключить самые разные библиотеки под систему сборки cmake и qmake:
- статическая
- динамическая с явным связыванием
- динамическая с неявным связыванием
Структура проекта
Проект состоит из стандартных по структуре приложений на C++ и QML для ОС Аврора.
-
Приложение с использованием qmake использует систему сборки qmake.
-
Приложение с использованием cmake использует систему сборки cmake.
Структура проекта CMake
Проект имеет стандартную структуру приложения на C++ и QML для ОС Аврора.
- Файл CMakeLists.txt описывает структуру приложения системы сборки cmake.
- Каталог add содержит исходники статической библиотеки, которая подключается к проекту
- Каталог sub содержит исходники динамической библиотеки, которая подключается неявно к проекту
- Каталог mul содержит исходники динамической библиотеки, которая подключается явно к проекту
- Каталог icons содержит значки приложений для разных разрешений экрана.
- Каталог qml содержит исходный код QML и ресурсы пользовательского интерфейса.
- Каталог cover содержит реализации оболочек приложений.
- Каталог icons содержит дополнительные иконки интерфейса пользователя.
- Каталог pages содержит страницы приложения.
- Файл cmake_libraries.qml обеспечивает реализацию окна приложения.
- Каталог rpm содержит настройки сборки rpm-пакета.
- cmake_libraries.spec файл используется инструментом rpmbuild.
- Каталог src содержит исходный код C++.
- Файл main.cpp является точкой входа приложения.
- Каталог translations содержит файлы перевода пользовательского интерфейса.
- Файл ru.auroraos.cmake_libraries.desktop определяет отображение и параметры запуска приложения.
Структура проекта QMake
Проект имеет стандартную структуру приложения на C++ и QML для ОС Аврора.
- Подпроект add содержит исходники статической библиотеки, которая подключается к проекту
- Подпроект sub содержит исходники динамической библиотеки, которая подключается неявно к проекту
- Подпроект mul содержит исходники динамической библиотеки, которая подключается явно к проекту Подпроект app описывает само приложение и имеет следующую структуру:
- Файл app.pro описывает структуру приложения системы сборки qmake.
- Каталог icons содержит значки приложений для разных разрешений экрана.
- Каталог qml содержит исходный код QML и ресурсы пользовательского интерфейса.
- Каталог cover содержит реализации оболочек приложений.
- Каталог icons содержит дополнительные иконки интерфейса пользователя.
- Каталог pages содержит страницы приложения.
- Файл qmake_libraries.qml обеспечивает реализацию окна приложения.
- Каталог rpm содержит настройки сборки rpm-пакета. qmake_libraries.spec файл используется инструментом rpmbuild.
- Каталог src содержит исходный код C++.
- Файл main.cpp является точкой входа приложения.
- Каталог translations содержит файлы перевода пользовательского интерфейса.
Правила использования и участие в разработке
Исходный код проекта предоставляется по лицензии, которая позволяет использовать его в сторонних приложениях.
Соглашение участника регламентирует права, предоставляемые участниками компании «Открытая Мобильная Платформа».
Информация об участниках указана в файле AUTHORS.
Кодекс поведения — это действующий набор правил компании «Открытая Мобильная Платформа», который информирует об ожиданиях по взаимодействию между членами сообщества при общении и работе над проектами.