<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>musl on
A Scripter's Notes</title><link>https://scripter.co/tags/musl/</link><description>Recent content in musl
on A Scripter's Notes</description><language>en-us</language><managingEditor>kaushal.modi@gmail.com (Kaushal Modi)</managingEditor><webMaster>kaushal.modi@gmail.com (Kaushal Modi)</webMaster><lastBuildDate>Wed, 22 Apr 2026 08:24:58 -0400</lastBuildDate><generator>Hugo -- gohugo.io</generator><docs>https://validator.w3.org/feed/docs/rss2.html</docs><atom:link href="https://scripter.co/tags/musl/index.xml" rel="self" type="application/rss+xml"/><item><title>Nim: Deploying static binaries</title><link>https://scripter.co/nim-deploying-static-binaries/</link><description>&lt;blockquote>Deploying Nim applications as static binaries for GNU/Linux type
operating systems, built using &lt;strong>musl&lt;/strong>.&lt;/blockquote>&lt;div class="ox-hugo-toc toc">
&lt;div class="heading">Table of Contents&lt;/div>
&lt;ul>
&lt;li>&lt;a href="#problem-statement">Problem statement&lt;/a>&lt;/li>
&lt;li>&lt;a href="#solution">Solution&lt;/a>&lt;/li>
&lt;li>&lt;a href="#1-building-static-binaries">1 Building static binaries&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#what-is-musl">What is musl?&lt;/a>&lt;/li>
&lt;li>&lt;a href="#installing-musl">Installing musl&lt;/a>&lt;/li>
&lt;li>&lt;a href="#static-linking">Static linking&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#2-optimizing-the-binary-size">2 Optimizing the binary size&lt;/a>&lt;/li>
&lt;li>&lt;a href="#3-doing-the-above-two-easily">3 Doing the above two easily&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#nimscript">NimScript&lt;/a>&lt;/li>
&lt;li>&lt;a href="#config-dot-nims">&lt;code>config.nims&lt;/code>&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#4-creating-and-deploying-the-builds-automatically">4 Creating and deploying the builds automatically&lt;/a>&lt;/li>
&lt;li>&lt;a href="#how-it-works-in-practice">How it works in practice&lt;/a>&lt;/li>
&lt;li>&lt;a href="#repo">Repo&lt;/a>&lt;/li>
&lt;li>&lt;a href="#references">References&lt;/a>&lt;/li>
&lt;/ul>
&lt;/div>
&lt;!--endtoc-->
&lt;h2 id="problem-statement">Problem statement&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#problem-statement">#&lt;/a>&lt;/h2>
&lt;p>I&amp;rsquo;d like to create Nim applications, and then be able to easily deploy
the static built binaries so that anyone on GNU/Linux type OS can just
download the binary and run them.&lt;/p>
&lt;p>&lt;em>If and when I figure out how to do the same for macOS and Windows
too, I&amp;rsquo;ll write a separate post for that. If you can help me out with
that, please comment below, or open an issue/PR in the repo linked at
the end.&lt;/em>&lt;/p>
&lt;h2 id="solution">Solution&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#solution">#&lt;/a>&lt;/h2>
&lt;p>The solution is multi-step:&lt;/p>
&lt;ol>
&lt;li>Building static binaries (only for GNU/Linux type OS).&lt;/li>
&lt;li>Optimizing the binary size.&lt;/li>
&lt;li>Doing the above two easily.&lt;/li>
&lt;li>Creating and deploying the builds automatcally (on GitHub).&lt;/li>
&lt;/ol>
&lt;h2 id="1-building-static-binaries">1 Building static binaries&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#1-building-static-binaries">#&lt;/a>&lt;/h2>
&lt;p>My primary OS for coding and development is RHEL 6.8.&lt;/p>
&lt;p>By default, Nim builds dynamically linked binaries using the &lt;em>glibc&lt;/em>
version present on the OS where those binaries are built.&lt;/p>
&lt;p>Living on a stable but &lt;span class="underline">old&lt;/span> OS like RHEL 6.8 (that has &lt;em>glibc 2.12&lt;/em>
by default), I have ended up with the issue many a times&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> where
the deployed binary would be compiled with a newer &lt;em>glibc&lt;/em> and so it
wouldn&amp;rsquo;t run on my system. I would need to eventually compile that
binary myself.&lt;/p>
&lt;p>I don&amp;rsquo;t want to inflict other people with the same problem.&lt;/p>
&lt;p>Inspired by how statically compiled binaries are distributed for tools
built in other languages (&lt;a href="https://github.com/gohugoio/hugo/releases">hugo&lt;/a> [Go], &lt;a href="https://github.com/BurntSushi/ripgrep/releases">ripgrep&lt;/a> [Rust], &lt;a href="https://github.com/jgm/pandoc/releases">pandoc&lt;/a> [Haskell],
etc), I wanted the same for whatever I build with Nim.&lt;/p>
&lt;p>I kept looking around for a &amp;ldquo;single press button&amp;rdquo; flow to do this in
Nim for a while, and after finding nothing, I came up a flow myself,
that I present in this post.&lt;/p>
&lt;p>I picked &lt;strong>musl&lt;/strong> to statically compile my binaries.&lt;/p>
&lt;h3 id="what-is-musl">What is musl?&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#what-is-musl">#&lt;/a>&lt;/h3>
&lt;p>Here&amp;rsquo;s a one-liner description from &lt;a href="https://en.wikipedia.org/wiki/Musl">Wikipedia&lt;/a>:&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>musl&lt;/strong> is a C standard library intended for operating systems based on
the Linux kernel, released under the MIT License.&lt;/p>
&lt;/blockquote>
&lt;p>Check out its &lt;a href="https://www.musl-libc.org/intro.html">introduction&lt;/a> on its official webpage for more details.&lt;/p>
&lt;h3 id="installing-musl">Installing musl&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#installing-musl">#&lt;/a>&lt;/h3>
&lt;p>Installing musl was as simple as &lt;a href="https://www.musl-libc.org/download.html">downloading&lt;/a> its &lt;em>.tar.gz&lt;/em> and running
&lt;code>make &amp;amp;&amp;amp; make install&lt;/code> with the &lt;code>--prefix&lt;/code> configured
appropriately. For the examples that follow, let&amp;rsquo;s say you set the
prefix to &lt;code>/usr/local/musl/&lt;/code>.&lt;/p>
&lt;div class="note">
&lt;p>Do &lt;strong>not&lt;/strong> install musl at the default &lt;em>prefix&lt;/em> location, else it will
override a lot of default header files &amp;ndash; an outcome that you probably
don&amp;rsquo;t want.&lt;/p>
&lt;/div>
&lt;ul>
&lt;li>With the &lt;em>prefix&lt;/em> set as above, the &lt;code>musl-gcc&lt;/code> binary would get
installed in the &lt;code>/usr/local/musl/bin/&lt;/code> directory.&lt;/li>
&lt;li>Add &lt;code>/usr/local/musl/bin/&lt;/code> to your &lt;code>PATH&lt;/code> environment variable.&lt;/li>
&lt;/ul>
&lt;h3 id="static-linking">Static linking&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#static-linking">#&lt;/a>&lt;/h3>
&lt;p>By default, Nim will use the &lt;code>gcc&lt;/code> executable that&amp;rsquo;s found in &lt;code>PATH&lt;/code>
for C compilation. But using the &lt;code>--gcc.exe&lt;/code> switch, we override to
use the &lt;code>musl-gcc&lt;/code> executable. Similarly, we use the &lt;code>--gcc.linkerexe&lt;/code>
switch to use &lt;code>musl-gcc&lt;/code> too, and then the &lt;code>-static&lt;/code> option is passed
to the linker using the &lt;code>--passL&lt;/code> switch.&lt;/p>
&lt;p>With a &lt;code>hello.nim&lt;/code> containing:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nim" data-lang="nim">&lt;span class="line">&lt;span class="cl">&lt;span class="n">echo&lt;/span> &lt;span class="s">&amp;#34;Hello, World!&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>running the below:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Assuming that musl-gcc binary is found in PATH.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">nim --gcc.exe:musl-gcc --gcc.linkerexe:musl-gcc --passL:-static c hello.nim
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>I got a &lt;em>98kB&lt;/em> statically linked &lt;code>hello&lt;/code> binary.&lt;/p>
&lt;h2 id="2-optimizing-the-binary-size">2 Optimizing the binary size&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#2-optimizing-the-binary-size">#&lt;/a>&lt;/h2>
&lt;p>The binary size can be optimized by Nim itself by doing a Release
build (&lt;code>-d:release&lt;/code>) which disables runtime checks used for debugging,
and enables certain optimizations. Adding &lt;code>--opt:size&lt;/code> does further
binary-size optimization.&lt;/p>
&lt;p>So, with the same &lt;code>hello.nim&lt;/code>, running the below:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Assuming that musl-gcc binary is found in PATH.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">nim --gcc.exe:musl-gcc --gcc.linkerexe:musl-gcc --passL:-static -d:release --opt:size c hello.nim
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>shrunk down the binary size to &lt;em>43kB&lt;/em>.&lt;/p>
&lt;p>Upon running external utilities like &lt;a href="https://sourceware.org/binutils/docs/binutils/strip.html">&lt;code>strip&lt;/code> (from &lt;code>binutils&lt;/code>)&lt;/a>&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>
and &lt;a href="https://github.com/upx/upx">&lt;code>upx&lt;/code>&lt;/a>&lt;sup id="fnref:3">&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref">3&lt;/a>&lt;/sup>, the binary size shrunk even further! &amp;ndash; &lt;strong>16kB&lt;/strong>.&lt;/p>
&lt;p>&lt;a id="code-snippet--musl-plus-opt">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Assuming that musl-gcc binary is found in PATH.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">nim --gcc.exe:musl-gcc --gcc.linkerexe:musl-gcc --passL:-static -d:release --opt:size c hello.nim
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">strip -s ./hello
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">upx --best ./hello
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="src-block-caption">
&lt;span class="src-block-number">&lt;a href="#code-snippet--musl-plus-opt">Code Snippet 1&lt;/a>:&lt;/span>
Static linking using &lt;code>musl-gcc&lt;/code> plus binary size optimization
&lt;/div>
&lt;h2 id="3-doing-the-above-two-easily">3 Doing the above two easily&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#3-doing-the-above-two-easily">#&lt;/a>&lt;/h2>
&lt;p>All of that is great, but it wouldn&amp;rsquo;t be fun or elegant to do all the
steps in &lt;a href="#code-snippet--musl-plus-opt">Code Snippet 1&lt;/a> manually (or even in a &lt;em>shell&lt;/em> script).&lt;/p>
&lt;p>Wouldn&amp;rsquo;t it be awesome if I could just run a &lt;code>nim musl hello.nim&lt;/code> command‽&lt;/p>
&lt;div class="verse">
&lt;p>    &amp;mdash; And that&amp;rsquo;s what I do! 😎&lt;br />&lt;/p>
&lt;/div>
&lt;h3 id="nimscript">NimScript&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#nimscript">#&lt;/a>&lt;/h3>
&lt;p>The &amp;ldquo;nim musl&amp;rdquo; command is not available out-of-box, but it is easy to
create one using a &lt;a href="https://nim-lang.org/docs/nims.html">NimScript config file&lt;/a>, which is in the form of a
project-specific &lt;code>config.nims&lt;/code>.&lt;/p>
&lt;div class="note">
&lt;p>Think of NimScripts as much superior &amp;ldquo;bash scripts&amp;rdquo; as they are
written in Nim 😄&lt;/p>
&lt;/div>
&lt;p>From the &lt;a href="https://nim-lang.org/docs/nims.html">NimScript docs&lt;/a>:&lt;/p>
&lt;blockquote>
&lt;p>Strictly speaking, NimScript is the subset of Nim that can be
evaluated by Nim&amp;rsquo;s builtin virtual machine (VM). This VM is used for
Nim&amp;rsquo;s compiletime function evaluation features, but also replaces
Nim&amp;rsquo;s existing configuration system.&lt;/p>
&lt;p>The VM cannot deal with &lt;code>importc&lt;/code>, the FFI is not available, so there
are not many stdlib modules that you can use with Nim&amp;rsquo;s VM. However,
at least the following modules are available:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://nim-lang.org/docs/strutils.html">strutils&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://nim-lang.org/docs/math.html">math&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://nim-lang.org/docs/distros.html">distros&lt;/a>&lt;/li>
&lt;/ul>
&lt;/blockquote>
&lt;p>That list of modules is not comprehensive. I believe that the &lt;a href="https://nim-lang.org/docs/macros.html">macros&lt;/a>
module should be added to that list too (we also happen to need it for
the &lt;code>error&lt;/code> macros in the &lt;code>config.nims&lt;/code> below 😄).&lt;/p>
&lt;p>So, instead of having to resort to the hacky bash scripts, NimScript
allows one to write scripts in the awesome Nim syntax, and it&amp;rsquo;s
platform-agnostic too!&lt;/p>
&lt;p>Also, as you see below, the &lt;em>tasks&lt;/em> in NimScripts basically become
user-defined Nim-subcommands. For example, &amp;ldquo;nim musl&amp;rdquo; command doesn&amp;rsquo;t
exist, but I could make one &lt;em>just like that&lt;/em> by defining a &amp;ldquo;musl&amp;rdquo;
NimScript &lt;em>task&lt;/em>.&lt;/p>
&lt;h3 id="config-dot-nims">&lt;code>config.nims&lt;/code>&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#config-dot-nims">#&lt;/a>&lt;/h3>
&lt;p>Below &lt;code>config.nims&lt;/code> is generic and would work for most Nim
projects. You need to just put it in the directory from where you
compile the Nim code.&lt;/p>
&lt;p>&lt;em>Nim &lt;strong>devel&lt;/strong> (v0.18.1) is needed for the below NimScript to work,
because the &lt;code>findExe&lt;/code> I use in there was not present in Nim v0.18.0.&lt;/em>&lt;/p>
&lt;p>&lt;a id="code-snippet--musl-config-nims">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nim" data-lang="nim">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># config.nims&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="n">macros&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">error&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="n">ospaths&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">splitFile&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">`&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="p">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># -d:musl&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">when&lt;/span> &lt;span class="n">defined&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">musl&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">var&lt;/span> &lt;span class="n">muslGccPath&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kt">string&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">echo&lt;/span> &lt;span class="s">&amp;#34; [-d:musl] Building a static binary using musl ..&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">muslGccPath&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">findExe&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;musl-gcc&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># echo &amp;#34;debug: &amp;#34; &amp;amp; muslGccPath&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">muslGccPath&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;&amp;#39;musl-gcc&amp;#39; binary was not found in PATH.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">switch&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;gcc.exe&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">muslGccPath&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">switch&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;gcc.linkerexe&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">muslGccPath&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">switch&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;passL&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;-static&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">proc &lt;/span>&lt;span class="nf">binOptimize&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">binFile&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kt">string&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">=&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="sd">## Optimize size of the ``binFile`` binary.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">echo&lt;/span> &lt;span class="s">&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">findExe&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;strip&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="s">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">echo&lt;/span> &lt;span class="s">&amp;#34;Running &amp;#39;strip -s&amp;#39; ..&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">exec&lt;/span> &lt;span class="s">&amp;#34;strip -s &amp;#34;&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">binFile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">findExe&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;upx&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="s">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># https://github.com/upx/upx/releases/&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">echo&lt;/span> &lt;span class="s">&amp;#34;Running &amp;#39;upx --best&amp;#39; ..&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">exec&lt;/span> &lt;span class="s">&amp;#34;upx --best &amp;#34;&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">binFile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># nim musl foo.nim&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">task&lt;/span> &lt;span class="n">musl&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;Builds an optimized static binary using musl&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="sd">## Usage: nim musl &amp;lt;.nim file path&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">numParams&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">paramCount&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">numParams&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;The &amp;#39;musl&amp;#39; sub-command needs exactly 1 argument, the Nim file (but &amp;#34;&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">$&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">numParams&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="s">&amp;#34; were detected).&amp;#34;&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s"> Usage Example: nim musl FILE.nim.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">nimFile&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">paramStr&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">numParams&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="sd">## The nim file name *must* be the last.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">(&lt;/span>&lt;span class="n">dirName&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">baseName&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">_&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">splitFile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">nimFile&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">binFile&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">dirName&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">baseName&lt;/span> &lt;span class="c"># Save the binary in the same dir as the nim file&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">nimArgs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;c -d:musl -d:release --opt:size &amp;#34;&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">nimFile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># echo &amp;#34;[debug] nimFile = &amp;#34; &amp;amp; nimFile &amp;amp; &amp;#34;, binFile = &amp;#34; &amp;amp; binFile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># Build binary&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">echo&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">Running &amp;#39;nim &amp;#34;&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">nimArgs&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="s">&amp;#34;&amp;#39; ..&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">selfExec&lt;/span> &lt;span class="n">nimArgs&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># Optimize binary&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">binOptimize&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">binFile&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">echo&lt;/span> &lt;span class="s">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">Created binary: &amp;#34;&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">binFile&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="src-block-caption">
&lt;span class="src-block-number">&lt;a href="#code-snippet--musl-config-nims">Code Snippet 2&lt;/a>:&lt;/span>
&lt;code>config.nims&lt;/code> defining the &lt;b>musl&lt;/b> NimScript &lt;i>task&lt;/i>
&lt;/div>
&lt;p>Here&amp;rsquo;s a quick breakdown of that script:&lt;/p>
&lt;ul>
&lt;li>We first import the modules we would need for the sugar-syntax
&lt;code>error&lt;/code> macro, and for basic file path operations.&lt;/li>
&lt;li>&lt;code>when defined(musl)&lt;/code> block is used to do something extra to the nim
command if user has passed a &lt;code>-d:musl&lt;/code> switch during compilation
(this custom compile-time define switch is used in the &amp;ldquo;musl&amp;rdquo; task).&lt;/li>
&lt;li>The &lt;code>binOptimize&lt;/code> is just a Nim &lt;em>proc&lt;/em> to contain the outside-Nim
binary size optimization commands.&lt;/li>
&lt;li>Finally, the NimScript &lt;a href="https://nim-lang.org/docs/nimscript.html#task.t,untyped,string,untyped">&lt;strong>task&lt;/strong>&lt;/a> &amp;ldquo;musl&amp;rdquo; allows me to define my custom
&amp;ldquo;musl&amp;rdquo; sub-command for &lt;code>nim&lt;/code> so that I can run &lt;code>nim musl FOO.nim&lt;/code>.&lt;/li>
&lt;/ul>
&lt;p>With a directory containing this &lt;code>config.nims&lt;/code> and a &lt;code>FOO.nim&lt;/code>,
running &lt;code>nim musl FOO.nim&lt;/code> will be analogous to manually running the
commands in &lt;a href="#code-snippet--musl-plus-opt">Code Snippet 1&lt;/a>.&lt;/p>
&lt;h2 id="4-creating-and-deploying-the-builds-automatically">4 Creating and deploying the builds automatically&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#4-creating-and-deploying-the-builds-automatically">#&lt;/a>&lt;/h2>
&lt;p>All of that is still great, but ..&lt;/p>
&lt;div class="verse">
&lt;p>    Wouldn&amp;rsquo;t it be awesome if I could do all of that &lt;strong>automatically&lt;/strong> to create static binary releases for my Nim projects‽&lt;br />&lt;/p>
&lt;/div>
&lt;p>And of course, I can do that too! &amp;ndash; At least on GitHub using Travis
CI.&lt;/p>
&lt;p>&lt;em>I would also like to know how to do the same on non-GitHub repos
too. If you know, please comment below.&lt;/em>&lt;/p>
&lt;p>Below is a generic &lt;code>.travis.yml&lt;/code> that works for a repo name &amp;ldquo;FOO&amp;rdquo; and
containing the Nim code in its &amp;ldquo;src/FOO.nim&amp;rdquo; file. Notes on what this
config file does follow after that snippet.&lt;/p>
&lt;p>&lt;a id="code-snippet--musl-travis">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">language&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">c&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">sudo&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">required&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">cache&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">directories&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">nim&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">upx&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">env&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">global&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">PROGNAME=&amp;#34;$(basename ${TRAVIS_BUILD_DIR})&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># /travis/build/kaushalmodi/hello_musl -&amp;gt; hello_musl&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">NIMFILE=&amp;#34;src/${PROGNAME}.nim&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">BINFILE=&amp;#34;src/${PROGNAME}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">ASSETFILE=&amp;#34;${PROGNAME}-${TRAVIS_TAG}.Linux_64bit_musl.tar.xz&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">NIMREPO=&amp;#34;https://github.com/nim-lang/Nim&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">NIMVER=&amp;#34;$(git ls-remote ${NIMREPO} devel | cut -f 1)&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">NIMDIR=&amp;#34;${TRAVIS_BUILD_DIR}/nim/${NIMVER}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">UPXVER=&amp;#34;3.95&amp;#34; &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Change this value when upgrading upx&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">addons&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">apt&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">packages&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># For building MUSL static builds on Linux.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">musl-tools&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">install&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">echo &amp;#34;NIMDIR = ${NIMDIR}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># After building nim, wipe csources to save on cache space.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;{ [ -f ${NIMDIR}/bin/nim ]; } ||
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> ( rm -rf nim;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> mkdir -p nim;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> git clone --single-branch --branch devel --depth=1 ${NIMREPO} ${NIMDIR};
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> cd ${NIMDIR};
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> [ -d csources ] || git clone --depth 1 https://github.com/nim-lang/csources.git;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> cd csources;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> sh build.sh;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> cd ..;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> ./bin/nim c koch;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> ./koch boot -d:release;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> rm -rf csources;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> )&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">export PATH=&amp;#34;${NIMDIR}/bin:${PATH}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">nim -v&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">echo &amp;#34;Installing upx ..&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;{ [ -f upx/${UPXVER}/upx ]; } ||
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> { curl -OL https://github.com/upx/upx/releases/download/v${UPXVER}/upx-${UPXVER}-amd64_linux.tar.xz;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> tar xvf upx-${UPXVER}-amd64_linux.tar.xz;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> mkdir -p upx;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> mv upx-${UPXVER}-amd64_linux upx/${UPXVER};
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> }&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">export PATH=&amp;#34;${TRAVIS_BUILD_DIR}/upx/${UPXVER}/:${PATH}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">upx --version | grep -E &amp;#39;^upx&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># Ensure that you are in repo/build root now.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">cd &amp;#34;${TRAVIS_BUILD_DIR}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">echo &amp;#34;NIMFILE = ${NIMFILE}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">echo &amp;#34;BINFILE = ${BINFILE}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># Compile the static binary using musl.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">nim musl &amp;#34;${NIMFILE}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># See that the binary is not dynamic.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">ldd &amp;#34;${BINFILE}&amp;#34; || true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="c"># Run the binary.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;${BINFILE}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">before_deploy&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">cd &amp;#34;${TRAVIS_BUILD_DIR}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">cp &amp;#34;${BINFILE}&amp;#34; &amp;#34;${PROGNAME}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">tar caf &amp;#34;${ASSETFILE}&amp;#34; &amp;#34;${PROGNAME}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">deploy&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">provider&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">releases&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">api_key&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;${GITHUB_OAUTH_TOKEN}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">file&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;${ASSETFILE}&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">skip_cleanup&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">tags&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="src-block-caption">
&lt;span class="src-block-number">&lt;a href="#code-snippet--musl-travis">Code Snippet 3&lt;/a>:&lt;/span>
GitHub Travis CI config file to generate musl-built Release assets
&lt;/div>
&lt;ul>
&lt;li>I like environment variables to do all the configuration. So I do
that in the &lt;em>env / global&lt;/em> block.&lt;/li>
&lt;li>Caching is enabled for &amp;ldquo;nim&amp;rdquo; and &amp;ldquo;upx&amp;rdquo; directories, which are
created in the &lt;em>install&lt;/em> block.
&lt;ul>
&lt;li>So if the Nim &lt;em>devel&lt;/em> branch hasn&amp;rsquo;t been updated since the last
Travis build, the cached Nim build is used.&lt;/li>
&lt;li>And similar applies to the &lt;code>upx&lt;/code> binary, which relies on the value
of the &lt;code>UPXVER&lt;/code> env variable.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>In the &lt;em>install&lt;/em> block, &lt;code>nim&lt;/code> is built from the Nim &lt;em>devel&lt;/em> branch
HEAD, and &lt;code>upx&lt;/code> binary is downloaded from the Releases section of
its repo.&lt;/li>
&lt;li>The key command is &lt;code>nim musl &amp;quot;${NIMFILE}&amp;quot;&lt;/code> in the &lt;em>script&lt;/em> block,
which uses the &lt;strong>musl&lt;/strong> NimScript task defined in the &lt;a href="#code-snippet--musl-config-nims">&lt;code>config.nims&lt;/code>&lt;/a> in
the same repo.&lt;/li>
&lt;li>In &lt;em>before_deploy&lt;/em>, &lt;code>tar&lt;/code> is used to create an archive of the
generated binary.&lt;/li>
&lt;li>The &lt;em>deploy&lt;/em> section is mainly copy-paste of &lt;a href="https://docs.travis-ci.com/user/deployment/releases/">what&amp;rsquo;s suggested&lt;/a> in the
Travis CI documentation.
&lt;ul>
&lt;li>About the &lt;code>${GITHUB_OAUTH_TOKEN}&lt;/code>, the first step is to get your
GitHub account&amp;rsquo;s &lt;strong>repo&lt;/strong> level token from &lt;a href="https://github.com/settings/tokens">GitHub Tokens settings&lt;/a>.&lt;/li>
&lt;li>The second step is to create a custom environment variable named
&lt;strong>GITHUB_OAUTH_TOKEN&lt;/strong> in that repo&amp;rsquo;s Travis CI settings (ensure
that the variable&amp;rsquo;s value is not made public in the Travis CI&amp;rsquo;s
logs, though they are private by default), and assigning that
token string to that variable.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="how-it-works-in-practice">How it works in practice&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#how-it-works-in-practice">#&lt;/a>&lt;/h2>
&lt;p>Let&amp;rsquo;s assume that the one-time setup for a new repo is already
done. The &lt;code>config.nims&lt;/code> and &lt;code>.travis.yml&lt;/code> are committed and pushed to
the GitHub repo, and the &lt;code>GITHUB_OAUTH_TOKEN&lt;/code> environment variable is
set in the repo&amp;rsquo;s Travis settings.&lt;/p>
&lt;p>Now, to auto-generate the assets for each &lt;em>release&lt;/em>, all I need to do
is:&lt;/p>
&lt;ol>
&lt;li>Commit my changes to the Nim code.&lt;/li>
&lt;li>Tag the commit.&lt;/li>
&lt;li>Push the commit &lt;strong>and&lt;/strong> tag to GitHub.&lt;/li>
&lt;/ol>
&lt;h2 id="repo">Repo&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#repo">#&lt;/a>&lt;/h2>
&lt;p>You can find the latest versions of the above code in my &lt;em>Nim+musl&lt;/em>
template repo &lt;a href="https://github.com/kaushalmodi/hello_musl">&lt;strong>hello_musl&lt;/strong>&lt;/a>.&lt;/p>
&lt;p>You can also try downloading and running (on a GNU/Linux 64-bit OS)
the deployed static binary from &lt;a href="https://github.com/kaushalmodi/hello_musl/releases">its Releases section&lt;/a> and see this
printed in full glory! 😄&lt;/p>
&lt;blockquote>
&lt;p>Hello, World!&lt;/p>
&lt;/blockquote>
&lt;h2 id="references">References&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#references">#&lt;/a>&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://www.reddit.com/r/programming/comments/2wk7q6/static_linking_with_nim/corwtl7/">r/nim &amp;ndash; Static Linking with Nim&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://hookrace.net/blog/nim-binary-size/#using-the-c-standard-library">hookrace.net &amp;ndash; Statically linking against musl libc&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/nim-lang/Nim/wiki/Using-NimScript-for-configuration">Using NimScript for configuration&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://nim-lang.org/docs/nimscript.html">NimScript &amp;ldquo;API&amp;rdquo;&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>&lt;a href="https://github.com/dom96/choosenim/issues/15">One example&lt;/a>&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>The &lt;em>binutils&lt;/em> &lt;strong>strip&lt;/strong> utility is used to remove complete
symbol tables and other debug info that are not needed for running the
executable.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:3">
&lt;p>From &lt;a href="https://github.com/upx/upx/blob/master/README">its docs&lt;/a>, &lt;strong>UPX&lt;/strong> is an advanced executable file
compressor. UPX will typically reduce the file size of programs and
DLLs by around 50%-70%, thus reducing disk space, network load times,
download times and other distribution and storage costs.&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description><author>Kaushal.Modi@fakeEmailToMakeValidatorHappy.com (Kaushal Modi)</author><category domain="https://scripter.co/categories/programming">programming</category><category domain="https://scripter.co/tags/nim">nim</category><category domain="https://scripter.co/tags/static">static</category><category domain="https://scripter.co/tags/binary">binary</category><category domain="https://scripter.co/tags/musl">musl</category><category domain="https://scripter.co/tags/gnu-linux">gnu-linux</category><category domain="https://scripter.co/tags/github">github</category><category domain="https://scripter.co/tags/travis-ci">travis-ci</category><guid>https://scripter.co/nim-deploying-static-binaries/</guid><pubDate>Mon, 24 Sep 2018 01:47:00 -0400</pubDate></item></channel></rss>