Приложению не удается связать библиотеку с OpenImageIO

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

  • В Windows 10 (MSVC 17.6) моя библиотека успешно собирается и связывается, а затем я могу создать приложение и связать с ним свою библиотеку.

  • В Ubuntu 20.04.6 (g++ 10.5.0, ld 2.34) моя библиотека успешно собирается и связывается, но все приложения не могут связать ее с множеством ошибок, указывающих неопределенную ссылку на некоторую библиотеку повышения.

Когда я собираю свою библиотеку как статическую библиотеку (в Ubuntu), она выдает ошибки, которые выглядят следующим образом:

/usr/bin/ld: ../../vcpkg_installed/x64-linux/debug/lib/libOpenImageIO_d.a(imageinput.cpp.o): in function `boost::thread_specific_ptr<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~thread_specific_ptr()':
/mnt/c/Users/cgnam/source/repos/vira/out/ubuntu/vcpkg_installed/x64-linux/include/boost/thread/tss.hpp:61: undefined reference to `boost::detail::set_tss_data(void const*, void (*)(void (*)(void*), void*), void (*)(void*), void*, bool)'

Минимальный рабочий пример:

Можно найти по адресу https://github.com/crgnam/oiio-linker-error

(Обязательно vcpkg на вашем компьютере):


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

vcpkg.json
CMakeLists.txt
myapp.cpp
mylib.cpp
mylib.hpp

vcpkg.json:

{
  "name": "vira",
  "version-string": "0.8.0",
  "dependencies": [
    "openimageio"
  ],
  "overrides": [
    {
      "name": "openimageio",
      "version": "2.5.8.0#2"
    }
  ],
  "builtin-baseline": "352c108a6b6d698c09a8272d8e95fdce550ae408"
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.19)

project(example LANGUAGES CXX VERSION 0.8.0)
set(CXX_STANDARD 20)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

include_directories(.)

# Build and link my library:
add_library(mylib STATIC mylib.cpp)
find_package(OpenImageIO CONFIG REQUIRED)
target_link_libraries(mylib PRIVATE OpenImageIO::OpenImageIO)

# Build and link Executable:
add_executable(myapp myapp.cpp)
target_link_libraries(myapp PRIVATE mylib)

mylib.hpp:

#ifndef MYLIB_MYLIB_HPP
#define MYLIB_MYLIB_HPP

#include <string>

namespace mylib {
    void getImageDimensions(const std::string& filepath);
};

#endif

mylib.cpp:

#include "mylib.hpp"

#include <string>
#include <iostream>
#include <stdexcept>

#include "OpenImageIO/imageio.h"
#include "OpenImageIO/imagebuf.h"

namespace mylib {
    void getImageDimensions(const std::string& filepath)
    {
        // Open the file:
        auto inp = OIIO::ImageInput::open(filepath);
        if (!inp) {
            throw std::runtime_error("OpenImageIO could not open: " + filepath);
        };

        const OIIO::ImageSpec& spec = inp->spec();
        int width = spec.width;
        int height = spec.height;
        int channels = spec.nchannels;

        std::cout << width << " x " << height << " x " << channels << "\n";
    };
};

myapp.cpp:

#include <string>

#include "mylib.hpp"

int main(int argc, char* argv[])
{
    if (argc == 2) {
        const std::string& filepath = argv[1];
        mylib::getImageDimensions(filepath);
        return 0;
    }
    else {
        return 1;
    };
};

Построить с:

mkdir build;
cd build;
cmake -DCMAKE_TOOLCHAIN_FILE=<path/to/vcpkg>/scripts/buildsystems/vcpkg.cmake ../
cmake --build .

Вещи, которые я уже пробовал:

  • Различные версии OpenImageIO доступны на vcpkg (я пробовал как самую последнюю версию 2.5.12, так и 2.5.8)
  • Создание библиотеки как СТАТИЧЕСКОЙ, так и ОБЩЕЙ
  • Установка интерфейса ссылки OpenImageIO на мою библиотеку, используя PUBLIC вместо PRIVATE (заменив source/mylib/CMakeLists.txt на использование: target_link_libraries(mylib PUBLIC OpenImageIO::OpenImageIO))
  • Связывание OpenImageIO напрямую с моим приложением (изменение source/myapp/CMakeLists.txt на использование: target_link_libraries(myapp PRIVATE OpenImageIO::OpenImageIO mylib))

