Hacker News new | ask | show | jobs
by vparikh 400 days ago
Looks like you are linking to static libraries. You should link to DLL not to static libraries - this is will cut down on the application size dramatically.
2 comments

That seems backwards. If you need to ship the DLLs with the program anyway (they are not part of the operating system, after all), they will contain their full functionality, each one potentially with its own C runtime, etc. If you statically compile everything into a single EXE, there will be only a single C runtime, all unused functions can be trivially removed, etc.

DLLs only reduce size if their code is meant to be shared between different programs.

> they are not part of the operating system

Yes they are. Exercising the native Windows API is the entire point of this project, and the only artifact it builds is an executable.

edit: See the thread; I had the wrong end here. I haven't worked with Win32 or C in so long I'd forgotten what balls of fishhooks and hair they both tend to be.

The CRT is not part of the operating system, unless you count the UCRT on Windows 10 onwards (yes there is also a MSVCRT copy in the Windows folder that Microsoft strongly discourages you from using, so let's ignore that for now). So unless you link against the system-provided UCRT, you will have to either ship a dynamic or a static copy of the C runtime, and linking it statically will be smaller because that will only contain the few string and time functions used by the program, instead of the whole CRT.
Why would you not link against the UCRT if you’re intentionally designing for Win32 though? It’s a decade old library by now. Time flies…
Some people value being able to support older OSes without shipping the entire UCRT as an optional component. Granted, this will become less and less relevant in the future...
At this point, the only Windows version which doesn't ship uCRT that's not out of support is Windows Server 2012 R2 VL, and even that is only supported through the paid Extended Security Updates program which ends next year.
The idea that something which ships with the OS, as a compatibility shim for legacy but still intentionally supported applications, can be called "not part of the OS," is religious. Strongly discouraged or otherwise, I believe it to be in use here.

Not sure. I haven't really done anything serious with MinGW, or Cygwin or even Windows really, in at least a decade now. But there's not really a lot going on in the build here, so I would imagine with your much more recent experience you'd be better able to interpret what's there.

edit: Wait, are you even discussing the old (okay, ancient) Win32 API? I'm confused, but as I said, it's been a very long time since I attended the space.

The important thing in the context of the original question is that mingw uses its own C runtime (MSVCRT is old and incomplete - you would not be able to use it as a drop-in replacement for a modern CRT). You can link the mingw CRT statically or dynamically, and OP suggested that linking it dynamically would reduce the size. But that is only true for the main executable. You would still have to ship the mingw CRT alongside, which in return would increase the distribution size of the program again.

I hope that clears my point up.

MSVCRT works perfectly fine for something with this feature set.
Regarding your edit: the CRT is responsible for headers such as time.h and string.h, which you can find being used in todo.h. Their implementations are not provided by the operating system but by the C runtime typically supplied by the compiler (mingw in this particular case). Other headers such as windows.h belong to the WinAPI, and result in functions being imported from OS libraries such as user32.dll. They are obviously not linked statically into the program.
> such as time.h and string.h

In Windows, the APIs provided by the OS are IMO better than these C standard headers.

WinAPI date/time is more precise, the kernel keeps int64 number of 100 nanosecond ticks. WinAPI supports arbitrary timezones, has functions to convert between timezones, has functions to deal with daylight saving.

About strings, WinAPI can convert strings between encodings, case-insensitive comparisons (including a version to use arbitrary locale), Unicode normalization, etc.

The CRT has been an OS component on Windows for a decade now:

https://learn.microsoft.com/en-us/cpp/porting/upgrade-your-c...

MinGW does not provide its own CRT. Historically, it used msvcrt.dll, which is the old and outdated CRT for VC++ 6.0 that was included in Windows a long time ago. These days it can also use uCRT, and that is indeed the new default:

https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64...

Ugh, thanks. That clears it up.

Say what you like about the modern JS ecosystem, the practical requirement of a single exhaustive declaration of all external dependencies and their sources is not to be sneered at.

You must not have worked with Win32 or C recently, they both tend to be giant balls of fishhooks and hair.

edit: Saw that you just now edited your comment, glad we're on the same page now.

Quite literally, it would seem! What an entirely remarkable coincidence.
Call it a coincidence all you want, we both know you just copy/pasted my comment into your own edit.
Bold, I'll give you that. Did we both get that from the UNIX-HATERS Handbook? I believe it originally described Perl, and not at all unjustly.
Not really, because this is Windows we are talking about.

A traditonal Windows application would be using the Windows APIs, and not the C standard library, e.g. FillMemory() instead of memset(), thus there is no DLLs to ship with the application.

As can be seen on Petzold books examples.

This code is not from the Petzold books. It literally includes and uses string.h, stdlib.h and time.h. It is not using WinAPI equivalents of C functions.
Exactly why there is still enough room to be a smaller executable.
No, linking to a static version of the CRT is a good thing, it cuts out the unused code. If you dynamic link to MSVCRxx/VCRUNTIME, you force the user to download that exact DLL from Microsoft. Dynamic linking to MSVCRT doesn't have that problem, but it's very hard to do in Visual Studio.

The only time you really can't static link to the CRT is LGPL compliance?

Windows has been shipping an up-to-date, modern CRT in the box for a decade now (Win10+), and MinGW will even dynamically link to it by default. Even on out-of-support OSes like Vista and Win7, users who have all the security updates installed will have it. So you have to unwind all the way back to WinXP for a version of Windows that doesn't have uCRT out of the box.

There's absolutely no reason to statically link CRT in a Win32 app today. Especially not if your goal is to minimize .exe size.

Note that the project is using mingw, so it's not using any Microsoft DLLs for the CRT anyway. mingw brings its own CRT along.
I thought Mingw defaulted to MSVCRT.DLL as the CRT?
It looks looks mingw actually has several options to base its own CRT on (including MSVCRT, UCRT and various VS runtimes). Still, in the context of OP's original post, we are talking about the mingw DLLs that may or may not redirect most of their duties to Microsoft DLLs, depending on how mingw is configured.
It's really hard these days to get Mingw to use msvcrt. It's not supported.