Volodymyr Gubarkov

Stand With Ukraine

Makesure vs Just command runners on examples

December 2023

This article compares the two tools on some particular real-world examples.

#1 Defining dependent vars


Makesure was deliberately designed to not have its own programming language. In essence, it consists of goals + dependencies + handful of directives + shell. So it doesn’t have two types of variables and therefore has an idiomatic solution:

  GIT_COMMIT="$(git rev-parse --short HEAD)"
  GIT_TIME="$(git show -s --format=%ci $GIT_COMMIT | tr -d '\n')"

@goal default
  echo "$GIT_COMMIT"
  echo "$GIT_TIME"

#2 Comments in recipes are echoed


Makesure doesn’t echo script lines by default. Command runner (as opposed to a build tool, like make) is recipe-oriented, not line-oriented. The unit of work is a recipe, not a line. So the recipe body is just an implementation detail.

However, it logs the goal names being executed, such that it’s clear what’s going on:

$ ./makesure
  goal 'fhtagn_installed' [already satisfied].
  goal 'debug' ...
GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
  goal 'debug' took 0.006 s
  goal 'prepared4tests' [empty].
  goal 'tests.basic.tush' ...
TESTS PASSED : tests.basic.tush
  goal 'tests.basic.tush' took 0.273 s
  goal '*.tush' [empty].
  goal 'tested' [empty].
  goal 'default' [empty].
  total time 0.281 s

Though, if you need, Makesure also has -x option with the same function as in shell (activates command tracing).

#3 Distinction between doc and non-doc comments


Makesure doesn’t have such issue because it uses a special directive @doc for a goal description, which doesn’t interfere with regular comments:

# some regular comment
@goal do_it
# some other comment
@doc 'This is a very useful goal'
  echo 'Doing...'

Overall Makesure chose an approach with a uniform syntax via directives rather than an ad-hoc syntax for every feature. This proved to be very solid choice for many reasons:

Makesurefile syntax highlighting

#4 Need to install


Makesure doesn’t need installation

#5 Files as dependency


How you do it with makesure

#6 Default target doesn’t play well with !include


By default, just invokes the first recipe. Makesure by default invokes the goal named default. So, although makesure doesn’t have includes, if it had, the issue would not happen.

#7 just can fail to execute shebang-recipes due to ‘Permission denied’


Makesure doesn’t produce temp files during goals execution, so it’s not susceptible to this problem.

#8 Need for custom functions for string manipulation


Makesure uses shell (instead of its own programming language) and relies on shell variables (instead of its own kind of variables).

The idiomatic solution to the described problem using parameterized goals:

@define BUILD_DIR 'build'
@define FILE_NAME 'out'

@goal pandoc @params ARG EXT @private
    echo pandoc input.md -o "$BUILD_DIR/$ARG/$FILE_NAME.$EXT"

@goal html @params ARG
@depends_on pandoc @args ARG 'html'

@goal pdf @params ARG
@depends_on pandoc @args ARG 'pdf'

@goal foo
@depends_on html @args 'foo'
@depends_on pdf  @args 'foo'


$ ./makesure -l
Available goals:

$ ./makesure foo
  goal 'pandoc@foo@html' ...
pandoc input.md -o build/foo/out.html
  goal 'html@foo' [empty].
  goal 'pandoc@foo@pdf' ...
pandoc input.md -o build/foo/out.pdf
  goal 'pdf@foo' [empty].
  goal 'foo' [empty].

$ ./makesure html@foo
  goal 'pandoc@foo@html' ...
pandoc input.md -o build/foo/out.html
  goal 'html@foo' [empty].

#9 Lack of incremental changes support

Such support could help avoiding unnecessary re-runs.


Idempotence is achievable elegantly with Makesure using @reached_if directive.


It’s clear that as an author of the tool I’m completely biased.

But to me the minimalism and inherent simplicity and coherence allows Makesure to eliminate having some problems, as well as solve many problems more elegantly.

If you are interested, I invite you to try out the makesure utility in your projects.

If you noticed a typo or have other feedback, please email me at xonixx@gmail.com