如何在CMake中的卡萨布兰卡(cpprestsdk)中发现Boost DLL依赖项

How to discover boost DLL dependencies in Cassablanca (cpprestsdk) in CMake

这是我的第一篇文章,所以请多多包涵。这是我的设置:

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

我正在使用Microsoft的软件包管理器(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的位置:

设置(ZLIB_ROOT" $ {VCPKG_HOME_WIN} / zlib_x64-windows")
设置(OPENSSL_ROOT_DIR" $ {VCPKG_HOME_WIN} / openssl-windows_x64-windows")

这一切都很好,并且很好用。然后我来提振。当使用vcpkg安装cpprestsdk时,它足够聪明,可以下载它将需要的所有增强功能,因此,有大量的带有大量DLL的boost目录。

当我尝试从旧版应用程序的DLL中调用函数时,由于无法找到其依赖DLL,导致DLL无法加载。我将restsdk,openssl和zlib dll复制到了旧版应用程序中,但是我不知道要复制哪些boost dll。显然,我可以shot弹枪,并简单地复制vcpkg作为restsdk的一部分下载的所有boost dll,但这似乎有些杀伤力。

最后,我不确定该怎么做,所以我在Visual Studio中构建了整个CMake项目。 Visual Studio以某种方式足够聪明地解决了这个问题,并且在我项目的输出目录中放置了以下增强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,一切都没有问题。

因此,到最后,我唯一需要的boost 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文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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)

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

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


嗯,我可能已经部分想出了答案。 Visual Studio的" dumpbin"实用程序可以为您部分完成此操作:

图像具有以下依赖性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 Manager可能也应该将它们下载为依赖项,但事实并非如此,因此我无法在当前环境中获得它们。我对这个答案仍然不满意。