1

Тема: CMake прив'язка теки з ресурсами до файлу динамічної бібліотеки

Якщо треба просто прив'язати шлях до теки з ресурсами в CMake.
то можна зробити так:

target_compile_definitions(target_name PRIVATE
    RESOURCES_DIR="${CMAKE_CURRENT_SOURCE_DIR}/resources"
  )

Але проблема в тому, що при збиранні динамічного бібліотеки (мова про Лінукс),
тобто створенні .so файлу, буде збережено абсолютний шлях з конкретної ОС всередині цього файлу.
І такий файл уже не можна буде використовувати на інших комп'ютерах.
Схожа проблема для сторонніх бібліотек, які використовуються у поточному проєкті,
вирішується за допомогою BUILD_RPATH_USE_ORIGIN TRUE та додаванням $ORIGIN
до відносних шляхів сторонніх бібліотек. Але цей $ORIGIN діє лише при читанні elf файлів
і у файлах із кодом (hpp, cpp) від нього жодної користі.

Як зробити щось схоже для теки зі звичайними ресурсами (шрифтами, текстурами і т.д.),
щоб можна було взяти .so файл покласти разом із ним у директорію теку з ресурсами
і передавати на інші машини у такому вигляді?

2

Re: CMake прив'язка теки з ресурсами до файлу динамічної бібліотеки

Відмовтеся від зашивання абсолютного шляху на етапі компіляції і замість цього визначайте шлях до ресурсів динамічно під час виконання, відштовхуючись від розташування самого .so файлу.

3

Re: CMake прив'язка теки з ресурсами до файлу динамічної бібліотеки

wander написав:

Відмовтеся від зашивання абсолютного шляху на етапі компіляції і замість цього визначайте шлях до ресурсів динамічно під час виконання, відштовхуючись від розташування самого .so файлу.

Я пробував зашивати відносний шлях, але коли бібліотека приєднується до іншого проєкту,
а потім там викликається клас, що все завантажує, то шлях уже змінюється.
І я якраз не розумію як динамічно визначати його під час виконання.

4

Re: CMake прив'язка теки з ресурсами до файлу динамічної бібліотеки

Гм, ну, якщо вам виключно лише під Linux, то по ідеї dladdr мав би зпрацювати.

Якщо зовсім "по-правильному", то це мало б бути якось так: бібліотека взагалі не шукає файли на диску, вона просто надає функцію конфігурування. А оскільки виконуваний файл (exe) точно знає, де він лежить (через системні параметри запуску), він бере цей шлях, налаштовує, де ресурси, і передає їх вашій бібліотеці.

Ще можете глянути в сторону GNUInstallDirs.

5

Re: CMake прив'язка теки з ресурсами до файлу динамічної бібліотеки

wander написав:

Гм, ну, якщо вам виключно лише під Linux, то по ідеї dladdr мав би зпрацювати.

Якщо зовсім "по-правильному", то це мало б бути якось так: бібліотека взагалі не шукає файли на диску, вона просто надає функцію конфігурування. А оскільки виконуваний файл (exe) точно знає, де він лежить (через системні параметри запуску), він бере цей шлях, налаштовує, де ресурси, і передає їх вашій бібліотеці.

Ще можете глянути в сторону GNUInstallDirs.

GNUInstallDir — це для інсталяції на системному рівні.
Мене більше цікавить окрема тека, яку можна розповсюджувати без встановлення в систему.

6

Re: CMake прив'язка теки з ресурсами до файлу динамічної бібліотеки

Ось таке добре працює:

auto get_resource_path()->std::filesystem::path
{
    Dl_info info{};

    if (dladdr(reinterpret_cast<void*>(&get_resource_path), &info) == 0
        || info.dli_fname == nullptr)
    {
        throw std::runtime_error("Cannot locate shared library");
    }

    return std::filesystem::path(info.dli_fname).parent_path() / "resources";
}