Z.MK(5)
π z.mk(5) β the manual page, bestie edition π
okay so this is z.mk(5), a section-5 (file formats) manual page from the LOCAL manual. It's about a makefile library, and yes, it's about to be your new hyperfixation. π¦
β¨ NAME β¨
z.mk β a library for writing featureful Makefiles. That's it, that's the whole vibe. π
πΈ SYNOPSIS πΈ
here's the whole "how do I even use this" moment, verbatim, no cap:
# Define name and version of the project.
Project.Name=foo
Project.Version=1.2
# Include the configuration file generated by the configure script, if one
# exists. This enables a multitude of configuration options to be used.
-include config.foo.mk
# Assume the source code is in the current directory. This variable is always
# defined by the generated configuration file, enabling support for out-of-tree
# builds.
ZMK.SrcDir ?= .
# Include z.mk by searching include directories. If zmk is not globally
# installed then ZMK.Version expands to nothing. As a last resort, assume that
# zmk was bundled into the release archive.
include z.mk
ifeq ($(value ZMK.Version),)
include $(ZMK.SrcDir)/z.mk
endif
# ZMK is now ready. Import additional modules or expand templates as necessary.
like. look at it. that last line is giving "you're all set, go be great" energy and I am obsessed. π
π DESCRIPTION π
z.mk, aka ZMK, is a library of GNU-make compatible makefiles that hands you an opinionated module and template system. She has taste. She has a point of view. And she comes with a whole collection of modules for common C/C++ software projects: compiling programs, creating libraries, installing development headers, data files, testing, etc. β¨
plus β and this is the part that lowkey eats β the library also offers specialized modules for constructing new modules that reuse specific behavior, like participating in targets such as all, clean, install or uninstall. modules that build modules. she's self-aware. main character energy fr fr. π
π§ Naming Convention
ZMK ships a convention for developing Make libraries. It's an informal convention, and the whole goal is reducing friction in an untyped language that has literally zero encapsulation system, which isβ¦ Make itself. π
Almost all variables and functions use a naming convention: every name gets prefixed with the name of the module, followed by a dot.
On top of that, every name is either:
- public β meant for other people to use, and it comes with some API stability guarantees π«Ά
- private β part of the implementation, not the interface you should be relying on, even though literally nothing in make stops you from touching it anyway π
Public names are capitalized. Private names start with a lower case character. That's the whole vibe check.
for example, ZMK.Version is a public symbol holding the version of the ZMK library, while ZMK.z.mk is a private symbol holding β at the time of this writing β the full path of the loaded z.mk library. slay. π
π¦ Modules
ZMK comes with a module system, which builds on the make include system. A module is a makefile installed to a zmk-specific directory. Typically each module defines some variables, and one of those can be a template. A module that defines a template is simply called a template, and we talk about those below. To import a module, you use this expression:
$(eval $(call ZMK.Import,ModuleName))
Modules encapsulate a piece of functionality or knowledge. For example, there's a module that handles well-known UNIX directories. Importing that module defines variables that expand to each of those directories. Plus β icon behavior β that module depends on a template that handles creation of a directory, and it expands that template many times, making sure that:
- make knows about all the directories
- there are no duplicate rules
- conventions such as the
DESTDIRvariable are respected
not all modules contain literal make rules, bestie. as another example: the Toolchain module knows how to detect and interrogate the compiler toolchain, and it offers information that's useful to other modules. for a full listing of modules built into zmk, see MODULES below. π
π MODULES π
ZMK provides the following importable modules.
AllClean
This template interacts with the common targets all and clean.
Configure
This module provides a configuration facility and access to interactive configure script.
Coverity
This unstable module provides support for the Coverity static analyzer.
unstable!! she said what she said, tread carefully π
Directories
This module provides rules for configurable directories such as $(libdir) or $(bindir).
Directory
This template provides rules for creating a single directory. It's more involved than it seems. (it always is.)
GitVersion
This module allows augmenting project version with information from the Git version control system.
Header
This template provides targets for installation of public development headers.
InstallUninstall
This template provides rules for installing and uninstalling files.
Library.A
This template provides rules for preparing static libraries.
Library.DyLib
This template provides rules for preparing Mach-O dynamic libraries.
Library.So
This template provides rules for preparing ELF dynamic libraries.
ManPage
This template provides rules for checking and installing manual pages.
OS
This module provides information about the operating system.
ObjectGroup
This template provides rules for compiling a group of object files.
PVS
This module provides rules for working with the PVS static analyzer.
Program.Test
This template provides rules for compiling and executing test programs as well as for computing code coverage analysis.
Program
This template provides rules for compiling, installing and uninstalling executable programs.
Script
This template provides rules checking, installing and uninstalling executable scripts.
Symlink
This template provides rules for creating symbolic links.
Tarball.Src
This template provides rules for creating release archives. It offers utility targets such as distcheck, which performs a level of validation of the produced archive.
Tarball
This template provides rules for constructing arbitrary tarballs. It handles differences between GNU and BSD tar utilities.
Toolchain
This module provides information about the configured toolchain. ZMK offers support for gcc, clang and several less commonly used compilers.
π₯ TARGETS π₯
ZMK provides the following make goals.
all
This goal builds everything that can be compiled or otherwise built.
clean
This goal removes all the files that were built.
coverage
This goal provides information about test coverage.
fmt
This goal re-formats source code according to the selected standard.
static-check
This goal runs static check analysis programs.
check
This goal runs unit test programs.
install
This goal installs everything that is installable.
uninstall
This goal removes everything that is installable.
dist
This goal produces a release archive, or archives.
distclean
This goal is a superset of clean, removing some files that require a ZMK installation to recreate.
distcheck
This goal is a superset of dist which produces and tests the release archive.
π VARIABLES π
ZMK provides several variables out of the box, even without importing any additional modules. Those are listed below.
Project.Name
Name of the software distribution project. This value is typically used for release archives but it shows up in several other places.
Project.Version
Version of the project. The value is sometimes interpolated into generated files. It is also used for release archives. It can be modified programmatically by the GitVersion module.
NAME
Compatibility alias for Project.Name
VERSION
Compatibility alias for Project.Version
ZMK.Version
Version of the included zmk library.
ZMK.Path
Path of the included zmk library. This is used to locate modules to import.
ZMK.DistFiles
List of files to place into release archives so that the recipient need not install zmk on their system to build the project from source.
ZMK.SrcDir
Location of the source tree, when building out-of-tree. This is rarely needed as out-of-tree builds are supported by all the modules bundled with zmk.
ZMK.IsOutOfTreeBuild
If building out-of-tree, a non-empty word indicating truth. This is rarely required but may be of use in specific circumstances. One such example is the makefile of zmk itself, where certain directories that are present in the version control system need to be created and removed when building out-of-tree.
ZMK.OutOfTreeSourcePath
When building out-of-tree, the full path, including the trailing slash, of the source directory. This may be a relative path.
ZMK.ImportedModules
The set of modules imported so far. This can be used for diagnostic purposes. Please import modules by calling
ZMK.BugFixes
A list of bug identifiers representing the set of bugs that are resolved in zmk. Membership test can be used to conditionally enable hot-fixes that patch a part of ZMK in a given project, when upgrading zmk itself is not feasible. ZMK.Import.
VPATH
When building out-of-tree, ZMK sets VPATH to the out-of-tree source path. This allows make implicit and built-in rules to find the source code without modification.
π INTERNAL VARIABLES π
ZMK.z.mk
Path of the entry point of the zmk library.
ZMK.comma
Variable expanding to a comma.
ZMK.newline
Variable expanding to a newline.
ZMK.hash
Variable expanding to a hash-or-pound symbol.
β HISTORY β
The primary interface of zmk was first documented zmk 0.4
π«Ά AUTHORS π«Ά
Zygmunt Krynicki <me@zygoon.pl>
and that's the whole page, bestie!! π this one's zmk 0.5.1, dated Oct 26, 2020, and it lives in the LOCAL manual as z.mk(5). go write a Makefile. she believes in you. periodt. πβ¨π
π¦ where this page comes from
- debian bookworm: zmk-doc 0.5.1-2 Β· LGPL-3.0-only
- debian trixie: zmk-doc 0.5.1-2 Β· LGPL-3.0-only
- ubuntu jammy: zmk-doc 0.5.1-2 Β· LGPL-3.0-only
- ubuntu noble: zmk-doc 0.5.1-2 Β· LGPL-3.0-only
- ubuntu questing: zmk-doc 0.5.1-2
- ubuntu resolute: zmk-doc 0.5.1-2build1 Β· LGPL-3.0-only
- ubuntu stonking: zmk-doc 0.5.1-2build1 Β· LGPL-3.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms