我有一个库,它使用由 vcpkg 管理的许多依赖项。 在我最近添加 OpenImageIO 之前,我从未遇到过任何问题。
在 Windows 10 (MSVC 17.6) 上,我的库成功构建并链接,然后我能够构建应用程序并将我的库链接到它。
在 Ubuntu 20.04.6(g++ 10.5.0,ld 2.34)上,我的库成功构建和链接,但所有应用程序都无法链接到它,并出现许多错误,指出对某些 boost 库的未定义引用。
当我将库构建为静态库(在 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
将 OpenImageIO 的链接接口设置到我的库(将 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 上一切正常)
如果我使用
sudo apt install libopenimageio-dev
安装 OpenImageIO,并且不使用 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 上的库来说不是问题)。
新添加的版本2.5.12.0#2修复了该问题。