Why does nim statically link everything? Not only does it make executables huge (more than 50 KB for hello world!), it makes compile times longer. Also, I am under the impression that nim compiles all included files (at the minimum standard.nim) while compiling a program. Why can't the functions or other resources used be compiled individually without compiling the extraneous stuff? For example, if I compile "echo "Hello, world!" then only echo and other necessary methods would be compiled from the standard library. Or is this already how its done?
2015-04-30 22:10:55

You have the option of linking the stdlib dynamically if you set up your system accordingly (-d:useNimRtl). Note also that Nim already does dead code elimination with the command line option or the pragma (also implied by -d:release), so it will then only generate code for procedures and variables that are actually being used. Hello world still has a minimum size because the garbage collector and a few other basic things are always included.

That said, unless you're running your code on a toaster, there's really not much point to dynamic linking, except for frequently used system libraries, and dynamic linking has a lot of downsides.

2015-04-30 22:30:48

Why does nim statically link everything?

Dynamic linking is possible: See



I think 50 KB for a HelloWorld executable is really not bad for a high level language, which generally includes GC and other runtime code. For my tests clang gave smallest executables, even smaller with LTO enabled. But gcc executables may be faster in some cases. Yes, I think that Nim indeed compiles all included files currently. For examples when templates are used that may be necessary? But Nim compiler is already really fast, and C backend compiles only changed files.

2015-04-30 22:32:43

How would I compile without the GC to get a smaller executable? I just want to see how small I can get it, and also, since it's just printing a string, it doesn't make sense to have a GC.

Stefan_Salewski: C backend compiles only changed files.

What does that mean?

2015-04-30 23:16:56
--gc:none may work as command line option for Nim, but I think that is not really recommended, because standard library may need GC. For the C backend: Nim generally generates C files, which are processed by gcc or clang. C files are stored in nimcache directory and are only generated again when necessary. Generally, very small executables are only needed for very small Microcontrollers like 8 bit AVR, but even these have 64 or more KB program memory generally.
2015-04-30 23:33:43
Ah, I understand: Once I've compiled my program once, it won't compile standard.nim again unless I change standard.nim, which I won't, or if I change my compile flags. Still, I thought nim had an optional garbage collector! How is it optional if I can't safely turn it off even for hello world? 2015-05-01 01:05:28

You can safely turn it off for a hello world program. The code:

echo "Hello, world!"

will be translated (after optimization) into something like:

void hwInit() {
  printf("%s\n", "Hello, world!");

(plus the general initialization boilerplate).

That said, I'm not sure why you'd want to turn the GC off for anything more complex.

2015-05-01 01:53:38
Also, if you pass -gc:none, and use something that requires GC, the compiler warns you at compile time.
2015-05-01 06:26:08
>I just want to see how small I can get it,
$ cat t.nim
echo "hello"

Nim Compiler Version 0.11.0 (2015-05-03) [Linux: amd64]
gcc version 4.9.2
clang version 3.6.0

nim c -d:release t.nim
Executable size:  62032 bytes

nim c --opt:size -d:release t.nim
Executable size: 25208 bytes

nim c --opt:size --gc:none -d:release t.nim
Executable size: 14536 bytes

nim c --cc:clang -d:release t.nim
Executable size:  33392 bytes

nim c --opt:size --cc:clang -d:release t.nim
Executable size:  29296 bytes
2015-05-03 18:05:55