【问题标题】:Which dlls to include with my compiled executable - Distinguish between system and other dlls哪些 dll 包含在我编译的可执行文件中 - 区分系统和其他 dll
【发布时间】:2021-09-21 11:51:36
【问题描述】:

我有一个使用 CMake 生成构建文件的 c++ 项目。这个项目依赖于外部库,我从互联网上下载了必要的文件(头文件、.lib 和 .dll)。我的项目可以编译,如果库的 DLL 包含在 PATH 中,或者将 DLL 复制到与我的项目的 .exe 相同的位置,则它可以正常运行。现在我希望能够在另一台计算机上运行这个程序。为此,我需要知道我必须在 .exe 文件旁边包含哪些 DLL。

我已经看到任何给定 dll 或 exe 的 DLL 依赖项都可以使用 MVSC dumpbin 找到。例如这个主要的:

#include <QApplication>
#include <QStyleFactory>
#include <QFileDialog>
#include <QStandardPaths>
#include <opencv2/highgui/highgui.hpp>

int main(int argc, char** argv)
{
  // Create application
  QApplication app(argc, argv);
  app.setStyle(QStyleFactory::create(QStringLiteral("Fusion")));

  // Get file name
  QString file_name = QFileDialog::getOpenFileName(nullptr, QObject::tr("Open File"),
                                                QStandardPaths::displayName(QStandardPaths::HomeLocation),
                                                QObject::tr("Images (*.png *.xpm *.jpg)"));

  // Read image
  cv::Mat mat = cv::imread(file_name.toStdString());

  // Show image in opencv
  cv::namedWindow("display",cv::WINDOW_KEEPRATIO |cv::WINDOW_GUI_NORMAL );
  cv::imshow("display",mat);
  cv::waitKey(0);

  // Run application
  return app.exec();
}

dumpbin /dependents main.exe 命令的输出是:

Microsoft (R) COFF/PE Dumper Version 14.28.29912.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file .\src\RelWithDebInfo\main.exe

File Type: EXECUTABLE IMAGE

  Image has the following dependencies:

    Qt5Widgets.dll
    opencv_world347.dll
    Qt5Core.dll
    VCRUNTIME140.dll
    VCRUNTIME140_1.dll
    api-ms-win-crt-runtime-l1-1-0.dll
    api-ms-win-crt-math-l1-1-0.dll
    api-ms-win-crt-stdio-l1-1-0.dll
    api-ms-win-crt-locale-l1-1-0.dll
    api-ms-win-crt-heap-l1-1-0.dll
    KERNEL32.dll
    SHELL32.dll

  Summary

        1000 .00cfg
        1000 .data
        2000 .idata
        1000 .pdata
        3000 .rdata
        1000 .reloc
        1000 .rsrc
        6000 .text

在这种情况下,我需要这个 DLL 列表才能运行我的程序。但是,有些是系统 DLL(KERNEL32.dll、SHELL32.dll...),有些是不是系统 DLL(Qt5Widgets.dll、opencv_world347.dll...)的库。

我应该在哪里决定停止复制 DLL 以发布我的程序?我应该与KERNEL32.dll SHELL32.dll一起发货,我应该包括api-ms-win*.dll还是应该只包括Qt5Widgets.dllQt5Core.dllopencv_world347.dll我如何从列表中知道哪些是系统 DLL,哪些不是?

PS2:我知道专门针对 Qt 有 windeployqt 会自动处理 Qt DLL 部分,并且 VCRUNTIME140*.dll 部分也可以通过安装 vc_redist 来处理

注意:这个问题的范围只是知道在哪里停止。我对如何构建安装程序或如何自动化文件副本或在哪里查找相关 DLL 不感兴趣。

注意2:问题Find dependent modules of dllhow do I include dll's such as kernel32.dll which my unmanaged dll needs 没有回答我的问题。

【问题讨论】:

  • 不允许运送 Windows dll(kernel32、shell32),因为目标操作系统已经安装了它们,所以无论如何都是没有意义的。
  • @500-InternalServerError 我知道这两个,但是api-ms-win*.dll呢?他们是系统吗?我应该复制它们并将它们放到我安装可执行文件的文件夹中吗?我更新了问题标题,试图更清楚地表明我正在寻找的是停止复制 dll 的限制,因为它们已经是系统的一部分。
  • "我应该只包括 Qt5Widgets.dll、Qt5Core.dll 和 opencv_world347.dll" ← 是
  • @spectras 我知道这个具体的例子。但更一般地说,我如何从列表中知道哪些是系统 DLL,哪些不是?
  • 不,那些是 windows 文件。 — 如果您使用一些工具来管理依赖项(这是一个好主意),那么它的工作就是为您提供这些答案。它的工具应该有一些命令或某种方式来获取你必须部署的文件列表。

标签: c++ dll


【解决方案1】:

一般情况

根据我的经验,这个问题经常出现在开发过程的早期。

正如我所见:当一个人开始一个空项目时,不需要在 i 中嵌入任何 dll。如您所说:不提供系统dll。

在某个时候,人们决定在项目中使用 opencv、QT 或任何外部依赖项。此时可以在制作文件(或项目/解决方案文件)中添加所需的头文件,并在构建脚本中添加 dll。

事实上,将 dll 添加到货件中是决定使用依赖项的一部分。

所以对您的问题的简短回答是:您知道要嵌入哪个 dll,因为它是在您尝试添加到项目的依赖项的文档中指定的。 (doc sample for opencv)

具体情况

我们可以想象,有人在某个不起眼的存储库中找到了一段代码,没有任何文档、历史信息,也没有“构建”脚本或等效项。这家伙想要构建和发布它,所以他必须决定要嵌入哪个 dll。

这家伙会做你所做的事情:使用依赖遍历器获取所有依赖列表,然后根据自己的判断决定要提供哪个。

我假设,如果应用程序在 Windows 上运行,这个人会嵌入除 Windows 特定 dll 之外的所有内容,或者执行安装程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    相关资源
    最近更新 更多