使用 cmake 链接两个相似的库

Linking against two similar libraries with cmake

我在使用 cmake 和链接我的应用程序时遇到问题: 我正在处理现有项目。该项目使用修改后的 libjpeg(静态库),我的可执行文件链接到它。

target_link_libraries( myprog jpeglib )

现在我想添加一个使用 turbojpeg 库的新功能。

add_library( newfeature SHARED ${LIBVNCSERVER_SOURCES})
set_target_properties( newfeature PROPERTIES DEFINE_SYMBOL DLLDEFINE)
target_link_libraries( newfeature turbojpeg-static)
target_link_libraries( newfeature LINK_INTERFACE_LIBRARIES)

我的程序将链接到这个共享库:

target_link_libraries ( myprog jpeglib newfeature )

在 Windows 下一切正常。但是如果我在 Linux 下使用这个功能,我会得到一个错误:

JPEG Error: JPEG parameter struct mismatch: library thinks size is 488, caller expects 504

此错误是由 libjpeg 生成的。

我在 Google 上找到的所有内容均无效。 我猜想共享库 newfeature 使用 myprog 中的 jpeglib,尽管 newfeature 是静态链接到 turbojpeg 库的。 newfeature 应该是独立的 .so 或 .dll 文件 如果我更改链接顺序,我会得到同样的错误,但它是从 turbojpeg 生成的。

无法将 myprog 与 turbojpeg-static 链接,因为它与修改后的 libjpeg 不兼容。

有人能帮忙吗?我的假设对吗?

问题是您将 libjpeg 静态链接到您的可执行文件中,但现在您试图添加对 (libjpeg-turbo) 的间接依赖,这是相同 API.

这是一个问题,因为现在 libjpeg API 中的每个 public API 符号(函数名称等)都有两种可能的解决方案。大多数库不在一个可执行文件中支持自身的两个版本,当然,实现相同接口的两个不同库也不太可能这样做。

如果您幸运的话,libjpeg 正在根据其库(在运行时)检查其头文件(在构建时)的版本。当图书馆不建立这些类型的检查时,这种问题通常不会被发现。

你应该尝试让 newfeature 不依赖于 libjpeg-turbo 而是用你自己的 libjpeg 来满足它,这似乎是你描述的固定要求。

我找到了解决方案:

我使用此 cmake 命令将 --exclude-libs,ALL 添加到 newfeature 的链接器命令中:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,--exclude-libs,ALL")

问题是我的 turbojpeg-static 中的符号被我的 newfeature.so 导出,因此从 "outside" 中可见。链接器首先从libjpeg中找到符号。在将 myprog 链接到 newfeature.so 时,链接器从我的 newfeature 方法中找到对 turbojpeg-static 的引用并覆盖它们。

我希望我能帮助有同样问题的人。如果有不清楚或不正确的地方,请告诉我。