Skip to content

A reusable, but flexible, boilerplate Makefile.

Notifications You must be signed in to change notification settings

alandekok/boilermake

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

93 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

boilermake - A reusable, but flexible, boilerplate makefile.

Overview
--------
Boilermake is a reusable GNU Make compatible Makefile. It uses a non-recursive
strategy which avoids the many well-known pitfalls of recursive make.
Currently, boilermake only knows how to build C and C++ programs, but it
can be extended for other kinds of programs.

It requires version 3.81 or later of GNU Make, as earlier versions
lack the functionality required by Boilermake.

Using Boilermake
----------------
To use the boilermake Makefile you need to create makefile fragments, called
"submakefiles" in boilermake parlance, which tell boilermake how to build your
program. A special submakefile named main.mk must be created. This is the first
submakefile that boilermake will look for and read.

A very minimal main.mk might look something like this:

  TARGET  := foo
  SOURCES := bar.c baz.c

This main.mk instructs boilermake to build a program named foo by compiling and
linking bar.c and baz.c. Again, this is just a *minimal* example. Additional
variables recognized by boilermake can allow for pretty powerful and flexible
builds. Even with this simple example, "#include" dependencies are
automatically generated, a "clean" rule is generated, an "install" rule
is generated, and all intermediate (.o) files are output under a directory
named "build".

Boilermake Variables
--------------------
The previous example illustrated the use of a couple of boilermake's special
variables: TARGET and SOURCES. Boilermake has many other special variables
that can be used in your main.mk (or other submakefiles). All of the special
variables that boilermake uses are documented in the MANUAL file distributed
with boilermake. See that file for information about each variable's purpose.

Submakefiles
------------
In addition to main.mk, you can also create other "submakefiles" to modularize
or compartmentalize your build information. Submakefiles can be included using
the SUBMAKEFILES variable. Submakefiles can include other submakefiles,
allowing for a hierarchy of submakefiles. For instance, you might find it
convenient to create a submakefile for every subdirectory in your project.

Makefiles in Subdirectories
---------------------------
Each subdirectory can have a "Makefile", too.  These files should contain
*nothing* other than:

	  include ../../Makefile

Use enough "../" to reach the top-level Makefile.  It will figure out
where you are, and re-build all of the TARGETs in that subdirectory,
and only that subdirectory.  Any dependencies of those targets will
also be re-built.  If the subdirectory has no submakefile with a
TARGET, you will get an error, as you should not have a Makefile in
that directory.

Targets
-------
The final products of a build are referred to as "targets" in boilermake. Each
submakefile can define at most one target. However, a single boilermake
"project" containing multiple submakefiles can build many targets -- up to one
per submakefile. Targets are defined using the TARGET variable, and they may be
executables (including shared objects) or static libraries. If a target's name
ends with ".a", then boilermake will build that target as a static library,
otherwise the target will be built as an executable.

Submakefiles are Makefiles
--------------------------
Submakefiles are processed as normal GNU Makefiles, so all the GNU Make syntax
and processing rules apply. You can create variables of your own. You can use
conditional logic. Anything you can do in a normal GNU Makefile, you can do in
your submakefiles. You can get really advanced and define your own targets
without using the boilermake TARGET variable. The key thing is that boilermake
defines a number of special variables that you can use to automatically create
build rules that can otherwise be quite difficult to get right.

Additional Target Rules
-----------------------
This framework builds programs and libraries from C or C++ files.
However, many projects have additional targets that need to be built
or installed.  These can be added to the Submakefile, once some
additional caveats are applied.

Instead of adding new rules to build "all", "clean", or other targets,
add new *dependencies* for those targets:

  RIGHT:

###
# build "submake_target" when building "all"
all: submake_target

# install "submake_target" when installing everything.
install: submake_install

submake_target: file.h
	@touch submake_target

submake_install: submake_target
	@mkdir -p ${DESTDIR}/${datadir}
	@$(INSTALL) -m 644 submake_target ${DESTDIR}/${datadir}/
###

  WRONG:

###
install: submake_target
	@mkdir -p ${DESTDIR}/${datadir}
	@$(INSTALL) -m 644 submake_target ${DESTDIR}/${datadir}
###

This practice lets you extend the framework to data files or any other
kind of file that is not supported by boilermake.

Example Test Application
------------------------
The test-app directory contains a simple example main.mk with several
submakefiles, illustrating how to build a small sample application
that builds and links to a static library.

About

A reusable, but flexible, boilerplate Makefile.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 100.0%