<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>static on
A Scripter's Notes</title><link>https://scripter.co/tags/static/</link><description>Recent content in static
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/static/index.xml" rel="self" type="application/rss+xml"/><item><title>Generics (not exactly) in SystemVerilog</title><link>https://scripter.co/generics-not-exactly-in-systemverilog/</link><description>&lt;blockquote>Using &lt;em>parameterized classes&lt;/em> with &lt;em>static functions&lt;/em> to make up for
the lack of generics in SystemVerilog.&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="#a-real-generics-example">A real &lt;em>Generics&lt;/em> example&lt;/a>&lt;/li>
&lt;li>&lt;a href="#poor-man-s-generics-in-systemverilog">&lt;em>Poor man&amp;rsquo;s Generics&lt;/em> in SystemVerilog&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#parameterized-classes">Parameterized Classes&lt;/a>&lt;/li>
&lt;li>&lt;a href="#static-methods">Static methods&lt;/a>&lt;/li>
&lt;li>&lt;a href="#should-compile-with-all-types-t">Should compile with all types &lt;em>T&lt;/em>&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#final-code">Final Code&lt;/a>&lt;/li>
&lt;li>&lt;a href="#cluelib">Cluelib&lt;/a>&lt;/li>
&lt;/ul>
&lt;/div>
&lt;!--endtoc-->
&lt;p>Many modern languages like &lt;a href="https://nim-lang.org">Nim&lt;/a> allow defining &lt;em>Generic&lt;/em> functions
types, etc that can work for any type. See Nim Manual &lt;a href="#citeproc_bib_item_2">2022&lt;/a> &lt;em>Generics&lt;/em>.&lt;/p>
&lt;p>This post demonstrates how you can make generics &lt;em>kind of&lt;/em> (if you
really squint your eyes, you can see it 😄) work with
SystemVerilog.&lt;/p>
&lt;h2 id="a-real-generics-example">A real &lt;em>Generics&lt;/em> example&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#a-real-generics-example">#&lt;/a>&lt;/h2>
&lt;p>The focus of this post is not how to write generics in Nim, but here&amp;rsquo;s
a quick summary:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="#org-coderef--51b0fc-1">Line 1&lt;/a> overloads the &lt;code>+&lt;/code> operator for any type &lt;code>T&lt;/code>.&lt;/li>
&lt;li>&lt;a href="#org-coderef--51b0fc-2">Line 2&lt;/a> is a &lt;strong>compile time&lt;/strong> check (using &lt;code>when&lt;/code>) to
see if &lt;code>T&lt;/code> is a &lt;em>string&lt;/em>, and then concatenates &lt;em>a&lt;/em> and &lt;em>b&lt;/em> inputs
using the &lt;code>&amp;amp;&lt;/code> &lt;em>string concat&lt;/em> operator.&lt;/li>
&lt;li>For &lt;a href="#org-coderef--51b0fc-4">other types&lt;/a>, it does the expected &amp;ldquo;a + b&amp;rdquo;.&lt;/li>
&lt;/ul>
&lt;!--listend-->
&lt;p>&lt;a id="code-snippet--code-generics-nim">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt" id="org-coderef--51b0fc-1">&lt;a style="outline: none; text-decoration:none; color:inherit" href="#org-coderef--51b0fc-1">1&lt;/a>
&lt;/span>&lt;span class="lnt" id="org-coderef--51b0fc-2">&lt;a style="outline: none; text-decoration:none; color:inherit" href="#org-coderef--51b0fc-2">2&lt;/a>
&lt;/span>&lt;span class="lnt" id="org-coderef--51b0fc-3">&lt;a style="outline: none; text-decoration:none; color:inherit" href="#org-coderef--51b0fc-3">3&lt;/a>
&lt;/span>&lt;span class="lnt" id="org-coderef--51b0fc-4">&lt;a style="outline: none; text-decoration:none; color:inherit" href="#org-coderef--51b0fc-4">4&lt;/a>
&lt;/span>&lt;span class="lnt" id="org-coderef--51b0fc-5">&lt;a style="outline: none; text-decoration:none; color:inherit" href="#org-coderef--51b0fc-5">5&lt;/a>
&lt;/span>&lt;span class="lnt" id="org-coderef--51b0fc-6">&lt;a style="outline: none; text-decoration:none; color:inherit" href="#org-coderef--51b0fc-6">6&lt;/a>
&lt;/span>&lt;span class="lnt" id="org-coderef--51b0fc-7">&lt;a style="outline: none; text-decoration:none; color:inherit" href="#org-coderef--51b0fc-7">7&lt;/a>
&lt;/span>&lt;span class="lnt" id="org-coderef--51b0fc-8">&lt;a style="outline: none; text-decoration:none; color:inherit" href="#org-coderef--51b0fc-8">8&lt;/a>
&lt;/span>&lt;span class="lnt" id="org-coderef--51b0fc-9">&lt;a style="outline: none; text-decoration:none; color:inherit" href="#org-coderef--51b0fc-9">9&lt;/a>
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&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="k">proc &lt;/span>&lt;span class="nf">`+`&lt;/span>&lt;span class="o">[&lt;/span>&lt;span class="n">T&lt;/span>&lt;span class="o">]&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">T&lt;/span>&lt;span class="p">):&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="o">=&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">T&lt;/span> &lt;span class="ow">is&lt;/span> &lt;span class="kt">string&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">b&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">else&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&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="mi">1&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">echo&lt;/span> &lt;span class="mf">100.1&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mf">100.2&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;x&amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="s">&amp;#34;y&amp;#34;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="s">&amp;#34;z&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;div class="src-block-caption">
&lt;span class="src-block-number">&lt;a href="#code-snippet--code-generics-nim">Code Snippet 1&lt;/a>:&lt;/span>
Example of generics in Nim
&lt;/div>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">200.3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">xyz
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We will now see how to write something like this in SystemVerilog.&lt;/p>
&lt;h2 id="poor-man-s-generics-in-systemverilog">&lt;em>Poor man&amp;rsquo;s Generics&lt;/em> in SystemVerilog&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#poor-man-s-generics-in-systemverilog">#&lt;/a>&lt;/h2>
&lt;p>SystemVerilog is a strongly typed compiled language. So you need to
define the types for &lt;em>function&lt;/em> and &lt;em>task&lt;/em> arguments.&lt;/p>
&lt;p>So if you need an &lt;em>add&lt;/em> function for integers, you would do:&lt;/p>
&lt;p>&lt;a id="code-snippet--sv-add-int">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-systemverilog" data-lang="systemverilog">&lt;span class="line">&lt;span class="cl">&lt;span class="k">function&lt;/span> &lt;span class="k">int&lt;/span> &lt;span class="n">add_int&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">input&lt;/span> &lt;span class="k">int&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">endfunction&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--sv-add-int">Code Snippet 2&lt;/a>:&lt;/span>
&lt;code>add_int&lt;/code> for adding integers
&lt;/div>
&lt;p>If you need an &lt;em>add&lt;/em> function for real numbers, you would do:&lt;/p>
&lt;p>&lt;a id="code-snippet--sv-add-real">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-systemverilog" data-lang="systemverilog">&lt;span class="line">&lt;span class="cl">&lt;span class="k">function&lt;/span> &lt;span class="k">real&lt;/span> &lt;span class="n">add_real&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">input&lt;/span> &lt;span class="k">real&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">endfunction&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--sv-add-real">Code Snippet 3&lt;/a>:&lt;/span>
&lt;code>add_real&lt;/code> for adding reals (doubles)
&lt;/div>
&lt;p>I am using the &lt;strong>add&lt;/strong> functions here only to demonstrate the
concept. In real world code, you would come across many cases where
you would want to avoid such function redefinitions. Some examples
are: dealing with objects of different classes, or queues with
elements of different types (e.g. queues of &lt;em>ints&lt;/em>, queues of
&lt;em>strings&lt;/em>), or dynamic arrays of different types, etc.&lt;/p>
&lt;h3 id="parameterized-classes">Parameterized Classes&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#parameterized-classes">#&lt;/a>&lt;/h3>
&lt;p>In &lt;a href="#code-snippet--sv-add-int">&lt;code>add_int&lt;/code>&lt;/a>, we see that the type &lt;code>int&lt;/code> has to be specified in the
function signature. That &lt;code>int&lt;/code> can be replaced by a &lt;em>parameter&lt;/em>
representing a &lt;em>type&lt;/em> only if that function is defined inside a
&lt;em>parameterized class&lt;/em> (See &lt;span style="color:grey;">§&lt;/span> &lt;strong>Parameterized classes&lt;/strong> &lt;a href="#citeproc_bib_item_1">2018, sec. 8.25&lt;/a>).&lt;/p>
&lt;p>So it would look like this:&lt;/p>
&lt;p>&lt;a id="code-snippet--parameterized-class1-sv">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-systemverilog" data-lang="systemverilog">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="n">math&lt;/span> &lt;span class="p">#(&lt;/span>&lt;span class="k">parameter&lt;/span> &lt;span class="k">type&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">int&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">function&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="n">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">input&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">endfunction&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">endclass&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--parameterized-class1-sv">Code Snippet 4&lt;/a>:&lt;/span>
Parameterized class and method
&lt;/div>
&lt;p>This code, though has a problem &amp;mdash; In order to call that function, we
would first need to construct an object of that class for each type
&lt;em>T&lt;/em> we plan to use.&lt;/p>
&lt;h3 id="static-methods">Static methods&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#static-methods">#&lt;/a>&lt;/h3>
&lt;p>The solution to that is to declare the methods/functions in the class
as &lt;strong>static&lt;/strong>. That way, that method can be called directly without
constructing the object first. See &lt;span style="color:grey;">§&lt;/span> &lt;strong>Static methods&lt;/strong> &lt;a href="#citeproc_bib_item_1">2018, sec. 8.10&lt;/a>.&lt;/p>
&lt;p>And because we don&amp;rsquo;t need to construct an object of that class, and
don&amp;rsquo;t want anyone else to unnecessary construct it, we declare the
class as &lt;em>virtual&lt;/em>.&lt;/p>
&lt;p>&lt;a id="code-snippet--parameterized-class2-sv">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-systemverilog" data-lang="systemverilog">&lt;span class="line hl">&lt;span class="cl">&lt;span class="k">virtual&lt;/span> &lt;span class="k">class&lt;/span> &lt;span class="n">math&lt;/span> &lt;span class="p">#(&lt;/span>&lt;span class="k">parameter&lt;/span> &lt;span class="k">type&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">int&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> &lt;span class="k">static&lt;/span> &lt;span class="k">function&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="n">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">input&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">endfunction&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">endclass&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--parameterized-class2-sv">Code Snippet 5&lt;/a>:&lt;/span>
Virtual parameterized class and &lt;b>static&lt;/b> method
&lt;/div>
&lt;p>Now we can call &lt;code class="code-inline language-systemverilog">&lt;span class="n">math&lt;/span> &lt;span class="p">#(&lt;/span>&lt;span class="k">int&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mh">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mh">2&lt;/span>&lt;span class="p">)&lt;/span>&lt;/code> and &lt;code class="code-inline language-systemverilog">&lt;span class="n">math&lt;/span> &lt;span class="p">#(&lt;/span>&lt;span class="k">real&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mf">100.1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">100.2&lt;/span>&lt;span class="p">)&lt;/span>&lt;/code> and get the expected results.&lt;/p>
&lt;h3 id="should-compile-with-all-types-t">Should compile with all types &lt;em>T&lt;/em>&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#should-compile-with-all-types-t">#&lt;/a>&lt;/h3>
&lt;p>But.. what if the type &lt;em>T&lt;/em> is &lt;em>string&lt;/em> ..&lt;/p>
&lt;p>&lt;code>$typename&lt;/code> system function (See &lt;span style="color:grey;">§&lt;/span> &lt;strong>Type name function&lt;/strong> &lt;a href="#citeproc_bib_item_1">2018, sec. 20.6.1&lt;/a>) comes to our help here. This function takes in a
variable identifier and returns a string name of that variable&amp;rsquo;s
type. So if a variable &lt;em>x&lt;/em> is a &lt;em>string&lt;/em>, &lt;code>$typename(x)&lt;/code> will return
&lt;code>&amp;quot;string&amp;quot;&lt;/code>.&lt;/p>
&lt;p>So, we can define the &lt;code>add&lt;/code> method like this, right?&lt;/p>
&lt;p>&lt;a id="code-snippet--parameterized-class3-sv">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-systemverilog" data-lang="systemverilog">&lt;span class="line">&lt;span class="cl">&lt;span class="k">virtual&lt;/span> &lt;span class="k">class&lt;/span> &lt;span class="n">math&lt;/span> &lt;span class="p">#(&lt;/span>&lt;span class="k">parameter&lt;/span> &lt;span class="k">type&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">int&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">static&lt;/span> &lt;span class="k">function&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="n">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">input&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">$typename&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s">&amp;#34;string&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">else&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">endfunction&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">endclass&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--parameterized-class3-sv">Code Snippet 6&lt;/a>:&lt;/span>
&lt;code>add&lt;/code> method with a condition for &lt;i>string&lt;/i> type &amp;#x2013; Won't compile!
&lt;/div>
&lt;p>❌ &lt;strong>Wrong&lt;/strong> ❌&lt;/p>
&lt;div class="note">
&lt;p>Even if you have the code execute conditionally based on the
&lt;code>$typename&lt;/code>, note that the &lt;code class="code-inline language-systemverilog">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">$typename&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s">&amp;#34;string&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>&lt;/code> check is happening at run time, and so the
&lt;strong>entire code&lt;/strong> needs to compile for any type &lt;em>T&lt;/em> that&amp;rsquo;s planned to be
used.&lt;/p>
&lt;/div>
&lt;p>In the above example, because the &lt;code>{a, b}&lt;/code> concatenation isn&amp;rsquo;t meant
for types like &lt;em>ints&lt;/em> and &lt;em>reals&lt;/em>, it will fail compilation.
&lt;span class="sidenote-number">&lt;small class="sidenote">
That&amp;rsquo;s the reason for the &amp;ldquo;(not exactly)&amp;rdquo; in this post&amp;rsquo;s title 😄
&lt;/small>&lt;/span>&lt;/p>
&lt;p>In order to make &lt;code>add&lt;/code> work with strings as well, we need this messy
&lt;em>cast&lt;/em> when the type name is &lt;em>&amp;ldquo;string&amp;rdquo;&lt;/em> : &lt;code class="code-inline language-systemverilog">&lt;span class="n">$cast&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ret_val&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">$sformatf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;%s%s&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">));&lt;/span>&lt;/code>. It&amp;rsquo;s basically
telling the compiler: &amp;ldquo;Trust me, I know what I am doing.. I will be
executing this code only when the &lt;em>ret_val&lt;/em> is a string.&amp;rdquo;&lt;/p>
&lt;h2 id="final-code">Final Code&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#final-code">#&lt;/a>&lt;/h2>
&lt;p>Finally, here&amp;rsquo;s the entire code with the &lt;em>generic&lt;/em> &lt;code>add&lt;/code> method and
some test code.&lt;/p>
&lt;p>&lt;a id="code-snippet--math-sv">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-systemverilog" data-lang="systemverilog">&lt;span class="line">&lt;span class="cl">&lt;span class="k">virtual&lt;/span> &lt;span class="k">class&lt;/span> &lt;span class="n">math&lt;/span> &lt;span class="p">#(&lt;/span>&lt;span class="k">parameter&lt;/span> &lt;span class="k">type&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">int&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">static&lt;/span> &lt;span class="k">function&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="n">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">input&lt;/span> &lt;span class="n">T&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&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="p">(&lt;/span>&lt;span class="n">$typename&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s">&amp;#34;string&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">begin&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">T&lt;/span> &lt;span class="n">ret_val&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">$cast&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ret_val&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">$sformatf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;%s%s&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">ret_val&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">end&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="k">begin&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">end&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">endfunction&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">add&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">endclass&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">math&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">module&lt;/span> &lt;span class="n">test&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="nb">$display&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;1 + 2 = %p&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">math&lt;/span> &lt;span class="p">#(&lt;/span>&lt;span class="k">int&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mh">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mh">2&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="c1">// 3
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nb">$display&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;1.1 + 2.2 = %p&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">math&lt;/span> &lt;span class="p">#(&lt;/span>&lt;span class="k">real&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mf">1.1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mf">2.2&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="c1">// 3.3
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nb">$display&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;1 + 1 = %p&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">math&lt;/span> &lt;span class="p">#(&lt;/span>&lt;span class="k">bit&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mh">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mh">1&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="c1">// 0
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nb">$display&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;abc + def = %p&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">math&lt;/span> &lt;span class="p">#(&lt;/span>&lt;span class="k">string&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;abc&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;def&amp;#34;&lt;/span>&lt;span class="p">));&lt;/span> &lt;span class="c1">// &amp;#34;abcdef&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">$finish&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">end&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">endmodule&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">test&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--math-sv">Code Snippet 7&lt;/a>:&lt;/span>
Parameterized class &lt;code>math&lt;/code> with &lt;i>static&lt;/i> function &lt;code>add&lt;/code>
&lt;/div>
&lt;h2 id="cluelib">Cluelib&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#cluelib">#&lt;/a>&lt;/h2>
&lt;p>If you liked how these &lt;em>&amp;ldquo;generics&amp;rdquo;&lt;/em> work in SystemVerilog and how the
&lt;code class="code-inline language-systemverilog">&lt;span class="n">math&lt;/span> &lt;span class="p">#(&lt;/span>&lt;span class="k">int&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mh">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mh">2&lt;/span>&lt;span class="p">));&lt;/span>&lt;/code> syntax
looks, check out the &lt;a href="https://github.com/cluelogic/cluelib">&lt;strong>cluelib&lt;/strong>&lt;/a> library by &lt;em>cluelogic.com&lt;/em>. It is an
amazing SystemVerilog library with a big collection of &lt;em>&amp;ldquo;generic&amp;rdquo;&lt;/em>
functions like above for handling strings, queues and dynamic arrays,
and a lot more. You can take a peek at its API &lt;a href="http://cluelogic.com/tools/cluelib/api/framed_html/index.html">here&lt;/a>.&lt;/p>
&lt;h2 id="references">References&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#references">#&lt;/a>&lt;/h2>
&lt;div class="csl-bib-body">
&lt;div class="csl-entry">&lt;a id="citeproc_bib_item_1">&lt;/a>IEEE Standard for SystemVerilog–Unified Hardware Design, Specification, and Verification Language. (2018). &lt;i>IEEE Std 1800-2017 (Revision of IEEE Std 1800-2012)&lt;/i>, 1–1315. &lt;a href="https://doi.org/10.1109/IEEESTD.2018.8299595">https://doi.org/10.1109/IEEESTD.2018.8299595&lt;/a>&lt;/div>
&lt;div class="csl-entry">&lt;a id="citeproc_bib_item_2">&lt;/a>Nim contributors. (2022). Nim Manual [Website]. In &lt;i>Nim&lt;/i>. &lt;a href="https://nim-lang.org/docs/manual.html">https://nim-lang.org/docs/manual.html&lt;/a>&lt;/div>
&lt;/div></description><author>Kaushal.Modi@fakeEmailToMakeValidatorHappy.com (Kaushal Modi)</author><category domain="https://scripter.co/categories/systemverilog">systemverilog</category><category domain="https://scripter.co/tags/parameterized-classes">parameterized-classes</category><category domain="https://scripter.co/tags/typename">typename</category><category domain="https://scripter.co/tags/static">static</category><category domain="https://scripter.co/tags/methods">methods</category><category domain="https://scripter.co/tags/generics">generics</category><category domain="https://scripter.co/tags/100daystooffload">100DaysToOffload</category><guid>https://scripter.co/generics-not-exactly-in-systemverilog/</guid><pubDate>Fri, 11 Feb 2022 01:48:00 -0500</pubDate></item><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>