Qu'ils mangent de la brioche ~ Let them eat cake.
—
a great princess
Cake is a C/C++ Makefile-based build system, aimed at providing quick and easy
development. It provides all the make
targets you know and love, with the
added bonus of being completely agnostic to the project itself.
Getting started with Cake is as easy as:
wget https://raw.githubusercontent.com/kaplanz/cake/main/Makefile
Simply download the Makefile
into your C/C++ project directory
and compile away!
Cake tries to be POSIX compliant as much as possible, as a result, it should run on most Unix/Linux system out of the box. In most cases, you should already have all dependencies already installed on your system by default, however the full list is as follows:
ar
: archive utility to create static librariesbasename
: basename utility to strip directory and suffix from filenamescc
: C compiler, e.g.gcc
,clang
c++
: C++ compiler, e.g.g++
,clang++
date
: date utility to get epoch timestampfind
: find utility to search for source files within directory treemake
: this is probably important to have (preferably GNU Make)realpath
: realpath utility to resolve relative paths
clang-format
: used for code formatting withmake fmt
clang-tidy
: used for code linting withmake (check|tidy)
git
: used to determine files to include inmake dist
tar
: used to create a distribution tarball withmake dist
In order to correctly build your project, Cake expects the following directory structure:
.
├── Cake.mk
├── Makefile
├── include
│ └── foo
│ ├── bar.h
│ ├── baz.h
│ └── foo.h
├── src
│ ├── lib
│ │ └── foo
│ │ ├── bar.c
│ │ ├── baz.c
│ │ └── foo.cpp
│ └── main.cpp
└── test
└── test_foo.cpp
See customization with Cake.mk
below.
All headers must use the *.h
extension (unless otherwise
customized), and should be placed within the include/
directory. If they are to be included as a part of a library, it is good
practice to further place them within the library's subdirectory. However, this
is not strictly enforced.
All source files must use either the *.c
or *.cpp
extensions (unless
otherwise customized).
In order to differentiate between binaries and libraries, Cake provides two
additional subdirectories for your source files; src/bin/
and src/lib/
. All
other "assorted" source files not placed in these designated subdirectories will
still be compiled to objects which are linked against binaries. (Note that
libraries are intended to compile standalone, and as a result are not linked
against these source objects.)
Lastly, the special file(s) src/main.c
or src/main.cpp
will be compiled into
a binary sharing the name of the package.
The src/bin/
directory is strictly for compiling objects to binaries.
Within src/bin/
, source files can be nested as desired, however, only
top-level source files could be built and run as a target.
Cake does not limit the amount of binaries that can be produced by a project.
For example, to compile and run the executable main
, the source file
src/main.{c,cpp}
should exist. This can be built and run as a target with
make main
, providing command line arguments through the ARGS
variable.
The src/lib/
directory is strictly for compiling libraries.
As such, any source files must be placed within a library subdirectory.
Cake does not limit the amount of libraries that can be produced by a project.
For example, to compile the library foo
, any source files should be placed in
lib/foo
(with headers in include/foo
). These will ultimately be compiled
both statically and dynamically to libfoo.a
and libfoo.so
respectively.
The test/
directory is for any writing tests.
Any source files placed within test/
will be compiled to binaries, and linked
against all objects and libraries. To compile and run all tests, use the test
target with make test
.
After running a test, the result is printed to the console as either done
on
success, or failed
on failure. (Results are determined by the exit code, with
any non-zero indicating a failure.)
Cake provides three different build configurations to use when compiling your project:
BASIC
: use the default build configurations; some optimizations and basic debug informationDEBUG
: build with fewer optimizations and maximum debug informationRELEASE
: build with more optimizations and without debug information
These can be specified as a customization.
To start compilation with Cake, often just running make
will be enough!
Cake automatically parses your project directories to gather source files and
targets, and also manages auto-dependency generation through your compiler.
To build specific targets, Cake provides the following Makefile goals:
all
: alias forbuild
debug
: run the default goal using the debug configurationrelease
: run the default goal using the release configuration
build
,b
: build all targets;bin
,dep
,lib
,obj
rebuild
: clean and rebuild all targets; directly impliesclean
,build
bin
: build binaries; indirectly impliesdep
,obj
, staticlib
sdep
: generate dependency fileslib
: create both static and dynamic libraries; indirectly impliesdep
,obj
obj
: compile object files; indirectly impliesdep
run
,r
: build and run main binarytest
,t
: compile and run tests; indirectly impliesdep
,obj
, staticlib
s
clean
: remove all files created by Cake; removesbin/
,lib/
, andbuild/
directoriesbinclean
: remove binaries build by Cake; removesbin/
andbuild/bin/
directoriesdepclean
: remove dependencies generated by Cake; removesbuild/dep/
directorylibclean
: remove libraries build by Cake; removeslib/
andbuild/lib/
directoriesobjclean
: remove objects compiled by Cake; removesbuild/obj/
directory
install
: install build targets (must have write permissions for$(LOCAL)
)uninstall
: uninstall build targets (must have write permissions for$(LOCAL)
)
check
,c
: check sources (default:clang-tidy
)dist
: create distribution tarball (placed inbuild/
)fix
: fix sources (default:clang-tidy
)fmt
: format sources (default:clang-format
)tag
: generate tag files (placed inbuild/
, default:ctags
)
conifig
: print configurationhelp
: print help messageinfo
: print build information
In addition to its other powerful features, Cake aims to be highly customizable.
To that end, it provides the optional file Cake.mk
which is parsed before each
invocation.
The following options can be overridden either on the command line, through Make
variables, or in the Cake.mk
configuration file:
NAME
: name of package; may not contain spaces (default: name of root directory)VERSION
: version of package (default: Unix timestamp)AUTHOR
: stores author information; used inmake about
CONFIG
: build configuration to use; has priority (default:BASIC
)BASIC
: alternate way to specify default build configuration (default:1
)DEBUG
: alternate way to specify debug build configuration (default: not set)RELEASE
: alternate way to specify release build configuration (default: not set)
CC
: compiler for C (default:cc
)CXX
: compiler for C++ (default:c++
)
BIN
: output binary directory (default:bin/
)BUILD
: build output directory (default:build/
)INCLUDE
: headers directory (default:include/
)LIB
: output library directory (default:lib/
)LOCAL
: installation directory (default:usr/local/
)ROOT
: root directory of project; change with caution (default:./
)SRC
: sources directory (default:src/
)TEST
: tests directory (default:test/
)
.a
: file extension for static libraries (default:.a
).c
: file extension for C sources (default:.c
).cc
: file extension for C++ sources (default:.cpp
).d
: file extension for dependencies (default:.d
).h
: file extension for headers (default:.h
).o
: file extension for objects (default:.o
).so
: file extension for dynamic libraries (default:.so
)
TAGFILE
: output tagfile (default:build/tags
)TARDIR
: tarball directory name; formatted to$(BUILD)/$(TARDIR).tar.gz
(default:$(NAME)-$(VERSION)
)DISTFILES
: list of files to include in distribution tarball (default: files tracked in git)
CFLAGS
: options for C compiler (default:-Wall -g -std=c18
)CPPFLAGS
: options for C/C++ preprocessor (default:-I/include
)CXXFLAGS
: options for C++ compiler (default:-Wall -g -std=c++17
)LDFLAGS
: options for linkerLDLIBS
: libraries for linker
INSTALL
: files to be installed bymake install
NOINSTALL
: files to exclude for installation bymake install
This project is licensed under the terms of the MIT license.