-
Technically all of these make targets look for files by the names of the targets. Each one should really be defined as .PHONY.
That said, I used to write makefiles like this all the time, but have since switched to just and justfiles in recent years which make this the default behavior, and is generally simpler to use. Things like parameters are simpler.
https://github.com/casey/just
-
SaaSHub
SaaSHub - Software Alternatives and Reviews. SaaSHub helps you find the best software and product alternatives
-
I do like "just" being suggested, but I strongly prefer using a very simple bash run script for tasks that do not require "make"'s extras, especially given that most modern build tools do parallelism and artifact caching internally.
Inspired by:
https://github.com/adriancooney/Taskfile
https://death.andgravity.com/run-sh
-
I also use make this way and have done for years. I even have the same kind of religious ritual the author has, like writing the Makefile is part of setting up the codebase and organising in my own head how the whole local dev environment is going to work.
The only thing is, this isn't what make is actually for. A number of commenters have recommended Just - the one I've been using on my personal projects is Task - https://taskfile.dev/ - which is pretty great. As other commenters have said, the problem is that make is installed everywhere already. I would love to see a task runner become standard to the same extent, and will have a look at Just if that's the one people are using.
-
Makefiles are an eerily lisplike turing tarpit. I hand wrote the makefiles for my projects, they generate wonderfully organized build trees. Hell I use makefiles to manage my dotfiles repository, even blogged about it.
https://www.matheusmoreira.com/articles/managing-dotfiles-wi...
The sanest way I've found to write makefiles is to think of it as a tool that maps input paths to output paths. When compiling a program, I want to map source/program.c to build/$(config)/program. So I write pattern rules that do just that. Then I write make functions to convert paths in some tree to paths in another tree, which makes it easy to declare dependencies which then match the pattern rules. These functions are then helped by lots and lots of project specific variables to organize things.
Using make without phony targets is insane. Without phony targets, I'd need to type things like "make build/aarch64/executable" in order to get a build started. So I use phony targets for everything.
It got to the point I created a phony-targets shell script which parses make's database output and processes it into a sort of help text for any given makefile's phony targets interface:
https://github.com/matheusmoreira/.files/blob/master/~/.loca...
-
> Does anyone know of anything better than Make?
Xmake https://xmake.io/ for C and C++ (I haven't use that for anything serious yet) and Buck 2 https://buck2.build/ if you need a really complex build system.
-
> Does anyone know of anything better than Make?
Xmake https://xmake.io/ for C and C++ (I haven't use that for anything serious yet) and Buck 2 https://buck2.build/ if you need a really complex build system.
-
Pixi is native on Windows, can install a wide range of dev tools and has task running built into projects (alongside dependency management).
https://pixi.sh/
-
Many responses suggesting a simple bash script instead. One reason I like make is that I can just tab-autocomplete targets. No extra setup needed.
If you’re using a single entry point script (e.g. do.sh) and handling $1 you don’t get that for free.
And the moment you need to make your entry point script aware of “B requires A” then you’re going to half-bake something similar to make, anyway.
Here’s [1] my ~80 line version for Python projects (micromamba + uv) which I’ve been pretty happy with.
[1] https://github.com/giovannipcarvalho/micromamba.mk
-
I use Make fairly similarly. You should .PHONY any non-file targets though lest you want your build to break suddenly and confusingly when you add a folder named say "build" in the authors case.
Make checks file modification dates by default to see if it can eliminate steps. Setting a target as a .PHONY indicates
Here's a very simple example
https://github.com/donatj/force-color.org/blob/dev/Makefile
-
-
Many have mentioned just, but I'm a much bigger fan of Earthly [0].
It allows you to write something similar to a Makefile, but everything runs in Docker. This gets you isolated builds with parallelism and caching built-in.
I've found it to be great especially for small to medium projects. For some examples, I use it to publish my personal site/blog [1] and to build a C/C++/Fortran/Rust cross-compiler targeting macOS [2].
[0]: https://earthly.dev/
[1]: https://github.com/shepherdjerred/sjer.red/blob/main/Earthfi...
[2]: https://github.com/shepherdjerred/macos-cross-compiler/blob/...
-
Many have mentioned just, but I'm a much bigger fan of Earthly [0].
It allows you to write something similar to a Makefile, but everything runs in Docker. This gets you isolated builds with parallelism and caching built-in.
I've found it to be great especially for small to medium projects. For some examples, I use it to publish my personal site/blog [1] and to build a C/C++/Fortran/Rust cross-compiler targeting macOS [2].
[0]: https://earthly.dev/
[1]: https://github.com/shepherdjerred/sjer.red/blob/main/Earthfi...
[2]: https://github.com/shepherdjerred/macos-cross-compiler/blob/...
Related posts
-
Makefiles for Web Work (2022)
-
Just: A Command Runner
-
Mask – A CLI task runner defined by a simple Markdown file
-
Foy: A simple, light-weight, type-friendly and modern task runner for nodejs, to make it easier for you to write NPM scripts.
-
Officially a Benefexer: My Journey from Probation to Becoming the First Backend Software Engineer in the Cebu Office