<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<title>Annapurna</title>
	<subtitle>IT Thoughts</subtitle>
	<link rel="self" type="application/atom+xml" href="https://blog.annapurna.cc/feed.xml"/>
  <link rel="alternate" type="text/html" href="https://blog.annapurna.cc"/>
  
	<updated>2025-11-04T00:00:00+00:00</updated>
	
	<id>https://blog.annapurna.cc/feed.xml</id>
	<entry xml:lang="en">
		<title>Autark: Rethinking build systems – Integrate, Don’t Outsource</title>
		<published>2025-11-04T00:00:00+00:00</published>
		<updated>2025-11-04T00:00:00+00:00</updated>
		<link rel="alternate" type="text/html" href="https://blog.annapurna.cc/posts/autark-intro/"/>
		<id>https://blog.annapurna.cc/posts/autark-intro/</id>
    
		<content type="html" xml:base="https://blog.annapurna.cc/posts/autark-intro/">&lt;p&gt;I enjoy programming in C. Over the years, I’ve built a couple dozen projects of varying complexity – from small toy
programs to game engines, key-value storage systems, and even algorithmic trading platforms. Each time I start a new
project, before I can begin the actual work, I have to go through a somewhat tedious phase: setting up the build system
and defining dependencies on other projects and libraries.&lt;/p&gt;
&lt;h2 id=&quot;cmake&quot;&gt;CMake&lt;a class=&quot;zola-anchor&quot; href=&quot;#cmake&quot; aria-label=&quot;Anchor link for: cmake&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Until recently, I used CMake. For each new project, this usually meant copying the build rules from one of my previous
projects and adapting them to the current needs. While that approach made it easier to get started, the process was
always painful. The imperative, BASIC-like scripting logic of CMake is too cumbersome for simple reuse or quick
adaptation to changing build requirements.&lt;/p&gt;
&lt;p&gt;Another inconvenience is that CMake requires you to constantly keep up with new features and changes in its vast
ecosystem. If you ignore them for too long, one day your project simply stops building with the current stable CMake
version – and you’ll need to enable some CMake policy to restore compatibility. Even if we ignore the scripting
complexity, there’s still the long-term issue: eventually, after the project is released, it will stop building exactly
as described in its own documentation.&lt;/p&gt;
&lt;p&gt;As we all know, CMake doesn’t actually build your project –  it’s a transpiler that converts CMakeLists.txt scripts into
rules for lower-level tools like Make or Ninja. In practice, that means you depend on two separate tools (and their
compatible versions) just to get a working build, not to mention the debugging headaches in complex setups.&lt;/p&gt;
&lt;p&gt;I won’t go into a detailed analysis of CMake’s pros and cons here – it’s a popular system, and it earned that popularity
for a reason. It’s far from perfect, but as my colleagues like to say, “Bad. But there’s nothing better yet.” Personally,
I decided to pursue a different concept for a build system – one that aligns more closely with my own values:
simplicity, stability, and lightness.&lt;/p&gt;
&lt;h2 id=&quot;make&quot;&gt;Make&lt;a class=&quot;zola-anchor&quot; href=&quot;#make&quot; aria-label=&quot;Anchor link for: make&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;So why not just use plain Make or even autotools? Take a look at the folks from a bit religious &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://suckless.org&quot;&gt;suckless.org&lt;/a&gt; community.
They write great software using pure POSIX mode Make. Though, amusingly, they forgot to include Make itself in their list of
software that rocks. I have my own reasons for not being too fond of Make, and I’m pretty sure I’m not alone. My
short-term memory isn’t great – if I don’t write Make scripts every day, I can never remember all the quirky mechanics
and syntax variations. Consider constructs like:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;make&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;.d&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; %&lt;/span&gt;&lt;span&gt;.c&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        @set -e; rm -f &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$@&lt;/span&gt;&lt;span&gt;; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;         $(&lt;/span&gt;&lt;span&gt;CC&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;)&lt;/span&gt;&lt;span&gt; -M &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;$(&lt;/span&gt;&lt;span&gt;CPPFLAGS&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; $&amp;lt;&lt;/span&gt;&lt;span&gt; &amp;gt; &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$@&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$$&lt;/span&gt;&lt;span&gt;; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;         sed&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; &amp;#39;s,\(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$*&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;\)\.o[&lt;/span&gt;&lt;span&gt; :&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;*&lt;/span&gt;&lt;span&gt;,\1.o &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$@&lt;/span&gt;&lt;span&gt; : ,g&amp;#39; &amp;lt; &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$@&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$$&lt;/span&gt;&lt;span&gt; &amp;gt; &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$@&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         rm -f &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$@&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$$&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;make&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;test&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    @for exec in &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;$(&lt;/span&gt;&lt;span&gt;EXECS&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;)&lt;/span&gt;&lt;span&gt;; do \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        echo &amp;quot;Running &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$$&lt;/span&gt;&lt;span&gt;exec...&amp;quot;; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;        $(&lt;/span&gt;&lt;span&gt;MEM_CHECKER&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;)&lt;/span&gt;&lt;span&gt; ./&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$$&lt;/span&gt;&lt;span&gt;exec; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    done&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And let’s not forget the &lt;em&gt;Automatic Variables&lt;/em&gt; list from section &lt;code&gt;10.5.3&lt;/code&gt; of the GNU Make manual – the one you’re
apparently not allowed to ignore if you dare to use Make. Please don’t tell me “it’s all simple”. I know there are people
for whom it is, but as I said earlier, for me and many colleagues with short memory spans, it’s not.&lt;/p&gt;
&lt;p&gt;There’s another point: I believe that when a professional uses a tool, they should understand and be able to use all of
its features. But the more complex the tool, the harder it is to claim you truly master it. (That’s why I’ll never call
myself a C++ expert.)&lt;/p&gt;
&lt;p&gt;In practice, we all end up sticking to a small set of build recipes that feel comfortable and just copy-paste them
between projects. Make, however, is too low-level to express build logic easily and gracefully, especially when it needs
to account for things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Changes in a Makefile should trigger a rebuild of all dependent targets.&lt;/li&gt;
&lt;li&gt;Changes in environment variables like &lt;code&gt;$CC&lt;/code&gt; or &lt;code&gt;$CFLAGS&lt;/code&gt; should cause dependent modules to rebuild.&lt;/li&gt;
&lt;li&gt;Modifications in system library headers should trigger rebuilds of the affected parts of the project.&lt;/li&gt;
&lt;li&gt;There are several flavors of Make: POSIX Make, GNU Make, BSD Make and you must decide what functionality to sacrifice
in order to stay compatible across environments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And that’s just the beginning. Sure, you can make Make handle all of this, but at what cost? I’ve yet to see a handmade
Make project that does it all correctly.&lt;/p&gt;
&lt;h2 id=&quot;autark&quot;&gt;Autark&lt;a class=&quot;zola-anchor&quot; href=&quot;#autark&quot; aria-label=&quot;Anchor link for: autark&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Realizing that it’s impossible to create a &lt;em&gt;perfect&lt;/em&gt; build system, I focused on defining a few key characteristics
I wanted to see in the final product even if that meant sacrificing some functionality elsewhere.&lt;/p&gt;
&lt;p&gt;Here’s what I needed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A simple, memorable syntax for build scripts.&lt;/li&gt;
&lt;li&gt;Deeper dependency tracking compared to Make (see above).&lt;/li&gt;
&lt;li&gt;Portability – ideally, the project shouldn’t require any preinstalled build system. It should be able to build itself
using only the most basic tools, like a &lt;code&gt;C&lt;/code&gt; compiler and a system shell.&lt;/li&gt;
&lt;li&gt;The ability to verify and adapt the project before building (a &lt;em&gt;configure&lt;/em&gt; phase).&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;dependencies&quot;&gt;Dependencies&lt;a class=&quot;zola-anchor&quot; href=&quot;#dependencies&quot; aria-label=&quot;Anchor link for: dependencies&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;To get started, I needed some inspiration and I found it in the &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://cr.yp.to/redo.html&quot;&gt;Redo build tool&lt;/a&gt;.
There are several Redo implementations available on GitHub, though the concept never became particularly
popular. I suspect that’s because it feels rather academic: a talented mathematician proposed a simple, elegant idea,
but for it to work in real-world projects, it needed to be wrapped in something more developer-friendly.&lt;/p&gt;
&lt;p&gt;While experimenting with Redo, I discovered that building a project often required a large set of shell scripts
scattered across many directories. In many of them, I had to reimplement utility functions that really belonged inside
the build system itself. However, I did take away one important concept: the idea of managing dependencies through individual files and
developed it further.&lt;/p&gt;
&lt;h3 id=&quot;portability&quot;&gt;Portability&lt;a class=&quot;zola-anchor&quot; href=&quot;#portability&quot; aria-label=&quot;Anchor link for: portability&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;To achieve true portability, I took a fairly radical approach: during the first build, the project compiles its own
build system from &lt;code&gt;C&lt;/code&gt;, and from then on, that build system compiles the project. The build system is a small C program
embedded directly inside a &lt;code&gt;build.sh&lt;/code&gt; script, which acts as its entry point. It only requires a C99-compatible compiler
(flags compatible with clang or gcc). The entire system is about 10K lines of code, compiles in under a second, and
caches its build artifacts. This way, everything related to the build process is already part of the project itself – no
need to worry about toolchain versions or environment differences across machines.&lt;/p&gt;
&lt;h3 id=&quot;script-syntax&quot;&gt;Script Syntax&lt;a class=&quot;zola-anchor&quot; href=&quot;#script-syntax&quot; aria-label=&quot;Anchor link for: script-syntax&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;Here I had to deal with a rather contradictory set of requirements. On one hand, I wanted a powerful declarative syntax;
on the other, it needed to be simple, and the parser had to remain minimal to allow fast compilation of the build system
during a cold start. I eventually settled on the following syntax:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RULE:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  rule_name { RULE | LITERAL ... }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LITERAL:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  word | &amp;#39;single quoted words&amp;#39; | &amp;quot;double quoted words&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;A script consists of a set of rules and literals.&lt;/li&gt;
&lt;li&gt;Rules and literals are separated by whitespaces.&lt;/li&gt;
&lt;li&gt;Every rule has a body enclosed in curly braces &lt;code&gt;{}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Rules form lists, similar to syntactic structures in Scheme or Lisp. The AST of a script can change dynamically
depending on conditions. I was amused to find that a trace of Scheme somehow made its way into this project without me
realizing it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A formal syntax description in PEG format can be found here:
&lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://github.com/Softmotions/autark/blob/master/scriptx.leg&quot;&gt;https://github.com/Softmotions/autark/blob/master/scriptx.leg&lt;/a&gt;.
Special thanks to &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://piumarta.com/cv/&quot;&gt;Ian Piumarta&lt;/a&gt; for his excellent &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://piumarta.com/software/peg/&quot;&gt;PEG parser generator&lt;/a&gt;
which I’ve used in many of my projects.&lt;/p&gt;
&lt;p&gt;Here’s a build script example from the &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://github.com/Softmotions/autark-sample-project&quot;&gt;demo project&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;Autark&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;cc&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  hello.c &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;  $&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;CFLAGS&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;  $&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;CC&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  consumes&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    # hello.h is a product of the `configure` rule,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    # so we declare our dependency on it here.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hello.h&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;# Builds the static library libhello.a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;run&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  exec&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; $&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;AR&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; rcs libhello.a &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;CC_OBJS&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  consumes&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;    $&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;CC_OBJS&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  produces&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;    $&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;LIBHELLO_A&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;current-status-of-autark&quot;&gt;Current Status of Autark&lt;a class=&quot;zola-anchor&quot; href=&quot;#current-status-of-autark&quot; aria-label=&quot;Anchor link for: current-status-of-autark&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The build system &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://autark.dev&quot;&gt;autark.dev&lt;/a&gt;  was implemented some time ago, and since then I’ve migrated most of
my C/C++ projects to it, fixing issues and polishing things along the way.&lt;/p&gt;
&lt;p&gt;Here are a few open-source projects that have already been migrated:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://github.com/Softmotions/iwnet&quot;&gt;github.com/Softmotions/iwnet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://github.com/Softmotions/iowow&quot;&gt;github.com/Softmotions/iowow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And even a fork of the third-party project &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://github.com/Softmotions/protobuf-c&quot;&gt;protobuf-c&lt;/a&gt;
where I &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://github.com/Softmotions/protobuf-c/blob/master/t/Issues.autark&quot;&gt;used macros&lt;/a&gt;
to build and run test cases.&lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Autark started as an experiment – a personal attempt to make the build process less painful and more predictable. Over
time, it grew into something I now use daily across nearly all my C projects. It’s not meant to compete with CMake or
reinvent the industry standard. Instead, it tries to do one thing well: give developers a lightweight, self-contained,
and reliable way to describe how their projects are built.&lt;/p&gt;
&lt;p&gt;I don’t claim that Autark is the best build system it’s simply the one that aligns with my values: simplicity,
transparency, and long-term stability. If you’ve ever struggled with build scripts that felt like they were fighting
you, maybe you’ll find something familiar in this approach.&lt;/p&gt;
&lt;p&gt;The project is still evolving, and feedback is very welcome. You can learn more or try it yourself at
&lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://autark.dev&quot;&gt;autark.dev&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Where are engineers?</title>
		<published>2020-06-15T00:00:00+00:00</published>
		<updated>2020-06-15T00:00:00+00:00</updated>
		<link rel="alternate" type="text/html" href="https://blog.annapurna.cc/posts/where-are-engineers/"/>
		<id>https://blog.annapurna.cc/posts/where-are-engineers/</id>
    
		<content type="html" xml:base="https://blog.annapurna.cc/posts/where-are-engineers/">&lt;p&gt;&lt;img src=&quot;/assets/20200615/one.png&quot; alt=&quot;one&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;extremes-and-excesses&quot;&gt;Extremes and excesses&lt;a class=&quot;zola-anchor&quot; href=&quot;#extremes-and-excesses&quot; aria-label=&quot;Anchor link for: extremes-and-excesses&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;A great number of paradoxes and contradictions are born in businesses when trying to answer this question. Decisions
become extremes: professional criteria are lowered and, primarily business tasks are solved. Another extreme is
increased requirements taking no account of the market and often appearing because of paranoia and
narrowmindedness. This leads to the destruction of the basic idea of a company and many of the decisions become
excessive. Concepts become vague: product quality and value, practicability to use technologies and developer’s
level. For example, the product was being produced but the main client had a lot of own needs, which led to
a technological and functional adjustment. Many big players dream of doing their products but business hampers them.&lt;/p&gt;
&lt;p&gt;But let excuses be excuses. There are good projects as well as excellent professionals!
&lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://softmotions.com&quot;&gt;Softmotions&lt;/a&gt; are unknown but we try to open to people a new oasis amid the huge and motionless
Enterprise-juggernauts. It’s a matter for us to be flexible and able to change.&lt;/p&gt;
&lt;h2 id=&quot;it-extravaganza&quot;&gt;IT-extravaganza&lt;a class=&quot;zola-anchor&quot; href=&quot;#it-extravaganza&quot; aria-label=&quot;Anchor link for: it-extravaganza&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Staying aside of &quot;hype-rays&quot; and rarely being in the recruitment market, our team have always thought that IT
environment has already educated engineers. Certainly, a great number of Java projects and endless PR-companies of
different businesses make us think that all the developers are already educated and they should not be explained simple
things.&lt;/p&gt;
&lt;p&gt;But IT world largely develops by the laws of playwriting and that’s when the problems not connected with development
appear:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The number of non-core and unprepared specialists, who evolved to developers, has achieved the tipping point. People are
now not embarrassed to send CVs with &quot;a machine gunner&quot; as their experience.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Machine gunner!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;The specialists who labelled themselves as &quot;Senior&quot; appear to be &quot;juniors&quot;. And there are many reasons for that: &quot;my
company said I am a senior&quot;, &quot;I can solve any problem on Java&quot;, &quot;Yandex is waiting for me&quot;. Some are more honest: &quot;Of
course I am a junior but I am paid as a senior — what can I do?&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;engineers&quot;&gt;Engineers?&lt;a class=&quot;zola-anchor&quot; href=&quot;#engineers&quot; aria-label=&quot;Anchor link for: engineers&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Let’s come to the roots and we might understand something:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Engineer: (French) ingénieur ← (Latin) ingenuim — abilities, creativity&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It is all simple: not to live in the realm of illusion, a person must create something, no matter if they are a writer or an engineer. It means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Engineers think projects not businesses, missions, etc., so they can define the entry point of their effort.&lt;/li&gt;
&lt;li&gt;An engineer must know what context is and must not suffer from &quot;vacuum syndrome&quot;, which is often manifested in
obsessive urge to use concrete technologies. The solution quality is measured by its congruence to the context, which
can be changed.&lt;/li&gt;
&lt;li&gt;Between the routine and interesting tasks, an engineer sees the right connection. If there is none, he expands the
context and finds the contradiction. Interesting tasks are not a whim but the meaning of activity. Without them an
engineer turns into a coder or a framework user and the business starts to parasite on the market body.&lt;/li&gt;
&lt;li&gt;An engineer has the correct understanding of fundamental knowledge as of an instrument enabling to create. To confirm
this opinion a &quot;Yandex&quot; developer, who often holds job interviews, commented on the problem: &quot;The point is that people
often consider a very limited number of solutions and don’t have a clue about some real facilities of the language.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An engineer needs to move in these directions — if they are a Junior or a Senior. Unfortunately, hype-rays create radio
noise among people and make it difficult to assemble an engineer team. But this is a great chance to launch new
companies and projects for the people who are tired of paradoxes and contradictions.&lt;/p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>The Story of the IT-depression, birds and EJDB 2.0</title>
		<published>2019-09-19T00:00:00+00:00</published>
		<updated>2019-09-19T00:00:00+00:00</updated>
		<link rel="alternate" type="text/html" href="https://blog.annapurna.cc/posts/the-story-of-the-it-depression/"/>
		<id>https://blog.annapurna.cc/posts/the-story-of-the-it-depression/</id>
    
		<content type="html" xml:base="https://blog.annapurna.cc/posts/the-story-of-the-it-depression/">&lt;p&gt;Apart from the development, I also teach at the Department of Informational Systems in a university, and once during the
exam I told one of my students that at the end of the course students should have at least a basic idea on how the
stop-and-copy garbage collector works. Student argued that the intellect and analytical skills can always offset not
knowing some facts, plus the topic itself looks minuscule in comparison to the fundamental laws of nature. Student
pointed out:&lt;/p&gt;
&lt;p&gt;—  Birds found out about electromagnetic fields way before us, they use them to orientate in space, but does it make them
smarter than humans?&lt;/p&gt;
&lt;p&gt;I want to tell you a story about one small but useful software project with some thoughtful implication.&lt;/p&gt;
&lt;h2 id=&quot;it-is-2011-popularization-of-nosql&quot;&gt;It is 2011: popularization of NoSQL&lt;a class=&quot;zola-anchor&quot; href=&quot;#it-is-2011-popularization-of-nosql&quot; aria-label=&quot;Anchor link for: it-is-2011-popularization-of-nosql&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The question about birds was asked in far-off 2011, and I really started to think about it. My lazy stream of thoughts
was interrupted by a mundane developer’s task: to make a convenient information storage and search system for audio
files metatags for a small media player written in C++.&lt;/p&gt;
&lt;p&gt;Taking on a task, just like any engineer, I started looking for the available solutions and, surprisingly, received
quite poor results: the implementation was either too bulky (SQLite) or had stability issues (GigaBASE). “Bulky SQLite?”
you might ask. Strangely enough, yes. My inner perfectionist was rebelling: the size of my whole project was one tenth
of the single sqlite.c file. At that time I didn’t compare project size to the system kernel. 2011 was the golden age of
different NoSQL solutions. I was taking a closer look at the MongoDB as a possible solution but we faced two essential
limitations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It was difficult to use MongoDB as an add-on DLL because it’s developers initially didn’t plan for such a use case,
and the MongoDB was not technically ready for this.&lt;/li&gt;
&lt;li&gt;MongoDB was under AGPL license which is, in my opinion,
detrimental. AGPL doesn’t bring anything to the world of open software and usually just a convenient cover for the
commercially-licensed products with a shareware code.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Looking for a better option of the lightweight data storage system for small projects, I defined the key qualities of the product:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Document-oriented with a possibility to store hierarchy of documents with an arbitrary structure.&lt;/li&gt;
&lt;li&gt;Support JSON documents collections. Implemented in &lt;code&gt;C99 language&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Free license which allows use in the closed sourced products.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;same-trap-twice&quot;&gt;Same trap twice&lt;a class=&quot;zola-anchor&quot; href=&quot;#same-trap-twice&quot; aria-label=&quot;Anchor link for: same-trap-twice&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;As you can guess, we created our own solution, which was inspired by the MongoDB: a database management system
implemented as a shared library (EJDB 1.0).&lt;/p&gt;
&lt;p&gt;EJDB 1.0 is based on a fascinating project TokyoCabinet, alas — abandoned now. EJDB became quite popular on github among
developers from all over the world. At that time one of the 10gen managers contacted me to discuss the query
compatibility between EJDB and MongoDB but it didn’t go any further than a discussion.&lt;/p&gt;
&lt;p&gt;However, we took too much from MongoDB and that became a problem. For example, the bulky format of the search queries,
e.g.:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;John&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$and&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;$or&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 38&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 39&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Eventually we realized that such query representation suits robots not people.&lt;/p&gt;
&lt;p&gt;Another controversial feature taken from the MongoDB was to keep document’s primary key in the document itself as
a special _id field, which mixes the original structure of the stored document with the implementation of the storage
system. Undoubtedly, the better approach would be to separate original documents from the data structures used to manage
collections.&lt;/p&gt;
&lt;p&gt;Despite the inner beauty of the TokyoCabinet, it imposed LGPL 1.x license on EJDB, which is freer than AGPL but still
limits the use of the EJDB by many projects.&lt;/p&gt;
&lt;p&gt;Being a bit disappointed I released a number of versions of EJDB and then left it inactive for a few years. From time to
time I recalled this project when I thought about that very question of birds.&lt;/p&gt;
&lt;h2 id=&quot;2018-inspiration-gained&quot;&gt;2018: inspiration gained&lt;a class=&quot;zola-anchor&quot; href=&quot;#2018-inspiration-gained&quot; aria-label=&quot;Anchor link for: 2018-inspiration-gained&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;It took a few years to finally convince myself that birds are not smarter than humans. They instinctively use the laws
of nature unable to comprehend them and to use according to their needs. But aren’t many developers doing the same?
Instead of comprehending “the laws of nature” they thoughtlessly migrate to technologies and frameworks like IT-birds
migrating with the seasons? A true story (from job interviews):&lt;/p&gt;
&lt;p&gt;—  You said you used TypeScript a lot. Does it mean you’re also familiar with JS and you understand how TypeScript improves it and what’s the difference?&lt;/p&gt;
&lt;p&gt;—  Well, I haven’t studied JS, so I can’t say.&lt;/p&gt;
&lt;p&gt;—  Why your tenure was so short in every company you worked for?&lt;/p&gt;
&lt;p&gt;—  The projects were generally boring. Wild outsourcing, you see? I want to develop real products!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/20190919/two.png&quot; alt=&quot;two&quot; /&gt;&lt;/p&gt;
&lt;p&gt;After interviewing yet another candidate Andrew and I got a drink, discussed candidates and talked about the unnecessary
complications of the modern software. Many specialists who came to the interview were surprised that we do not use
Spring Boot in our projects: &quot;because everybody does&quot;. But almost no one is surprised by the Slack-like desktop apps
based on Eleсtron, which effectively are secretly packed full featured web-browsers eating up hundreds of megabytes of
virtual memory to serve a simple chat.&lt;/p&gt;
&lt;p&gt;During the discussion we started to understand what irritates us so much in the modern IT — the inappropriate use of the
monstrous hype solutions.&lt;/p&gt;
&lt;p&gt;—  Stop complicating! — we decided, and used this as an inspiration we took on the second version of EJDB.&lt;/p&gt;
&lt;h2 id=&quot;ejdb-2-0-philosophy-of-openness-and-simplicity&quot;&gt;EJDB 2.0: philosophy of openness and simplicity&lt;a class=&quot;zola-anchor&quot; href=&quot;#ejdb-2-0-philosophy-of-openness-and-simplicity&quot; aria-label=&quot;Anchor link for: ejdb-2-0-philosophy-of-openness-and-simplicity&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Open source can not be half-open, so we decided to use the MIT license for all the project components, completely getting rid of LGPL code from the TokyoCabinet.&lt;/p&gt;
&lt;p&gt;Just for the EJDB2 we developed Key-value data storage &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://github.com/Softmotions/iowow&quot;&gt;IOWOW&lt;/a&gt; under the MIT license.&lt;/p&gt;
&lt;h3 id=&quot;simple&quot;&gt;Simple&lt;a class=&quot;zola-anchor&quot; href=&quot;#simple&quot; aria-label=&quot;Anchor link for: simple&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;IOWOW can work with a lot of key-value data sub-bases, stored in one file, which simplified transferring the data
between devices and making backup copies and it also reduces the chance of inconsistencies in the storage data.&lt;/p&gt;
&lt;p&gt;IOWOW is based on the simple data structure —  skip list, which allowed us to create a much more understandable
implementation of the persistent storage with a much smaller code base (compared to B+tree and LSM tree) with high
performance (according to benchmarks).&lt;/p&gt;
&lt;p&gt;Maximum volume of a database file is &lt;code&gt;512G&lt;/code&gt;, which is a consequence of compromises in the implementation of the one-file
database on skip lists.&lt;/p&gt;
&lt;p&gt;Documents stored in the EJDB2 collections are serialized in a simple binary format —  &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://github.com/liteserver/binn&quot;&gt;Binn&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;clear&quot;&gt;Clear&lt;a class=&quot;zola-anchor&quot; href=&quot;#clear&quot; aria-label=&quot;Anchor link for: clear&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;During the work on EJDB2 we reconsidered the search queries format and we introduced a new, more intuitive (comparing to
the 1.x version) XPath-like search queries —  the JQL language.&lt;/p&gt;
&lt;p&gt;JQL supports JSON Patch and JSON merge patch standards. Here are some examples:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;/[firstName = Andy]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;/[firstName = Silvio] and /[lastName = &amp;quot;De Sousa&amp;quot;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Select all documents and then keep (project) only firstName and lastName fields in the resulting documents:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;/* | /{firstName,lastName}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;easy&quot;&gt;Easy&lt;a class=&quot;zola-anchor&quot; href=&quot;#easy&quot; aria-label=&quot;Anchor link for: easy&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;It is always better to have a choice than not, so, despite that the easiest and the most efficient way of accessing the
data is to do it locally, with EJDB2 you can expose your database via HTTP/Websocket protocols so you can access it
remotely over the network using a simple text protocol. This substantially broadens the number of architectures you can
have with EJDB2. To enable remote access, built-in HTTP server can be configured and started using C API or a separate
executable can be started. You can both query and manage your data using network API.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/20190919/one.jpg&quot; alt=&quot;two&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;aside-from-the-hype-rays&quot;&gt;Aside from the hype-rays&lt;a class=&quot;zola-anchor&quot; href=&quot;#aside-from-the-hype-rays&quot; aria-label=&quot;Anchor link for: aside-from-the-hype-rays&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Having finished with the birds, I got haunted by the thoughts about a spanner — this invention was not intended to
tighten all possible kinds of screw-nuts but the number of screw-nuts existing just for this spanner is enough for it to
have it’s purpose of life. On the other hand, it is weird to tighten all screw-nuts with one spanner. It’s quite common
to promise developers to ride a spaceship but in reality they dig a tunnel with a pickaxe. We give them pickaxe right
away because it is the only way to stop being a bird and understand which spanner will suit which screw-nuts.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://github.com/Softmotions/ejdb&quot;&gt;EJDB2&lt;/a&gt;&lt;/p&gt;
</content>
	</entry>
</feed>
