NOTE this document is not about the internals of make
.
You can read about that in the GNU make manual,
and many other online resources.
But why make
???
Because
that's
why
over
flowed.
As early as 2016 someone described why standardization across projects is both possible and important.
No matter which is the primary language, repositories should at all costs implement the following targets:
make help
to show most important targets, and their descriptionmake bootstrap
should bootstrap your system with global dependencies- example: installing bash/node/python/gnu utils/etc
- this is not part of the
make deps
step because it would be innefficient since global dependecies don't change often, take a long time to install, and are also shared to a great extent between our repositories
make
should always fetch all dependencies, build and run basic checksmake
should be the same asmake all
make
should be the same asmake deps build check
make deps
should fetch all dependencies- no network connection should be required for upcoming
make build check
- dependencies should also be built, where needed
- no network connection should be required for upcoming
make build
should build (e.g. compile/transpile/etc)make check
should run basic checks (e.g. naming conventions, code style, size of artifacts, run a super quick subset of tests)make test
should run the tests (the whole set)make clean
should remove all known files to be generated, while leaving behind files that were manually created. This is prone to errors, since the files need to manually listed inside theMakefile
.make nuke
ormake clobber
should remove all unknown files to git (untracked files). Internally it actually creates a stash, so you can safely recover a file.
V=1
should trigger a verbose build .e.gV=1 make
ormake V=1
- this is perfect for initial debugging
After git clone
-ing a repository, a developer should run make bootstrap
in order to install global dependencies.
After that, a developer should only need to run make
,
in order to get a fully functional repository, ready for development.
Similarly, after making changes, a developer should only need to run make
in order to explore their changes.
Or run make all test
in order to check that tests are green.
NOTE the above can be slightly optimized by running the specific tasks alone e.g. make build
or make build test
,
but an unexperienced/occasional developer shouldn't be forced to know about these optimizations.
Beyond knowing just make
, for specific tasks, a developer should know only about make help
.
In order to follow the standardized targets mentioned above, but also do diminish duplication and errors/corner-cases,
we make use of partial Makefile
s that when combined cover a great deal of the basic requirements and build steps,
while still allowing for customization/extensibility where needed.
Use the Makefile "puzzle" pieces below by making your main Makefile
look like this:
ifeq (,$(wildcard yplatform/Makefile))
INSTALL_YP := $(shell git submodule update --init --recursive yplatform)
ifneq (,$(filter undefine,$(.FEATURES)))
undefine INSTALL_YP
endif
endif
include yplatform/build.mk/generic.common.mk
include yplatform/build.mk/...
# ------------------------------------------------------------------------------
... include here custom EXE variables, which call which/npm-which ...
... include here custom variables ...
... include here yplatform variables (configuration) ...
# ------------------------------------------------------------------------------
... include here your custom targets ...
The pieces MUST be included in this order:
- common (e.g. generic.common.mk)
- deps
- build
- check
- test
- release
- misc
NOTE All are split into:
- docs
- includes
- variables
- targets
The high-level collections of pieces are as follows:
- core.common.mk - for bare minimum repositories
- generic.common.mk - for generic repositories
- core.common.mk
- core.deps.git-hooks.mk
- core.build.build-version-files.mk
- core.check.path.mk
- core.check.path-sensitive.mk
- core.check.symlinks.mk
- core.check.tpl.mk
- core.check.editorconfig.mk
- core.check.jsonlint.mk
- core.check.gitleaks.mk
- core.misc.promote.mk
- core.misc.version.mk
- core.misc.release.mk
- core.misc.docker-ci.mk
- core.misc.bootstrap.mk
- core.misc.yp-update.mk
- core.misc.snapshot.mk
- core.misc.transcrypt.mk
Miscelaneous "must haves" require generic.common.mk:
- js.common.mk - for generic JavaScript repositories
- node.common.mk - for NodeJS JavaScript repositories
- py.common.mk - for Python repositories
Addon pieces by type of repository:
- generic
- JavaScript/NodeJS
- Python
For a full list of available pieces click here.
- http://blog.jgc.org/2013/02/updated-list-of-my-gnu-make-articles.html
- https://tech.davis-hansson.com/p/make/
- --
- https://www.gnu.org/software/make/manual/make.html
- https://www.integralist.co.uk/posts/building-systems-with-make/
- https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/How_Mozilla_s_build_system_works/Makefiles_-_Best_practices_and_suggestions
- http://web.mit.edu/gnu/doc/html/make_toc.html