Makefile Best Practices

Sun, 10 Jul 2022 11:19:12 -0700

There’s no real guide for writing distribution-quality makefiles, so here’s my attempt at compiling some [adjective for knowledge that is not documented but known via word of mouth and experience] knowledge.

Most of this is accumulated via working with Makefiles for writing gentoo packages, gentoo requires standard makefiles because that’s mostly how it interfaces with the build system


makefiles make heavy use of variables, so being able to set these to be configurable by the building agent is useful. Here are some distinctions:


This directory is where your installed package should eventually end up.

I don’t think any explicit copies/moves should be done to this directory, it’s just where your application’s hardcoded paths should prefix themselves with this directory

For example, a common install might be to root: /, or maybe to /usr/ since a lot of packages go there. /usr/local/ is also an option. I know homebrew uses /opt but one might even want to install a package into a user-owned directory: /home/joe/.local or whatever.

Note: You might not be able to use this variable for install locations / expected locations of other packages. I’ve found especially with things expected to be in /etc/, you just need to hardcode that top-level root.


This should be the prefix in which files are actually installed to. If DESTDIR=/, then files should be installed under the root in whatever directories you want.

This may be different from where the files actually end up, if you include hard coded paths in your source code to where files end up those should not depend on DESTDIR.

How this plays out in gentoo is: files are sandbox installed in DESTDIR, tracked, and then copied over to the system install prefix.

Additionally, you can’t assume the structure of DESTDIR because of this. It is very likely that entire tree is empty, so you need to create all directories you want to install files in, etc


This looks to be the standard way to install files. Because of the above destdir warning about created directories,

you probably definitely want to use the -m flag to set permissions, by default everything installed is executable


If you want to install files in /run/ (or any temporary directories), you need them to be created on each startup. That’s where tmpfiles.d comes into play.

The standard seems to be appending .tmpfiles.conf for the configuration file if you want to distinguish it from a normal configuration file.