While preparing a presentation for my intermediary thesis' defence, I wanted to use graphics instead of words so my audience wouldn't have to read and listen at the same time.
Rather than fiddling with shapes and images in traditional office software, I knew I'd be less frustrated just using the SVG editor Inkscape.
And a makefile would be nice to stitch the SVGs together to create a PDF file that I could use during my exposé.
We already declared the corresponding SVG file as a dependency for each slide's PDF, so *make* will know that it should rebuild them if the SVG was changed.
And if any PDF was updated, the end result will be, too.
If you now create a file `clean` and run `make clean`, *make* will quite contently say it doesn't need to do anything: the file `clean` exists and it depends on nothing else.
To avoid this, non-file targets must be marked as "phony".
If you would use our makefile up to now, Inkscape would fail, complaining that `build/` doesn't exist.
This is to be expected, since directories have to be created before you can place files in them.
Much to my dismay, there seems to be no clean, standard way to create the necessary directories in *make*.
In my opinion, this is *make*'s single biggest shortcoming.
There [are a few ways](https://www.cmcrossroads.com/article/making-directories-gnu-make), none of them elegant.
For our simple makefile, we can just put `@mkdir -p $(@D)` in each rule.
It's not ideal for performance, **TODO and it might give race conditions if there are more directories and rules, should think how to word this and stuff when less tired**
You'll have noticed by default *make* prints the commands it executes; the `@` in front of this trivial command suppresses this.
`$(@D)` refers to the parent directory of the current target.
`$(OUTPUT)` is currently defined as `slides.pdf`, but we might change it to another directory later.
So just for good measure its rule too gets the special `mkdir` treatment.
One more thing: the default target, for when you call *make* without arguments, is the first one in the makefile (with [some caveats][gmake_docs_targets]).
You could override this with `.DEFAULT_GOAL := your_target_name_here`, but it's just as easy to reorder the rules, which is what I've done in the summary below.
[gmake_docs_targets]: https://www.gnu.org/software/make/manual/html_node/Goals.html "Goals – GNU make documentation"
I'm using *GNU make* and I'll admit I don't know if this works in other flavours.
GNU's documentation is installed on my system and accessible with `info make` (<kbd>tab</kbd> to jump to next link, <kbd>enter</kbd> to activate it, <kbd>l</kbd> to return to previous screen, <kbd>Shift+h</kbd> for help).
When online you can also use the [online documentation][gmake_docs].
[gmake_docs]: https://www.gnu.org/software/make/manual/html_node/index.html "GNU make documentation"