151-byte static Linux binary in Rust
mainisusuallyafunction.blogspot.com
mainisusuallyafunction.blogspot.com
But honestly... does it really matter how small your executable is? I'd care a lot more about performance characteristics than binary size.
[1] http://www.muppetlabs.com/~breadbox/software/tiny/teensy.htm...
Of course, this is just an approximate general rule, and extremely small binaries (and generally any "pointless" experimentation) like this are mainly interesting from a learning point of view (or for small embedded microcontrollers), e.g. understanding syscalls and program start-up, and, for the write-up you link, the ELF format. (Not everything has to be inherently useful for an actual task.)
So we already knew that about assembler, now we also know Rust can be twisted quite close to that too.
It demonstrates how much control you can choose to exert over your compiled program.
The key word here is I'd. The programming world is vast, and the range of hardware is likewise vast. So, so vast. Really huge. Pick a restriction you don't have to worry about; someone else out there does.
Hello World in Rust with tip of tree (as of yesterday) is a ~500K binary that depends on glibc and friends.
Switching from println!() to std::io...write_str() actually made it larger!
The only unresolved symbol is: __libc_start_main@@GLIBC_2.2.5
Even if that means him dismissing me/my question entirely lol.
Because that's explicitly one of the things Rust was developed for.
Here's a whole list of kernels and other OS projects that have been created using Rust:
https://github.com/rust-lang/rust/wiki/Operating-system-deve...
As I recall Rust is currently targeting only Intel and ARM backends.
And it's way too early to see if it'll make it.
push 1
pop eax
mov edi, eax
mov esi, 400008h
push 7
pop edx
syscall
push 3ch
pop eax
xor edi, edi
syscall
It should be 10 bytes shorter.All of the machine code comes out of rustc. (Although all of the instructions that survive optimization went in as inline assembly.)
So while his main() is written in (unsafe) Rust, he's basically using it as a macroassembler.
(Edit: I mistook this for a Go thread.)
If so I can see that working for very simple code, but what about wanting to use Tasks/Threads or do I/O. Is that converted to native system calls at compile time?
The RFC describing the changes is [^1] and the actual commit that finalized them is [^2].
[^1]: https://github.com/rust-lang/rfcs/pull/230
[^2]: https://github.com/rust-lang/rust/commit/0efafac398ff7f28c5f...
As far as I know, Go statically links the runtime into the binary (including the garbage collector, the scheduling system and more)... so for a small program like this sample, it will appear to be abnormally bloated. If it were a larger, more complex example, then the binary size wouldn't change as drastically (and on a surface level might appear to be more justifiable).
? http://doc.rust-lang.org/std/
> there would likely be multiple json or http libraries (just to name "low-level" libraries with widespread usage)
The standard library used to build json in, that was actually split out to a standalone libraries for various reasons: https://github.com/rust-lang/rustc-serialize
> and you might end up linking a few of them in a binary as indirect dependency.
That's not a counter-argument to erglkjahlkh's comment. In fact it's pretty much irrelevant:
* Go works at a library level, when you import fmt you don't import encoding/json, and it's not loaded
* The issue he outlines is mostly that Go does little to no dead code elimination, when a library is imported all of its content (and the content of its dependencies) will end up in the final library, even if you only access a small utility function
Yet. With the rewrite of the compiler it is safe to assume that there will be many optimizations to come.
http://forum.dlang.org/post/qcbicxrtmjmwiljsyhdf@forum.dlang...
The PE format is rather bulkier than ELF, though.
On Linux, with dynamic linking:
rustc: 8656 bytes
clang: 6960 bytes
gcc: 6688 bytes