Angle.Bracket
Angle.Bracket

Reputation: 1532

Why does the msvc linker produce such a large exectuable when invoked from the command line?

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

Answers (1)

Angle.Bracket
Angle.Bracket

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

Related Questions