<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: RZM64</title>
    <description>The latest articles on DEV Community by RZM64 (@rzm64_c7017ade827d335e7ea).</description>
    <link>https://dev.to/rzm64_c7017ade827d335e7ea</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4208902%2F778c9e42-870a-40c2-a98e-9c8e2ac6c3d8.jpg</url>
      <title>DEV Community: RZM64</title>
      <link>https://dev.to/rzm64_c7017ade827d335e7ea</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rzm64_c7017ade827d335e7ea"/>
    <language>en</language>
    <item>
      <title>I was tired of writing CMake. So I built a simpler build system.</title>
      <dc:creator>RZM64</dc:creator>
      <pubDate>Mon, 26 Oct 2026 14:13:08 +0000</pubDate>
      <link>https://dev.to/rzm64_c7017ade827d335e7ea/i-was-tired-of-writing-cmake-so-i-built-a-simpler-build-system-6d</link>
      <guid>https://dev.to/rzm64_c7017ade827d335e7ea/i-was-tired-of-writing-cmake-so-i-built-a-simpler-build-system-6d</guid>
      <description>&lt;h2&gt;
  
  
  The frustration
&lt;/h2&gt;

&lt;p&gt;I didn't start building HelpMake because I was bored. I started because CMake kept breaking on me.&lt;/p&gt;

&lt;p&gt;It would not work for me, Cmake was bugging, crashing, complex to learn, annoying,...&lt;/p&gt;

&lt;p&gt;At some point I realized I wasn't the only one. Every C++ Discord, every Reddit thread, every "what's wrong with my build" question, it's the same story. People don't hate CMake because it's bad. They hate it because it's &lt;strong&gt;a lot&lt;/strong&gt;, and it breaks in ways that aren't obvious, and every project needs a slightly different incantation to make it work.&lt;/p&gt;

&lt;p&gt;I don't build 100,000-file projects. I build 5–20 file projects. Sometimes 50. For that scope, CMake is a lot of machinery for a small job, and the failure modes are worse than the thing it's trying to solve.&lt;/p&gt;

&lt;p&gt;So I built a build system where the whole config fits on one screen and you build with one command.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;CMakeLists.txt&lt;/code&gt; itself isn't really the problem. It's everything around it. The generator step. The out-of-source build requirement. The "why is it building in Debug when I didn't specify". The "why does this work on Linux but not Windows".&lt;/p&gt;

&lt;p&gt;I don't build 100,000-file projects. I build 5–20 file projects. Sometimes 50. For that scope, CMake is a lot of ceremony for a small job.&lt;/p&gt;

&lt;h2&gt;
  
  
  What if it was one file?
&lt;/h2&gt;

&lt;p&gt;I wanted a build system where the whole config fits on one screen and you build with one command. Not one command to configure another to build. Just one.&lt;/p&gt;

&lt;p&gt;So I built one. It's called &lt;strong&gt;HelpMake&lt;/strong&gt;. The entire config for a small C++ project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Compiler: g++
Version: std=c++20
Output: build/app

InputFiles {
    src/**/*.cpp # built-in recursive glob
}

Includes {
    include
}

