'.lib and .dll file size difference on visual studio and cmake

I followed https://docs.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?



Solution 1:[1]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 IInspectable