I just read on how to remove alot of dependencies on system libs in windows C code which resulted in a very small executable. What I tried in Nim was just:
var a = 1
nimrod compile --deadCodeElim:on --opt:size lab1.nim
But due to system.c, lab.exe becomes 168kb for that one line.
Are there more ways to tell the compiler to remove more or are there other ways to step around it?
You can also try clang with LTO as backend instead of gcc. See my test:
|--lineTrace:off does not change the size at all|
|--gc:off costs less than 9kb|
|--os:standalone doesnt compile but generates:|
system.nim(2126, 10) Error: cannot open 'panicoverride'
How do I get around the panicoverride error?
Also I tried changing switching to clang but ran into this (using windows8, and couldnt find gold to link with!?):
clang.exe -o w:nimcodejunklab1.exe w:nimcodejunknimcachesystem.o w:nimcodejunknimcachelab1.o system.o : error LNK2019: unresolved external symbol fileno referenced in function systemInit system.o : error LNK2019: unresolved external symbol setmode referenced in function systemInit w:nimcodejunklab1.exe : fatal error LNK1120: 2 unresolved externals clang.exe: error: linker command failed with exit code 1120 (use -v to see invocation) Error: execution of an external program failed
For anyone interested:
Interesting that windows executables are much larger than on Linux...
For clang LTO backend: I had some difficulties to get it work on my Gentoo Linux box, because the default has to be still gcc for my box. I wrote how I solved it, but I can not tell you for Windows... But you should test a plain C program first -- when that does not work, Nim will not also.
Generally: Testing with an input file which does nothing may not make much sense -- even an stupid compiler may notice that there is no output and no other activity and simple generate a few byte minimal dummy file. And: GC is generally needed, because std lib may use it. I once did a test compile without CG and noticed a size difference of a few 10 kB -- I really thing GC will be larger than 9kB. So question is what makes the 9k difference you noticed. And what is you motivation at all? File size is important for embedded devices, but not really for PC. I guess, when you really wants to investigate this topic, you may look at the generated C code in nimcache directory. Generally Nim is good with file size, and may become even better when developers have solved all the other more important topics. Rust was very bad with filesize in early days, and someone told me some months ago that Rust generates still larger files than Nim.
thx Araq nimrod compile --deadCodeElim:on --opt:size --stackTrace:off --lineTrace:off -d:release --os:standalone lab1.nim
now generated ~134 kb of .exe
with clang it generaed 79 kb of .exe (but omitting the .exe since the line generated was:
clang.exe -o w:nimcodejunklab1 w:nimcodejunknimcachepanicoverride.o w:nimcodejunknimcachesystem.o w:nimcodejunknimcachelab1.o
So 168 to 79 kb is realtivly easy.
Compile time with gcc = 178ms, with clang about 128ms
IF we want to go even smaller the question is if we can make the compiler kill even more dead code or make it compile without the CRT in windows. In this post: https://forums.handmadehero.org/index.php/forum?view=topic&catid=4&id=79 he takes an empty windows program in c that compiles to 68KB and shows how avoid the c/c++ runtime and reducing the size to about 2.5KB (admittingly he adds code at the end). Also he is compiling using vcc (cl.exe) and not clang, implying that the code could be even smaller.
Are there any other steps we can do in Nim, in order to reduce the size beyond my 134KB/79KB ?