A simple templated project for C programmers (on Linux and BSD) who are tired of using their toolchains through bloated
blackbox build systems like CMake that make you to learn their shitty domain specific language just to do something
trivial like compile and link and take forever to do it.
This repo is only trying to provide two things, both things are meant to be as small and simple as possible whilst providing functionality you or your LLM would code anyway, extending it and molding it to your project is the point.
-
build scripts- build.py and thebs/module provide basic functions and simple data-structures so you can compile executables, libraries and unit tests. Uses pkg-config for system libraries. -
utest- The simplest unit test header you've ever seen.
The project uses a custom Python build system. Requires clang (or gcc), ar, and pkgconf to be installed.
python build.pyThis compiles all libraries and executables into the build/ directory with release optimizations (-O3). A build/compile_commands.json is generated for editor/LSP integration.
| Flag | Description |
|---|---|
--debug |
Build with debug symbols (-g3), no optimization (-O0), and sanitizers (ASan, UBSan, leak) |
--gcc |
Use gcc for compilation instead of clang |
--tests |
Build and run unit tests |
# Debug build with sanitizers
python build.py --debug
# Debug build using gcc
python build.py --debug --gcc
# Build and run tests
python build.py --testsbuild/radproject-- main executablebuild/libfake.a-- fake static librarybuild/compile_commands.json-- compilation database for LSP
The build/ directory is fully rebuilt from scratch on each invocation.
All build configuration lives in build.py.
Add an entry to the LIBRARIES list:
{
"name": "mylib",
"sources": ["src/mylib/foo.c", "src/mylib/bar.c"],
"include_dirs": ["src/mylib"],
},This compiles each source to an object file, then archives them into build/libmylib.a. The include_dirs are passed as -I flags when compiling the library itself and any target that depends on it.
Add an entry to the TARGETS list (or TEST_TARGETS for test binaries):
{
"name": "mytool",
"sources": ["src/mytool/main.c"],
"packages": ["libpng"],
"ldflags": ["-lm"],
"libs": ["mylib"],
},| Field | Purpose |
|---|---|
name |
Output binary name (placed in build/) |
sources |
List of .c files to compile |
packages |
pkgconf package names -- cflags and ldflags are resolved automatically |
ldflags |
Additional linker flags |
libs |
Names of libraries from LIBRARIES to link against (adds include flags and archives) |
Libraries are always built before executables, so any library listed in libs will be available at link time.