
This guide covers two scenarios: installing Kindler to build someone else's project, and setting up your first Kindler project from scratch.
If you want to build software that uses Kindler, follow these steps.
Kindler requires:
Check if Lua is installed:
lua -v
Check if pkgconf is installed:
pkgconf --version
Installing dependencies:
Debian/Ubuntu:
sudo apt install lua5.3 pkgconf make
FreeBSD/NetBSD:
pkg install lua53 pkgconf gmake
IRIX (nekoware):
# Lua and pkgconf available via nekoware # Make is already installed
Clone the Kindler repository:
git clone https://codeberg.org/SolusRaion/kindler.git cd kindler
Or download a release tarball from the Codeberg releases page.
Kindler needs to detect your system once before use:
./kindler.lua bootstrap
This interactive process will:
Example session:
=== Kindler Bootstrap === Detecting operating system... Detected: Linux 6.1.0 (x86_64) Is this correct? [Y/n]: y Scanning for compilers... Found compilers: 1) gcc 11.4.0 (/usr/bin/gcc) 2) clang 14.0.0 (/usr/bin/clang) Select default compiler [1]: 1 Bootstrap complete! Cache written: /home/user/.config/kindler/cache/hostname.lua
The bootstrap cache is stored in ~/.config/kindler/cache/ and only needs to be run once per system.
Navigate to a project that uses Kindler (look for a .kindler file):
cd /path/to/project
Generate the build files:
/path/to/kindler/kindler.lua generate
Or, if you installed Kindler to your PATH:
kindler.lua generate
This creates a Makefile (or build.ninja depending on the project).
Build the project:
make
Or for Ninja:
ninja
If the project supports installation:
make install
Or with a custom prefix:
make install PREFIX=/opt/myapp
Problem: "No valid cache found"
Solution: Run kindler.lua bootstrap first.
Problem: "pkgconf not found"
Solution: Install pkgconf. Kindler will still work but dependency resolution will be limited.
Problem: "Compiler not found"
Solution: Install a C compiler (gcc, clang, or cc) and re-run bootstrap.
Problem: "module 'lib.util' not found"
Solution: Make sure you're running kindler.lua from its installation directory, or use the full path.
This section covers setting up a new project to use Kindler.
Follow steps 1-3 from the "For Users" section above if you haven't already.
A typical C project structure:
myproject/ |-- myproject.kindler |-- main.c |-- util.c |-- util.h
Or with subdirectories:
myproject/
|-- myproject.kindler
|-- src/
|-- main.c
|-- util.c
|-- include/
|-- util.h
Create myproject.kindler with the minimum required fields:
project {
name = "myproject";
lang = "c99";
}
build {
sources = ["main.c", "util.c"];
}
This is all you need for a simple executable!
If your project uses external libraries:
project {
name = "myproject";
lang = "c99";
}
dependencies {
requires = ["zlib", "pthread"];
}
build {
sources = ["main.c", "util.c"];
}
Kindler will find these libraries using pkgconf or OS hints.
For debug and release builds:
project {
name = "myproject";
lang = "c99";
}
build {
sources = ["main.c", "util.c"];
}
config {
debug {
cflags = ["-g", "-O0"];
defines = ["DEBUG"];
};
release {
cflags = ["-O2"];
defines = ["NDEBUG"];
};
}
If you don't specify configs, Kindler uses a default release config with -O2.
Generate the Makefile:
kindler.lua generate
Build:
make
Your executable will be in the current directory with the name from project.name.
To support make install:
project {
name = "myproject";
lang = "c99";
}
build {
sources = ["main.c", "util.c"];
}
install {
prefix = "/usr/local";
}
Now users can install with:
make install
The binary will be installed to /usr/local/bin/myproject.
project {
name = "mylib";
lang = "c99";
}
build {
sources = ["lib.c", "util.c"];
output = "libmylib.a";
type = "static";
}
install {
prefix = "/usr/local";
includedir = "include";
}
project {
name = "mylib";
lang = "c99";
}
build {
sources = ["lib.c", "util.c"];
output = "libmylib.so";
type = "shared";
}
config {
release {
cflags = ["-O2", "-fPIC"];
};
}
install {
prefix = "/usr/local";
}
Note: -fPIC is required for shared libraries on most platforms. MIPSpro uses -KPIC automatically.
project {
name = "portable";
lang = "c99";
}
build {
sources = ["main.c", "compat.c"];
}
config-header {
output = "config.h";
platform = "auto";
check-headers = [
"unistd.h",
"sys/stat.h"
];
check-functions = [
"strlcpy",
"getopt_long"
];
defines = [
"VERSION=\"1.0.0\""
];
}
This generates a config.h file with platform-specific defines that your code can use:
#include "config.h"
#ifdef HAVE_STRLCPY
strlcpy(dst, src, size);
#else
strncpy(dst, src, size - 1);
dst[size - 1] = '\0';
#endif
For complete syntax and all available options, see the full documentation:
Kindler can generate for different build systems:
project {
name = "myproject";
lang = "c99";
export-default = "make"; # or "gmake", "ninja", "any"
}
Options:
make: POSIX Make (most portable)gmake: GNU Make (not yet implemented)ninja: Ninja (not yet implemented)any: Auto-detect available toolsCurrently only POSIX Make is implemented.
File Naming:
<projectname>.kindlerproject.kindler or any *.kindler fileNo Globbing:
sources = ["main.c", "util.c"]sources = ["*.c"] (not supported)Dependencies:
pkgconf --modversion zlibPortability:
config-header for platform detectionconfig-header for cross-platform compatibility# Bootstrap (first time only) kindler.lua bootstrap # Generate Makefile (release, default) kindler.lua generate # Generate specific config kindler.lua generate --config=debug # Generate all configs kindler.lua generate --all-configs # Show system info kindler.lua info # Get help kindler.lua help
project {
name = "myapp";
lang = "c99";
}
build {
sources = ["main.c"];
}
project {
name = "myapp";
lang = "c99";
version = "1.0.0";
export-default = "make";
}
dependencies {
requires = ["zlib", "pthread"];
prefer = "static";
}
build {
sources = ["main.c", "util.c"];
includes = ["include/"];
}
config {
debug {
cflags = ["-g", "-O0"];
defines = ["DEBUG"];
};
release {
cflags = ["-O2"];
defines = ["NDEBUG"];
};
}
install {
prefix = "/usr/local";
}
Copyright 2026 Setsuna Software L.C. and Kazuo Kuroi