Visual Studio 和 cmake 上的 .lib 和 .dll 文件大小差异

发布于 2025-01-19 16:15:30 字数 806 浏览 1 评论 0原文

我跟着 https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-170 在调试模式下创建 dll,并使用 cmake 执行相同的操作。

cmake_minimum_required(VERSION 3.19.1)

project(MathLibrary)

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)

add_library(MathLibrary SHARED MathLibrary.cpp)

毕竟我知道

#### debug vs

2.4K Apr  7 15:10 Debug/MathLibrary.lib
 38K Apr  7 15:10 Debug/MathLibrary.dll*

#### debug cmake

2.9K Apr  7 16:20 MathLibrary/build/Debug/MathLibrary.lib
 52K Apr  7 16:20 MathLibrary/build/Debug/MathLibrary.dll*

为什么文件大小不同?还有什么不同?是否可以使用 cmake 创建相同的文件?如何?

I followed
https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-170
to create the dll in debug mode and did the same using cmake.

cmake_minimum_required(VERSION 3.19.1)

project(MathLibrary)

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)

add_library(MathLibrary SHARED MathLibrary.cpp)

After all I got

#### debug vs

2.4K Apr  7 15:10 Debug/MathLibrary.lib
 38K Apr  7 15:10 Debug/MathLibrary.dll*

#### debug cmake

2.9K Apr  7 16:20 MathLibrary/build/Debug/MathLibrary.lib
 52K Apr  7 16:20 MathLibrary/build/Debug/MathLibrary.dll*

Why file size is different? What else is different? Is it possible to create an identical file using cmake? How?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风追烟花雨 2025-01-26 16:15:30

如果没有看到 IDE 传递给编译器和链接器的完整命令行,就很难确定地回答这个问题。

模块大小的差异可能由多种原因造成,例如:

  • 支持库的动态和静态链接之间不匹配(/MDd/MTd
  • 不同的异常处理模型(/EH
  • 不同的浮点行为(/fp)
  • 不同的目标架构(例如 x86 与 x64)
  • ...

您必须比较命令行传递给每个编译器和链接器看看是否有任何差异。

模块的大小也很可能由于导致导入库增长的原因而增长:CMake 脚本正在设置 WINDOWS_EXPORT_ALL_SYMBOLS 属性设置为 TRUE。这是 Microsoft 构建工具的非标准行为,其中符号默认为私有且必须显式导出。

如果您要求每个符号都是公开的,这显然意味着您的导入库有更多条目,因此它会变得更大。因此,如果您从模块中导出更多符号,那么该模块的导出表也会增长。

这里还有一个不太明显的效果:当符号是私有的时,链接器可以轻松证明它是否正在被使用。所有潜在的用途必须来自模块内部。如果链接器可以证明某个符号未被使用,则可以将其从生成的模块中删除。另一方面,如果您将所有内容公开,则链接器将无法再执行此优化。

那么,只需

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)

从 CMake 脚本中删除,您可能会看到更多可比较的结果。一旦该行消失,请确保不再将此特定属性设置为 TRUE

Without seeing the full command line passed by the IDE to the compiler and linker, it's fairly hard difficult to answer the question with certainty.

The difference in size in the modules could be down to any number of reasons, such as:

  • Mismatch between dynamic and static linking of the support libraries (/MDd vs. /MTd)
  • Different exception handling models (/EH)
  • Different floating point behavior (/fp)
  • Different target architectures (e.g. x86 vs. x64)
  • ...

You'll have to compare the command lines passed to the compiler and linker for each to see if there are any differences.

It's also quite possible that the module grew in size due to what caused the import library to grow: The CMake script is setting the WINDOWS_EXPORT_ALL_SYMBOLS property to TRUE. This is non-standard behavior for Microsoft's build tools, where symbols default to being private and have to be explicitly exported.

If you request that every symbol be public that clearly means that your import library has more entries, so it gets larger. Consequently, if you're exporting more symbols from your module then that module's export table will grow as well.

There's also a less obvious effect here: When a symbol is private, the linker can easily prove whether it is being used. All potential uses must necessarily come from inside the module. If the linker can prove that a symbol isn't used it can be removed from the resulting module. If, on the other hand, you make everything public, then the linker can no longer perform this optimization.

So then, simply remove

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)

from your CMake script, and you'll probably see a lot more comparable results. Once that line is gone make sure to not ever set this particular property to TRUE again.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文