Reputation: 1532
I am using Microsoft (R) Incremental Linker Version 14.16.27041.0 both from the command line and via a Visual Studio project.
I am compiling and linking the following well-known program residing in a file called HelloWorld.c
:
#include "stdio.h"
int main() {
printf("Hello World !\n");
return 0;
}
The sizes of the respective *.exe files differ in a remarkable way:
a) Compiled and linked as a VS project using the default linker options from the VS Debug Build:
/OUT:"D:\HelloWorld.exe" /MANIFEST /NXCOMPAT /PDB:"D:\00_HelloWorld.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG:FASTLINK /MACHINE:X86 /INCREMENTAL /PGD:"D:\00_HelloWorld.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\00_HelloWorld.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1
38,400 HelloWorld.exe
b) Compiled and linked on the command line:
link /OUT:HelloWorld.exe HelloWorld.obj
102,400 HelloWorld.exe
I tried to figure out which of the additional linker options that VS provided could lead to the smaller executable, but could not find any, especially as /OPT:ICF and /OPT:REF (the ones that seemed to be the most likely candidates in my opinion) are enabled automatically when link.exe
is invoked at the command line, as it says here: /OPT (Optimizations) MSVC Linker Reference
Can anybody explain these different sizes ?
EDIT:
The program was compiled using
a)
/JMC /permissive- /GS /analyze- /W3 /Zc:wchar_t /ZI /Gm- /Od /sdl /Fd"Debug\vc141.pdb" /Zc:inline /fp:precise /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /FC /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\00_HelloWorld.pch" /diagnostics:classic
b)
cl /c HelloWorld.c
Upvotes: 0
Views: 322
Reputation: 1532
It is the /MD compiler(!) option that is responsible for the different sizes.
Compiling the above program like so:
cl /c /MD HelloWorld.c
and linking it in the same way like above:
link /OUT:HelloWorld.exe HelloWorld.obj
yields the following executable:
8,192 HelloWorld.exe
The /MD option instructs the compiler to produce an object file with a built-in library name MSVCRTD.lib
that acts as am internmediate layer between the program and the CRT residing in a DLL called MSVCRversionnumber.DLL
. (See also here for more information: /MD option MSVC compiler). Not using this option results in a executable with statically linked CRT libs, hence the larger size.
Note that this way of compiling and linking C/C++ programs does require the existence of the aforementioned DLL on the target platform (including version number).
Upvotes: 1