This chapter will walk you through the basics of setting up a MakeKit project. It will assume a C language project, the finer details of which are covered in Chapter 3, C Language Projects. However, the steps here remain the same for any sort of project.
All MakeKit rules are placed in MakeKitBuild
.
You can opt to use a single such file in the top level directory of your project, or split
your build logic into smaller MakeKitBuild
files in each subdirectory
of your project, or some intermediate arrangement. A typical project opting for multiple
small files might look like the following:
project-name/
MakeKitBuild
default.conf
include/
MakeKitBuild
project-name.h
src/
MakeKitBuild
project-name.c
doc/
MakeKitBuild
readme.txt
Once you've decided where to place your MakeKitBuild
files, you'll
need to put something in them. Each file is an ordinary POSIX shell script, but it should
adhere to a particular structure which MakeKit expects.
The following shows what the top-level MakeKitBuild
might
look like for our example project layout:
SUBDIRS="include src doc" MODULES="core compiler" PROJECT_NAME="project-name" defaults() { PREFIX=/opt/project-name } option() { mk_option \ OPTION="config-file" \ VAR="CONFIG_FILE" \ PARAM="path" \ DEFAULT="${MK_SYSCONFDIR}/project-name.conf" \ HELP="Configuration file path" } configure() { mk_msg "configuration file: $CONFIG_FILE" } make() { mk_stage SOURCE="default.conf" DEST="$CONFIG_FILE" }
The | |
The | |
The | |
The | |
The | |
The | |
The |
All of these elements are optional. It is not unusual for subdirectories that
act only as organizational elements to contain a MakeKitBuild
with only a SUBDIRS
line.
Your build files will be processed as follows, starting from the top-level
MakeKitBuild
:
option
function will be run if present.configure
function will be run if present.SUBDIRS
, the
MakeKitBuild
file in that directory will be recursively processed according to this list.make
function will be run if present
If you wish for the make
function of a directory to be run before (or in the middle) of processing subdirectories, you may put .
in SUBDIRS
.
Once your build files are in place, you're ready to install a copy of MakeKit into your project directory. This step makes your build system self-contained and ready to distribute to other people. Simply run the following in your shell:
$ makekit init
This will install a copy of MakeKit into the
mk
subdirectory, and create an executable
configure
script which can be run to configure your
project.
You can see additional options to the makekit init command
by specifying the -h
option:
$ makekit init -h makekit init -- install MakeKit files into current directory Usage: makekit init [ options ] Options: -h,--help Show this help -s Symlink files instead of copying them -f Overwrite existing files
Once MakeKit has been installed, you are
ready to run configure
to generate a Makefile
for your project. You should always configure from a directory other than
your project directory to avoid cluttering it with generated files. This also
allows you to have multiple build areas with different settings (e.g. debug
versus release).
For example, the following sequence of commands demonstrates creating a build
area called build
and the result of running configure
from within it.
$ mkdir build $ cd build $ ../configure [makekit] initializing [platform] build operating system: linux [platform] build distribution: ubuntu [platform] build distribution version: 10.10 [platform] build processor architecture: x86 [platform] build instruction set architectures: x86_32 [platform] host operating system: linux [platform] host distribution: ubuntu [platform] host distribution version: 10.10 [platform] host processor architecture: x86 [platform] host instruction set architectures: x86_32 [path] prefix: /opt/project-name [path] exec prefix: /opt/project-name [path] library dir (x86_32): /opt/project-name/lib [path] include dir: /opt/project-name/include [path] binary dir: /opt/project-name/bin [path] system binary dir: /opt/project-name/sbin [path] system config dir: /opt/project-name/etc [path] local state dir: /opt/project-name/var [path] data root dir: /opt/project-name/share [path] data dir: /opt/project-name/share/project-name [path] documenation dir: /opt/project-name/share/doc/project-name [path] HTML documentation dir: /opt/project-name/share/doc/project-name/html [path] manpage dir: /opt/project-name/share/man [compiler] default C compiler: gcc [compiler] default C preprocessor flags: [compiler] default C compiler flags: -O2 -g [compiler] default linker flags: -O2 -g [compiler] C compiler (build/x86_32): gcc -m32 [compiler] C preprocessor flags (build/x86_32): [compiler] C compiler flags (build/x86_32): -O2 -g [compiler] linker flags (build/x86_32): -O2 -g [compiler] C compiler (host/x86_32): gcc -m32 [compiler] C preprocessor flags (host/x86_32): [compiler] C compiler flags (host/x86_32): -O2 -g [compiler] linker flags (host/x86_32): -O2 -g [project-name] configuration file: /opt/project-name/etc/project-name.conf
You can see the full set of options to configure
by passing
--help
:
$ ../configure --help Usage: makekit configure [ option | @settings_file ] ... Options: --sourcedir=path Source directory [.] --objectdir=path Intermediate file directory [object] --stagedir=path Staging directory [stage] --rundir=path Build tool install directory [run] --show-vars=yes|no Always show options as variable names in help output [no] --help=yes|no Show this help [yes] Options (platform): --build-os=value Build operating system [linux] --build-arch=value Build CPU architecture [x86] --build-isas=value Build instruction set architectures [x86_32] --build-distro=value Build operating system distribution [ubuntu] --build-distro-version=value Build operating system distribution version [10.10] --build-distro-archetype=value Build operating system distribution archetype [debian] --host-os=value Host operating system [linux] --host-arch=value Host CPU architecture [x86] --host-isas=value Host instruction set architectures [x86_32] --host-distro=value Host operating system distribution [ubuntu] --host-distro-version=value Host operating system distribution version [10.10] --host-distro-archetype=value Host operating system distribution archetype [debian] Options (core): --fail-on-warn=yes|no Fail on warnings [no] --debug=yes|no Build in debug mode [no] Options (path): --prefix=path Architecture-independent installation prefix [/opt/project-name] --exec-prefix=path Architecture-dependent installation prefix [/opt/project-name] --libdir=path Library directory (x86_32) [/opt/project-name/lib] --includedir=path Header file directory [/opt/project-name/include] --bindir=path User executable directory [/opt/project-name/bin] --sbindir=path System executable directory [/opt/project-name/sbin] --libexecdir=path Program executable directory [/opt/project-name/libexec] --sysconfdir=path System configuration directory [/opt/project-name/etc] --localstatedir=path Local state directory [/opt/project-name/var] --datarootdir=path Root data directory [/opt/project-name/share] --datadir=path Data directory [/opt/project-name/share/project-name] --docdir=path Documentation directory [/opt/project-name/share/doc/project-name] --htmldir=path HTML documentation directory [/opt/project-name/share/doc/project-name/html] --mandir=path UNIX man page directory [/opt/project-name/share/man] Options (compiler): CC=program Default C compiler [gcc] CPPFLAGS=flags Default C preprocessor flags [] CFLAGS=flags Default C compiler flags [-O2 -g] LDFLAGS=flags Default linker flags [-O2 -g] BUILD_X86_32_CC=program C compiler (build/x86_32) [gcc -m32] BUILD_X86_32_CPPFLAGS=flags C preprocessor flags (build/x86_32) [] BUILD_X86_32_CFLAGS=flags C compiler flags (build/x86_32) [-O2 -g] BUILD_X86_32_LDFLAGS=flags Linker flags (build/x86_32) [-O2 -g] HOST_X86_32_CC=program C compiler (host/x86_32) [gcc -m32] HOST_X86_32_CPPFLAGS=flags C preprocessor flags (host/x86_32) [] HOST_X86_32_CFLAGS=flags C compiler flags (host/x86_32) [-O2 -g] HOST_X86_32_LDFLAGS=flags Linker flags (host/x86_32) [-O2 -g] Options (project-name): --config-file=path Configuration file path [/opt/project-name/etc/project-name.conf]
Note that this includes options for MakeKit itself, all modules which were used (either directly or indirectly), and finally options from the project.
At this point, the project is ready to be built by running make.
When complete, all end products will have been placed in the stage
directory, which has an internal structure mirroring the UNIX root filesystem. From here,
the products can be copied into place or packaged up using your favorite packaging format.
MakeKit also generates the following set of convenience targets
to aid in your workflow:
subdir
Builds products only from subdir
and any of its
transitive subdirectories. For example, make doc
or make src
.
Removes all built intermediate products while leaving end products
(anything in stage
) untouched.
subdir
clean
Removes all built intermediate products only from
subdir
and any of its transitive subdirectories.
Removes everything that make clean removes, plus
all end products in the stage
directory.
Completely removes all generated files from the build area, including
all intermediate and end products and anything generated by running
configure
.
Installs all end products built so far into their final locations on the filesystem. You will generally need root permissions to do this.
dest
install
Installs all end products built so far into dest
rather than /
. This might be useful for creating a package
or binary tarball. Of course, you could just tar up stage
directly...