EZmakefile: One makefile to rule them all

a pre-configured, dynamic makefile for all of us who hate them

Kostis Maninakis
6 min readMay 21, 2017

One makefile to rule them all,
one makefile to find them (source files),
a single make to build them all
and into a bin compile them.

—I’m sorry, I tried

EZwut?

EZmakefile is a plug-n-play, easily configurable, directory-structure-agnostic makefile to be consumed by GNU Make tool into your C and C++ projects. EZmakefile makes getting started on new C/C++ projects a breeze and scales automagically as your projects get larger. It can be extended to support your custom scenarios if need be, yet keeps out of your way until then. It features automatic compilation into intermediate object files, but it does so by compiling only those source files that have been changed since last build.

For example, let’s say there are 10 .c files in your project. If you updated the code in just one source file and went on to build or make your project, you wouldn’t want to compile all 10 .c files again every time. The code in the 9 other files hasn’t changed, so why compile it all again? Ideally you’d want to compile only those source files that have been updated and let the rest chill. EZmakefile does for you just that. Even as you add new .c and .h files or remove them from your project, it all just works.

If you are still unsure of what GNU Make is, why it’s needed, or just need a quick refresher of your CS102 days, here’s a great and to-the-point read into makefiles from Boston University.

You sure it’s for me?

EZmakefile will be of most use to anyone starting out with a new C or C++ project. People like students or more experienced programmers who just want to write some code and see it build with a single make command in the terminal, without ever having to fiddle with mind-bending makefile configurations, or set up anything at all to get a build going. That being said, it could also serve as a powerful boilerplate makefile for advanced programmers that want to enjoy its automation and extend it with additional rules to accompany their specific needs.

Enough talk, show me the money!

Sure, here you go:

(a gif of EZmakefile running in the terminal, may take a sec to load)

That’s cool, but what exactly happened here?

Hopefully what you expected. Typing a single make command in the terminal builds the whole project, typing make clean deletes the generated executable and all intermediate object files and typing make run will run the executable. If there’s need to build it first, it will do so before proceeding to run it as commanded.

Getting Started

Essentially all you have to do is download the file named makefile from the github repo and move it to your project’s directory. Depending on your case you would probably have to do a simple 1 minute configuration drill setting up a couple variables, but don’t worry, I’ll show you how in a sec.

But first let’s have a closer look at the code, have a quick top-level tour around and see how you can have fun with it yourself.

Probably outdated gist, checkout actual EZmakefile github repo for latest version

So as you can see, EZmakefile’s source is split into three major sections: Configuration, File Lists, and Dependency Rules. Broadly speaking you could think of these three as “play here”, “keep off” and “don’t touch unless you know what you are doing”, respectively.

Configuration

Any variable that begins with an underscore e.g. _HSUF is exactly where you have to stand when playing. Some variables here that don’t begin with an underscore are best left alone, unless you are feeling confident on what you are doing. While each variable should already be sufficiently documented in-line, for the sake of the example, if you are programming in plain C instead of C++, you would probably want to change the following variables to look like this:

_SSUF = c#        # Suffix of source files
_HSUF = h# # Suffix of header files
_CC = gcc# # Compiler to be used

Notice the trailing # character which acts as a delimiter for Make. It’s a best practice to make sure that everything in the makefile is parsed the way you intend it to, so make sure you leave it there.

File Lists

This section is very much a “keep off” area unless you’re also meddling with the rules extensively to extend EZmakefile’s functionality. More or less it’s a couple of glorified shell scripts to store in each variable the names + their path, both for the header files and for the intermediate object files (which may initially not exist, but are extrapolated from the source filenames).

Dependency Rules

This section is the bread and butter of any makefile; it’s where all the magic happens. .PHONY and .SILENT are special built-in target names of Make that are used here as a best practice and to achieve the fancier, cleaner logging of EZmakefile.

Next up are the actual dependency rules, loaded to the brink with meta-ness. I’ll avoid going into any detail here unless you ask me to and there’s already enough in-code documentation to get a good abstract idea of what each rule is supposed to do. Worth noting is that by default EZmakefile supports the three make targets make, make run, make clean, as they were formerly described in the beginning of this chapter. This code section can of course be extended with additional and more fine-grained rules if there’s need for that and if you know your way around makefiles.

The rest of the files in the repo, like the C++ code, are there for boilerplate/demo purposes and can safely be ignored or deleted. If the makefile is all you need, just copy-paste this one file from the github repo into your working directory.

Limitations (or what’s coming next)

Nice as EZmakefile’s automation is, as with most automated solutions, it’s bound to come with its own set of limitations; some of which could be seen as missing features and others maybe as problems that we’ll just have to live with or go back to manual makefile scripting (or put up with yet another layer of automated complication like GNU Automake or CMake). The list is by no means exhaustive and please feel free to help me out nail them down either in the comments below or as issues on github.

  • if a header file changes, all source files will have to be compiled (no way to know which source file imports which header file unless you crawl every source file before every make and do plenty of hard tricks thereafter)
  • it works only on UNIX systems (it could be extended to support Windows)
  • there is currently no way of switching to a “verbose mode” by flipping a configuration flag and having EZmakefile print the actual noisy bash scripts instead of the default fancier printouts
  • there is currently no support for multi-level ordering of files within the designated folders that contain the source or header files. So all .c or .cpp files must rest within the same folder and similarly for header files.
  • there is currently no support for multiple suffixes of source or header files. So your source files will have to all be either .c or .cpp and similarly with header files.

Parting words

It’s funny because programming in C and C++, especially in the eyes of those developing for the web, is known to sometimes look like sort of a black art. All those pointers and low level code and manual memory management, it’s almost mystical. And then there’s those weird makefiles to build it all into an executable. Competent C/C++ engineers are thus renowned dark artisans of this realm for many that work outside of it. I may have had my fair share of the dreaded Segmentation Fault, but I still see myself as an outsider. Yet, with EZmakefile I may just help you and me a bit make our way through this marvelous realm. Hopefully without ever having to meddle with pesky build configurations at all, or at least do it to a minimum and only when there’s actual need for it. While I’m excited with what this little project already is, I’m even more excited thinking what it can become.

The project is published under GNU GPLv3 licence and I know there are still lots of stones yet left untouched, so if you see anything missing or something that could be improved, I’d love to see all you dark artisans of the realm open an issue or file a pull request with your own tricks to help make it better for all.

If you found this was worth your time, please click the 👏 below so that other people may see it here on Medium.

Thank you for your attention.
--maninak

--

--

Kostis Maninakis

I enjoy writing about code, entrepreneurship, life and anything in between. https://maninak.com