Live data from Hacker News

Show HN: Tiny 1k Rust binary on Windows

github.com

31–40 of 66 posts

Re: Show HN: Tiny 1k Rust binary on Windows

#31
post #16

I'm disappointed. In C I can get a 1k Hello Word binary simply be writing int main(void) { puts("Hello World!"); return 0; } The Rust version is a mess [0] [0] https://github.com/mcountryman/min-sized-rust-windows/blob/m...

You're comparing C+StdLib vs. Rust without StdLib. Disable stdlib for C version and use the following program: #include int _start() { const char str[] = "Hello world!\n"; HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE); DWORD written; WriteFile(stdout, str, sizeof(str), &written, NULL); ExitProcess(12); return 0; } https://stackoverflow.com/a/42536990 Which is similar to what the Rust program does. The result should…

I think the thing being measured by GP is "easiest way to get to the 1kb mentioned in the title" not "most complicated way to get as small as possible".

Re: Show HN: Tiny 1k Rust binary on Windows

#32
post #24

Earlier quoted context omitted.

They are not the same, and the asm! version is already implemented; the RFC came with an implementation. That first PR moved the old asm to llvm_asm, and then the new asm was built after a period of time so folks could migrate their code to llvm_asm, as a temporary measure. This commit happened after that transition so this has to be from the new asm back to the transition version.

Oops, my bad, I was working with an outdated understanding of the situation. Thanks for correcting me.

No problem :) It was a feature that had no changes for a long time, and now has had a bunch of improvements and is finally on a path to stable. It can be hard to keep up with things sometimes.

Re: Show HN: Tiny 1k Rust binary on Windows

#33
post #22

Zig actually does a good job of cutting final output bytes automatically , even with standard library use. I think (?) its compiler sort-of implements a more advanced version of Unix strip. Andrew Kelley could probably chime in more on it.

It's very easy and fast to try: using 0.7.0+51d7c14ce from https://ziglang.org/download/ and: const std = @import("std"); pub fn main() void { std.debug.print("Hello, world!\n", .{}); } ---------- zig build-exe hello.zig -O ReleaseSmall --strip --single-threaded -target x86_64-windows Resulting hello.exe is 3072 bytes. From these 2560 are zero bytes . The only system calls from the resulting binary are to ExitProcess…

Ah, yeah, I wasn't trying to shrug off the usefulness of zig, sorry. I think when it comes to compile size zig does it a bit better due to it's smaller std although, when compiling rust with just a link to libc and a printf call I believe you get an exe ~2048b when optimizing for size so I'm not certain how well that scales.

The 100 line hack I used was to noop out the `.idata` section which link.exe refused to merge/shrink, that only saved me 1Kb in the end.

Looking at the section info of the zig exe it looks like there is some black magic going on with it's alignment so I may have to dig deeper to see what zig is doing here. Also thank you both for pointing zig out, I haven't heard of it until now and it may come in handy for something else I'm planning on making :)

Re: Show HN: Tiny 1k Rust binary on Windows

#34
post #17

Earlier quoted context omitted.

Can you, though? Compiling that source on Windows using visual studio produces a 98K executable.

You just need to add some compiler options; /MD should get the size down quite a bit already, then decrease the file alignment and merge sections together: /MD /link /align:4096 /filealign:512 /merge:.rdata=.text /merge:.data=.text That produced a 1.5K binary, which with a custom stub should reach 1K.

In order to get that to 1Kb you would probably have to drop the `.idata` section and resolve syscalls from the PEB like I did.

Re: Show HN: Tiny 1k Rust binary on Windows

#35

I'm disappointed. In C I can get a 1k Hello Word binary simply be writing int main(void) { puts("Hello World!"); return 0; } The Rust version is a mess [0] [0] https://github.com/mcountryman/min-sized-rust-windows/blob/m...

Have you actually tried this on MSVC? This is my program. I created a file called `small.c`

    #include 
    
    int main(void) {
        puts("Hello World!");
        return 0;
    }

I then compiled it using this command:

   cl small.c /MD
The result? 9kb! That's 9 times the size.

Re: Show HN: Tiny 1k Rust binary on Windows

#36
post #17

Earlier quoted context omitted.

Can you, though? Compiling that source on Windows using visual studio produces a 98K executable.

You just need to add some compiler options; /MD should get the size down quite a bit already, then decrease the file alignment and merge sections together: /MD /link /align:4096 /filealign:512 /merge:.rdata=.text /merge:.data=.text That produced a 1.5K binary, which with a custom stub should reach 1K.

Have you actually tried this? Merging .data into .text doesn't work. The binary doesn't run and there's this link warning:

> LINK : warning LNK4254: section '.data' (C0000040) merged into '.text' (60000020) with different attributes

Re: Show HN: Tiny 1k Rust binary on Windows

#37
post #16

I'm disappointed. In C I can get a 1k Hello Word binary simply be writing int main(void) { puts("Hello World!"); return 0; } The Rust version is a mess [0] [0] https://github.com/mcountryman/min-sized-rust-windows/blob/m...

You're comparing C+StdLib vs. Rust without StdLib. Disable stdlib for C version and use the following program: #include int _start() { const char str[] = "Hello world!\n"; HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE); DWORD written; WriteFile(stdout, str, sizeof(str), &written, NULL); ExitProcess(12); return 0; } https://stackoverflow.com/a/42536990 Which is similar to what the Rust program does. The result should…

I tried your program with MSVC using the following command:

    cl small2.c /MD /link /entry:_start /subsystem:CONSOLE kernel32.lib
It's 5kb.

Re: Show HN: Tiny 1k Rust binary on Windows

#38
post #36

Earlier quoted context omitted.

You just need to add some compiler options; /MD should get the size down quite a bit already, then decrease the file alignment and merge sections together: /MD /link /align:4096 /filealign:512 /merge:.rdata=.text /merge:.data=.text That produced a 1.5K binary, which with a custom stub should reach 1K.

Have you actually tried this? Merging .data into .text doesn't work. The binary doesn't run and there's this link warning: > LINK : warning LNK4254: section '.data' (C0000040) merged into '.text' (60000020) with different attributes

[deleted]

Re: Show HN: Tiny 1k Rust binary on Windows

#39
post #27

I'm disappointed. In C I can get a 1k Hello Word binary simply be writing int main(void) { puts("Hello World!"); return 0; } The Rust version is a mess [0] [0] https://github.com/mcountryman/min-sized-rust-windows/blob/m...

The smallest executable gcc (on Ubuntu) compiles that to is 8296 bytes (tried every -O optimization).

Hm I only looked at the output of size which gives

   text    data     bss     dec     hex filename
   1566     600       8    2174     87e hello
(no optimisations)
Post reply on HN