aboutsummaryrefslogtreecommitdiff
path: root/content/posts/2021-12-31-tiny-binaries.md
blob: 26eec4dcae1bfa203c0710e153831591c60b7721 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
---
slug: tiny-binaries
title: "Tiny Binaries"
date: "2021-12-31T09:28:32-04:00"
---
Out of curiousity I experimented with building the smallest possible
static [x86-64][] [Linux][] binaries in several programming languages.

Each binary does the following:

1. Print `hi!` and a newline to [standard output][stdout].
2. Return an exit code of `0`.

I tested [Assembly][], [C][], [Go][go], and [Rust][rust] with various
optimization and build option combinations.

Here's a plot of the results (**note:** [log scale][] X axis):

{{< figure
  src="/files/posts/tiny-binaries/sizes-all.min.svg"
  class=image
  caption="All Static Binary Sizes"
>}}

Here's a plot of the smallest static binary sizes (<1k, linear scale X
axis):

{{< figure
  src="/files/posts/tiny-binaries/sizes-tiny.min.svg"
  class=image
  caption="Tiny Static Binary Sizes (<1k)"
>}}

Full Disclosure: `asm-opt` is the smallest *legitimate* result;
`asm-elf` uses dirty tricks from [Tiny ELF Files: Revisited in
2021][tiny-elf].

Source code, build instructions, a [CSV][] of results, and additional
details are available in the [companion GitHub repository][repo].

**Update (2022-01-01):** See [Tiny Binaries: Assembly
Optimization][tb-asm] for an explanation of the assembly results.

**Update (2022-02-24):** [Rust 1.59.0][] was released today
and makes it [significantly easier to create stripped
binaries][rust-strip].

**Update (2022-03-02):** Added a [follow up post][tb-redux] with Go
1.18rc1, Rust 1.59, and TinyGo 0.22.

[x86-64]: https://en.wikipedia.org/wiki/X86-64
  "64-bit version of x86 instruction set"
[linux]: https://en.wikipedia.org/wiki/Linux
  "Linux operating system"
[assembly]: https://en.wikipedia.org/wiki/Assembly_language
  "Assembly language"
[c]: https://en.wikipedia.org/wiki/C_(programming_language)
  "C programming language"
[go]: https://golang.org/
  "Go programming language"
[rust]: https://www.rust-lang.org/
  "Rust programming language"
[log scale]: https://en.wikipedia.org/wiki/Logarithmic_scale
  "Logarithmic scale"
[repo]: https://github.com/pablotron/tiny-binaries
  "Tiny Binaries GitHub repository"
[tiny-elf]: https://nathanotterness.com/2021/10/tiny_elf_modernized.html
  "Tiny ELF Files: Revisited in 2021"
[stdout]: https://en.wikipedia.org/wiki/Standard_streams#Standard_output_(stdout)
  "Standard output."
[csv]: https://en.wikipedia.org/wiki/Comma-separated_values
  "Comma-Separated Values"
[tb-asm]: {{< ref "/posts/2022-01-01-tiny-binaries-assembly-optimization.md" >}}
  "Tiny Binaries: Assembly Optimization"
[rust 1.59.0]: https://blog.rust-lang.org/2022/02/24/Rust-1.59.0.html
  "Rust 1.59.0 release announcement."
[rust-strip]: https://blog.rust-lang.org/2022/02/24/Rust-1.59.0.html#creating-stripped-binaries
  "Creating stripped binaries section of Rust 1.59.0 release announcement."
[tb-redux]: {{< ref "2022-03-02-tiny-binaries-redux.md" >}}
  "Tiny Binaries Redux post with Go 1.18rc1, Rust 1.59, and TinyGo 0.22.0."