У меня есть библиотека, которая использует множество зависимостей, управляемых 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 .
Вещи, которые я уже пробовал:
PUBLIC
вместо PRIVATE
(заменив source/mylib/CMakeLists.txt
на использование: target_link_libraries(mylib PUBLIC 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).
Я понимаю, что отсутствует ускорение, но не требуется вручную связывать его с приложениями, которые напрямую не требуют этого. Это внутренняя зависимость только OpenImageIO, не предоставляемая его общедоступным API. Все корректно линкуется в Windows, а также при компиляции с OpenImageIO, установленным через apt
вместо vcpkg
. Поэтому я подозреваю, что проблема с портом vcpkg этой библиотеки.
Вы проверили командную строку компилятора? Это первый шаг отладки
Сообщение об ошибке, которое вы получили, потому что вы связываетесь с OpenImageIO как статической библиотекой, но не связываетесь с Boost, функции которого используются в OpenImageIO. Можно было бы ожидать, что импортированная цель OpenImageIO::OpenImageIO
уже содержит связь с библиотеками Boost, но большинство проектов CMake не создают такую связь в своих установленных файлах конфигурации. Я предполагаю, что все ваши успешные попытки используют общий вариант OpenImageIO: в отличие от статического, файл общей библиотеки сам содержит список всех зависимых библиотек.
@Tsyvarev, если OpenImageIO::OpenImageIO
действительно не ссылается на статические библиотеки boost, то это ошибка в vcpkg, она определенно должна работать. most CMake projects don't create such linkage in their installed config files
значит эти проекты глючные, каждая библиотека, которую я использовал, ссылается на ее зависимости
@AlanBirtles: «если OpenImageIO::OpenImageIO
действительно не ссылается на статические библиотеки Boost, то это ошибка в vcpkg» - насколько я понимаю дух vcpkg, в случае библиотек, поставляемых с проектами CMake, он просто собирает (и устанавливает) эти проекты через CMake. Таким образом, если что-то не охвачено проектом библиотеки CMake, то это не будет охвачено vcpkg.
@Tsyvarev, я думаю, что они предоставляют свои собственные файлы конфигурации, независимо от того, предоставляют ли они или нет файлы конфигурации OIIO, которые правильно ссылаются на повышение
@AlanBirtles, к сожалению, сегодня утром я не могу это проверить. Я проверю, когда вечером вернусь за компьютер. прошу прощения за сумбур с моей стороны
@Tsyvarev, это не мое понимание vcpkg, и у меня не было опыта работы с каким-либо другим пакетом. Этот пакет вызывает у меня такую проблему
Оказывается, проблема была в порте vcpkg. Недавно добавленная версия 2.5.12.0#2 устраняет проблему.
Недавно добавленная версия 2.5.12.0#2 устраняет проблему.
Похоже, отсутствует поток повышения, присутствует ли эта библиотека в командной строке компилятора?