Makefile Conventions
There's no real guide for writing distribution-quality makefiles, so here's my attempt at compiling some conventional 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
Variables
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:
PREFIX := /usr: Able to be overridden as a command line argument egmake PREFIX=/optPREFIX ?= /usr/: Able to be overridden as a command line argument OR environment variable egPREFIX=/opt make. I don't actually know of a build system that passes these through env variables but not makefile arguments, but better safe than sorry. This one's preferred unless you know env variables are going to get in your way
PREFIX
https://wiki.gentoo.org/wiki/Project:Prefix/Technical_Documentation
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.
DESTDIR
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 is called INSTALL_ROOT for qmake
- https://www.gnu.org/prep/standards/html_node/DESTDIR.html
- https://stackoverflow.com/questions/11307465/destdir-and-prefix-of-make
INSTALL_ROOT
see above
C{,PP,XX}FLAGS
LDFLAGS, LDLIBS, LOADLIBES
LOADLIBES is deprecated, LDLIBS is not, https://stackoverflow.com/questions/17052006/make-ldlibs-deprecated -> https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
C{,PP}_SRCS
devdoc.net/web/developer.mozilla.org/en-US/docs/How_Mozilla's_build_system_works/Makefile_-_variables.html
uses CSRCS instead
OBJS
from www.gnu.org/s/make/manual/html_node/Variables-Simplify.html:
It is standard practice for every makefile to have a variable named objects, OBJECTS, objs, OBJS, obj, or OBJ which is a list of all object file names. We would define such a variable objects with a line like this in the makefile:
install(1)
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
make check
Runs tests
tmpfiles
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.
conventional goals
https://www.gnu.org/software/make/manual/make.html#index-all-_0028standard-target_0029 https://www.gnu.org/software/make/manual/html_node/Standard-Targets.html
ROOT
A Note about writing makefile libraries
I've been around the block. I've written makeduino, I've wrangled with bespoke embedded toolchain's automagical make libraries.
Makefile libraries should be designed to fit within the variables and conventions defined within here, but they shouldn't define an automatic way to build the thing. They should provide examples and templates, but the makefile needs to just provide rules with no actual enforced directory structure or expectations as to what's plugging in to it. this way, they're extensible.