Flags {
    -Wall
    -O2
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;hm -b&lt;/code&gt; and you get a binary. No configure step, no generator, no build directory you have to manage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, another build system?
&lt;/h2&gt;

&lt;p&gt;I know. There are dozens. But every one I tried had the same problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Make&lt;/strong&gt; - doable, but you can't see the whole build script on one screen, and it's not cross-platform by design&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CMake&lt;/strong&gt; - powerful, but a lot of ceremony for small projects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meson&lt;/strong&gt; - nice, but you still configure before you build&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bazel&lt;/strong&gt; - for Google-scale monorepos, not side projects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ninja&lt;/strong&gt; - a backend, not something you write by hand&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The gap I kept running into: there's a &lt;strong&gt;"too much"&lt;/strong&gt; tier (CMake, Bazel, Meson) and a &lt;strong&gt;"too raw"&lt;/strong&gt; tier (Make, Ninja), but no &lt;strong&gt;lightweight&lt;/strong&gt; tier that's actually simple.&lt;/p&gt;

&lt;p&gt;That's the tier I wanted.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's actually interesting about it
&lt;/h2&gt;

&lt;p&gt;The basic config isn't the interesting part. It's how a build system &lt;em&gt;should&lt;/em&gt; work. These three things are why people actually use HelpMake:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Cross-platform without duplication
&lt;/h3&gt;

&lt;p&gt;On Windows you want &lt;code&gt;/W4&lt;/code&gt; and &lt;code&gt;/EHsc&lt;/code&gt;. On Linux you want &lt;code&gt;-Wall -Wextra -pthread&lt;/code&gt;. In CMake that's &lt;code&gt;if(WIN32) ... else() ... endif()&lt;/code&gt; blocks. In HelpMake:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Flags {
    -Wall
    win: /W4 /EHsc
    linux: -Wextra -pthread
    mac: -Wextra
    x64: -march=native
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;win:&lt;/code&gt; and &lt;code&gt;linux:&lt;/code&gt; prefixes are &lt;strong&gt;platform conditionals&lt;/strong&gt;. Any line can have one. One config for every OS.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;code&gt;hm test&lt;/code&gt; - a real test runner
&lt;/h3&gt;

&lt;p&gt;Mark configs as tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Config: test-core {
    Test: true                  # Save as test
    Output: build/test-core
    InputFiles { tests/core.cpp }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;hm test&lt;/code&gt; builds and runs every marked config. Exit code 1 on failure. That's what CI needs, built in, no separate &lt;code&gt;ctest&lt;/code&gt; step.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;code&gt;hm -b -w&lt;/code&gt; - watch mode
&lt;/h3&gt;

&lt;p&gt;Save a file, rebuild. Save a file, rebuild. &lt;code&gt;hm -b -w -r&lt;/code&gt; builds, runs, and rebuilds on save. That's the entire dev loop in one command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest caveats
&lt;/h2&gt;

&lt;p&gt;HelpMake isn't trying to replace CMake. It won't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate Visual Studio solutions&lt;/li&gt;
&lt;li&gt;Auto-detect hundreds of system libraries (you write &lt;code&gt;Dependency: raylib { ... }&lt;/code&gt; for external libs)&lt;/li&gt;
&lt;li&gt;Handle 100,000-file projects&lt;/li&gt;
&lt;li&gt;Give you &lt;code&gt;CMakeLists.txt&lt;/code&gt; compatibility if you need to hand the project to someone using CMake&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need any of those, &lt;strong&gt;use CMake&lt;/strong&gt;. Seriously.&lt;/p&gt;

&lt;p&gt;HelpMake is for the projects where CMake feels like overkill - which, for a solo dev or a small team, is most of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned building it
&lt;/h2&gt;

&lt;p&gt;Three things I didn't expect:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;C++20 modules are still a mess in build systems.&lt;/strong&gt; Every compiler handles them differently. Getting GCC and Clang working end-to-end took more time than the rest of the parser combined.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Just one more flag" is how build configs get to 200 lines.&lt;/strong&gt; Every feature I added had to justify why the user can't just put it in &lt;code&gt;Flags { }&lt;/code&gt;. That constraint kept the file format small.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The hard part isn't the build system. It's the error messages.&lt;/strong&gt; A build system that fails with "compilation failed" is useless. HelpMake tries to say &lt;code&gt;HelpMake.txt:42: unknown field 'Compilr:' - did you mean 'Compiler:'?&lt;/code&gt; Getting those right is most of the work.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;If you've read this far, you probably have a project in mind where CMake feels like too much. HelpMake might be for you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hm &lt;span class="nt"&gt;--install&lt;/span&gt;    &lt;span class="c"&gt;# or build from source, ~30 seconds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Compiler: g++
Output: game.exe
InputFiles {
    src/*.cpp
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hm &lt;span class="nt"&gt;-b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/Gag91/Help_Make" rel="noopener noreferrer"&gt;https://github.com/Gag91/Help_Make&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs:&lt;/strong&gt; &lt;a href="https://github.com/Gag91/Help_Make/tree/main/docs" rel="noopener noreferrer"&gt;https://github.com/Gag91/Help_Make/tree/main/docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MIT licensed. Single binary, no runtime dependencies. If it's useful, a ⭐ on the repo helps other people find it.&lt;/p&gt;

&lt;p&gt;If it's &lt;em&gt;not&lt;/em&gt; useful - if CMake is the right tool for your project - that's completely fine, and I'd love to hear what your CMake setup looks like. That's the kind of feedback that makes the next version better.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Xavi&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cpp</category>
      <category>buildsystem</category>
      <category>programming</category>
      <category>resources</category>
    </item>
  </channel>
</rss>
