使用 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
的引用并覆盖它们。
我希望我能帮助有同样问题的人。如果有不清楚或不正确的地方,请告诉我。
我在使用 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
的引用并覆盖它们。
我希望我能帮助有同样问题的人。如果有不清楚或不正确的地方,请告诉我。