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可能也应该将它们下载为依赖项,但事实并非如此,因此我无法在当前环境中获得它们。我对这个答案仍然不满意。