'Why is the import library .lib bigger than the .dll?
In a cmake project that generates a .dll and corresponding .lib I just noticed the .lib is bigger than the .dll. How is that possible? Isn't the .lib supposed to be much smaller than the .dll?
debug
.lib (~870KB) and .dll (~700KB)
release
.lib (~200KB) and .dll (~200KB)
CMakeLists.txt
cmake_minimum_required(VERSION 3.19.1)
project(mylib)
set (CMAKE_CXX_STANDARD 14)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
link_libraries(${OpenCV_LIBS})
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
add_library(mylib SHARED mylib.cpp another_lib.cpp)
Wondering if perhaps there is something wrong with the CMakeLists.txt?
And why is the .lib size different in debug and release builds?
dumpbin.exe /symbols mylib.lib
Microsoft (R) COFF/PE Dumper Version 14.29.30133.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file mylib.lib
File Type: LIBRARY
COFF SYMBOL TABLE
000 010175B5 ABS notype Static | @comp.id
001 00000000 SECT2 notype External | __IMPORT_DESCRIPTOR_mylib
002 C0000040 SECT2 notype Section | .idata$2
003 00000000 SECT3 notype Static | .idata$6
004 C0000040 UNDEF notype Section | .idata$4
005 C0000040 UNDEF notype Section | .idata$5
006 00000000 UNDEF notype External | __NULL_IMPORT_DESCRIPTOR
007 00000000 UNDEF notype External | ⌂mylib_NULL_THUNK_DATA
String Table Size = 0x52 bytes
COFF SYMBOL TABLE
000 010175B5 ABS notype Static | @comp.id
001 00000000 SECT2 notype External | __NULL_IMPORT_DESCRIPTOR
String Table Size = 0x1D bytes
COFF SYMBOL TABLE
000 010175B5 ABS notype Static | @comp.id
001 00000000 SECT2 notype External | ⌂mylib_NULL_THUNK_DATA
String Table Size = 0x1D bytes
Summary
C3 .debug$S
14 .idata$2
14 .idata$3
8 .idata$4
8 .idata$5
C .idata$6
Solution 1:[1]
I just noticed the
.libis bigger than the.dll. How is that possible?
Simple math. Each export in the DLL's .edata section consists of the symbol name, its 32-bit relative virtual address (RVA), and a 16-bit ordinal. That is, the length of the exported symbol plus 6 bytes. The import library, by contrast, contains (at a minimum) the symbol name, the name of the module exporting the symbol, plus file format overhead, for each symbol.
In other words: The encoding of an exported symbol takes up more space in an import library than it does in a module's export table. As you're adding exports, the import library grows faster than the module. At some point the size of the import library will exceed the size of its corresponding module.
And indeed, you're trying hard to export just about any symbol that can be exported from the CMake script:
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
This is setting the WINDOWS_EXPORT_ALL_SYMBOLS property to TRUE, causing every symbol (except for data symbols) to be implicitly exported.
This is generally not what you'd want, and you should remove that line from the CMake script. You'll immediately see that both the import library as well as the module will get smaller. As an added bonus this enables several linker optimizations that would otherwise be left unused.
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 |
