如何在 CMake 中发现 Cassablanca (cpprestsdk) 中的 boost DLL 依赖项



这是我的第一篇文章,所以请耐心等待。这是我的设置:

我最近开始在Windows 10 64位上使用Cassablanca (cpprestsdk)。

我正在使用微软的包管理器(vcpkg):

https://github.com/Microsoft/vcpkg

我没有使用Visual Studio,尽管我使用的是它的编译器。我创建了一个 CMake 项目,该项目创建了一个 DLL,该 DLL 基本上使用 cpprestsdk 中的介绍项目:https://github.com/Microsoft/cpprestsdk/wiki/Getting-Started-Tutorial

最终目标是我希望从旧应用程序的另一个现有 DLL 调用我正在创建的此 DLL。

现在我已经四处搜索,我已经想出了如何完成这项工作。

另一个 DLL 只是与这个新 DLL 链接并调用我感兴趣的函数。

经过一些搜索,我发现我的新DLL需要与以下内容链接:

target_link_libraries( PRIVATE cpprestsdk::cpprest cpprestsdk::cpprestsdk_zlib_internal cpprestsdk::cpprestsdk_boost_internal cpprestsdk::cpprestsdk_openssl_internal)

更多搜索,我发现我需要指定 zlib 和 openssl 的位置:

set(ZLIB_ROOT "${VCPKG_HOME_WIN}/zlib_x64-Windows") set(OPENSSL_ROOT_DIR "${VCPKG_HOME_WIN}/openSSL-windows_x64-Windows")

这一切都很好,效果很好。然后我来提升。当使用 vcpkg 安装 cpprestsdk 时,它足够智能,可以下载它所需要的所有提升,所以有大量的提升目录和大量的 DLL。

当我尝试从旧版应用程序的 DLL 调用函数时,DLL 无法加载,因为它找不到其依赖项 DLL。我将restsdk,openssl和zlib dll复制到旧版应用程序中,但我不知道要复制什么boost dll。 显然,我可以用枪射击它,并简单地复制 vcpkg 下载的所有加速 dll,作为 restsdk 的一部分,但这似乎有点矫枉过正。

最后,我不确定该怎么做,所以我在Visual Studio中构建了整个CMake项目。不知何故,Visual Studio足够聪明地解决这个问题,在我的项目的输出目录中,它放置了以下boost DLL:

boost_date_time-VC141-MT-GD-X32-1_68.dll boost_system-VC141-MT-GD-X32-1_68.dll

所以我想我会试一试,我复制了这些库,瞧,一切都很有效。旧版 DLL 成功加载了我的 DLL,因为它具有所有正确的依赖项。

更奇怪的是,我决定把每一个都拿出来,看看他们是否真的需要。事实证明,如果我删除了boost_system dll,一切正常,但如果我删除了boost_date_time dll,则一切正常。

所以归根结底,我唯一需要的提升dll就是boost_date_time,所以看起来即使是Visual Studio也是错的。

最后,这就引出了我的问题,当我唯一能做的是 cpprestsdk 需要通过这个语句提升时,我到底应该如何弄清楚我的 CMake 项目需要哪个 dll?

target_link_libraries( PRIVATE cpprestsdk::cpprest cpprestsdk::cpprestsdk_zlib_internal cpprestsdk::cpprestsdk_boost_internal cpprestsdk::cpprestsdk_openssl_internal)

我想我希望答案不是"这取决于"我的代码实际调用的 boost 函数,我不知道答案,因为我不知道 cpprestsdk 实际上根据我的代码调用的 cpprestsdk 函数调用了哪些 boost 函数。

谢谢你的时间。

整个CMake文件如下:

cmake_minimum_required(VERSION 3.7)
include(GenerateExportHeader)
include_directories(${CMAKE_BINARY_DIR})
project(mydll)
set(mydll.SOURCES <source files>)
add_library(mydll SHARED ${mydll.SOURCES})
generate_export_header(mydll
BASE_NAME mydll_exports 
EXPORT_MACRO_NAME mydll_EXPORTS
EXPORT_FILE_NAME mydll_EXPORTS.h
STATIC_DEFINE mydll_EXPORTS_BUILT_AS_STATIC)
find_package(cpprestsdk CONFIG REQUIRED)
target_link_libraries(mydll PRIVATE cpprestsdk::cpprest
cpprestsdk::cpprestsdk_zlib_internal
cpprestsdk::cpprestsdk_boost_internal
cpprestsdk::cpprestsdk_openssl_internal)

嗯,我可能已经部分找到了答案。Visual Studio的"dumpbin"实用程序可以为您部分执行此操作:

映像具有以下依赖项:

HTTPAPI.dll  
WINHTTP.dll  
bcrypt.dll  
CRYPT32.dll  
boost_date_time-vc141-mt-gd-x64-1_69.dll  <- I had to add this
SSLEAY32.dll  <- I had to add this
LIBEAY32.dll  <- I had to add this
zlibd1.dll  <- I had to add this
KERNEL32.dll  
MSVCP140D.dll  
CONCRT140D.dll  
WS2_32.dll  
VCRUNTIME140D.dll
ucrtbased.dll

这里的问题是,即使这不是一个完美的答案,因为我没有添加,也没有httpapi.dll,winhttp.dll,bcrypt.dll和crypt32.dll。它只是可能有效,因为我的代码实际上都没有从这些库中调用任何函数。如果确实需要它们,那么 vcpkg 管理器可能也应该将它们作为依赖项下载,但它没有,所以我无法在当前环境中获取它们。我对这个答案仍然不满意。

我认为工具DependencyWalker(depends.exe)是正确的答案。

它显示所有其他 dll 都是系统 dll,我的应用程序可能正在从系统加载它们,而我需要添加的 dll,当我在cpprestsdk_2_10d.dll上使用它时,它显示这些 dll 缺少依赖项。这就是我所追求的,这就是我真正需要与我的 dll 打包以解决这些依赖问题。我想我会继续将此标记为答案。

最新更新