До сих пор все, что я пытаюсь сделать, по-прежнему успешно собирает и связывает библиотеку, но не может связать библиотеку с моим исполняемым файлом. (Хотя в Windows/MSVC все работает нормально)

Обновлено:

Если я установлю OpenImageIO с помощью sudo apt install libopenimageio-dev и НЕ буду использовать vcpkg, а затем изменю source/mylib/CMakeLists.txt на:

add_library(mylib STATIC mylib.cpp)

find_library(OIIO OpenImageIO)
target_link_libraries(mylib PRIVATE ${OIIO})

Мое приложение успешно свяжется с mylib и будет работать нормально (в Ubuntu).

Означает ли это, что с портом vcpkg что-то не так? Или я что-то не понимаю? Потому что я ожидаю (как и в случае со всеми другими библиотеками, которые я использую), что это не должно быть проблемой (и действительно, это не касается других моих библиотек, таких как TBB, cpsice и т. д., или в Windows).

Похоже, отсутствует поток повышения, присутствует ли эта библиотека в командной строке компилятора?

Alan Birtles 06.07.2024 06:19

Я понимаю, что отсутствует ускорение, но не требуется вручную связывать его с приложениями, которые напрямую не требуют этого. Это внутренняя зависимость только OpenImageIO, не предоставляемая его общедоступным API. Все корректно линкуется в Windows, а также при компиляции с OpenImageIO, установленным через apt вместо vcpkg. Поэтому я подозреваю, что проблема с портом vcpkg этой библиотеки.

Chris Gnam 06.07.2024 06:28

Вы проверили командную строку компилятора? Это первый шаг отладки

Alan Birtles 06.07.2024 08:03

Сообщение об ошибке, которое вы получили, потому что вы связываетесь с OpenImageIO как статической библиотекой, но не связываетесь с Boost, функции которого используются в OpenImageIO. Можно было бы ожидать, что импортированная цель OpenImageIO::OpenImageIO уже содержит связь с библиотеками Boost, но большинство проектов CMake не создают такую ​​связь в своих установленных файлах конфигурации. Я предполагаю, что все ваши успешные попытки используют общий вариант OpenImageIO: в отличие от статического, файл общей библиотеки сам содержит список всех зависимых библиотек.

Tsyvarev 06.07.2024 11:23

@Tsyvarev, если OpenImageIO::OpenImageIO действительно не ссылается на статические библиотеки boost, то это ошибка в vcpkg, она определенно должна работать. most CMake projects don't create such linkage in their installed config files значит эти проекты глючные, каждая библиотека, которую я использовал, ссылается на ее зависимости

Alan Birtles 06.07.2024 11:57

@AlanBirtles: «если OpenImageIO::OpenImageIO действительно не ссылается на статические библиотеки Boost, то это ошибка в vcpkg» - насколько я понимаю дух vcpkg, в случае библиотек, поставляемых с проектами CMake, он просто собирает (и устанавливает) эти проекты через CMake. Таким образом, если что-то не охвачено проектом библиотеки CMake, то это не будет охвачено vcpkg.

Tsyvarev 06.07.2024 12:08

@Tsyvarev, я думаю, что они предоставляют свои собственные файлы конфигурации, независимо от того, предоставляют ли они или нет файлы конфигурации OIIO, которые правильно ссылаются на повышение

Alan Birtles 06.07.2024 12:26

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

Chris Gnam 06.07.2024 16:06

@Tsyvarev, это не мое понимание vcpkg, и у меня не было опыта работы с каким-либо другим пакетом. Этот пакет вызывает у меня такую ​​проблему

Chris Gnam 06.07.2024 16:06

Оказывается, проблема была в порте vcpkg. Недавно добавленная версия 2.5.12.0#2 устраняет проблему.

Chris Gnam 07.07.2024 01:06
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Недавно добавленная версия 2.5.12.0#2 устраняет проблему.

См.: https://github.com/microsoft/vcpkg/issues/39533

Другие вопросы по теме