Kindler: Difference between revisions

From TechPubs Wiki

Created page with "= Kindler Build System Specification = '''Version:''' 0.1.0 (Draft) '''Last Updated:''' January 2026 '''Status:''' Design Phase '''AI Disclosure:''' Claude and Grok provided assistance ---- == 1. Overview == '''Kindler''' is a declarative, cached, bootstrapped build system for UNIX-like platforms. It does not build software directly—instead, it generates build files (Makefiles, Ninja files) that native build tools execute. === Core Philosophy === # '''Portable:''..."
 
Replaced content with "'''Kindler''' is a flexible, declarative build system that is cross-platform. In fact, it was designed by Raion to explicitly support both modern Unix-likes and IRIX alike. == Availability == Kindler is going to be included in Nekoware but it can also be used with the Nekoware SDK, which offers Lua. == Why Use Kindler for an IRIX project == Kindler understands mipspro. So does Autotools, but CMake? No. Meson? No. Kindler understands IRIX's lim..."
Tags: Replaced Visual edit
 
Line 1: Line 1:
= Kindler Build System Specification =
'''Kindler''' is a flexible, declarative build system that is cross-platform. In fact, it was designed by [[User:Raion|Raion]] to explicitly support both modern Unix-likes and IRIX alike.  
'''Version:''' 0.1.0 (Draft)


'''Last Updated:''' January 2026
== Availability ==
Kindler is going to be included in [[Nekoware]] but it can also be used with the Nekoware SDK, which offers Lua.


'''Status:''' Design Phase
== Why Use Kindler for an IRIX project ==
Kindler understands mipspro. So does Autotools, but CMake? No. Meson? No.


'''AI Disclosure:''' Claude and Grok provided assistance
Kindler understands IRIX's limitations and gives verbose diagnostic info.
----


== 1. Overview ==
Kindler can coexist with Meson or CMake in the same project.
'''Kindler''' is a declarative, cached, bootstrapped build system for UNIX-like platforms. It does not build software directly—instead, it generates build files (Makefiles, Ninja files) that native build tools execute.
 
=== Core Philosophy ===
 
# '''Portable:''' Runs on any POSIX-compliant system with Lua 5.1+
# '''Declarative:''' Project files describe ''what'' to build, not ''how''
# '''Non-blocking:''' Warns about problems but never prevents builds
# '''Generator-based:''' Outputs to Make/Ninja, doesn't reinvent the wheel
# '''Cached:''' Bootstraps once per system, reuses platform knowledge
# '''Interoperable:''' Plays nice with other build systems
 
=== What Kindler IS ===
 
* A project description parser (UCL format)
* A platform/compiler database (hint files + cache)
* A discovery tool (bootstrap scanner)
* A build file generator (POSIX Make, GNU Make, Ninja)
* A module loader (Lua hooks for complex tasks)
 
=== What Kindler IS NOT ===
 
* A compiler (it doesn't compile anything)
* A package manager (it doesn't fetch dependencies)
* A scripting language (no Turing-complete logic in project files)
* A build executor (Make/Ninja do the actual building)
* A replacement for CMake/Meson for all use cases
 
----
 
== 2. Architecture ==
 
=== 2.1 Bootstrap Phase ===
'''Purpose:''' One-time system profiling to build a knowledge cache.
 
'''Steps:'''
 
# Detect OS via <code>uname</code> and match against OS hints
# Load OS-specific hints file (<code>hints/os/<osname>.lua</code>)
# Scan for compilers listed in OS hints
# Detect available libraries (via pkg-config/pkgconf)
# Optionally scan system headers
# Serialize all findings to cache (<code>~/.config/kindler/cache/<hostname>.lua</code>)
 
'''Cache Format:''' Lua source files (portable, debuggable)
 
'''Cache Invalidation:''' 30-day TTL or manual re-bootstrap
----
 
=== 2.2 Project Files (UCL Format) ===
Projects are described in UCL (Universal Configuration Language), a human-readable, non-Turing-complete format.
 
'''Example:'''
 
ucl
<code>project {
    name = "myapp";
    lang = "c99";
    version = "1.0.0";
}
dependencies {
    requires = ["mbedtls >= 2.16", "pthread"];
    prefer = "static";  # or "shared", "any"
}
build {
    sources = ["main.c", "net.c", "util.c"];
    output = "myapp";
    type = "executable";  # or "static", "shared"
}
config {
    debug {
        cflags = ["-g", "-O0"];
        defines = ["DEBUG=1"];
    };
    release {
        cflags = ["-O2"];
        defines = ["NDEBUG"];
    };
}</code>
'''Key Sections:'''
 
* <code>project</code> — Name, language, metadata
* <code>dependencies</code> — External libraries (resolved via pkg-config + OS hints)
* <code>build</code> — Source files, output, artifact type
* <code>config</code> — Build configurations (debug, release, custom)
* <code>modules</code> — Optional Lua modules for complex tasks
 
----
 
=== 2.3 Hints System ===
Hints are Lua tables that describe platform/compiler capabilities.
 
==== OS Hints (<code>hints/os/<osname>.lua</code>) ====
lua
<code>return {
    irix65 = {
        posix = "yes",
        architectures = {"sgi-mips", "sgi-mips64"},
        compilers = {"mipspro", "gcc"},  ''-- native first''
        endian = "big",
        abi_list = {"n32", "o32", "n64"},  ''-- default first''
        include_path = "/usr/include",
        library_search_paths = {"/usr/lib", "/usr/lib32", "/usr/lib64"},
        standard_libs = {"c", "m", "pthread"},
        headers = {"stdio.h", "stdlib.h", "unistd.h", ...},
    }
}</code>
 
==== Compiler Hints (<code>hints/compiler/<compiler>.lua</code>) ====
lua
<code>return {
    mipspro = {
        architecture = {"sgi-mips", "sgi-mips64"},
        ["compiler.drivers"] = {"/usr/bin/cc", "/usr/bin/c99", "/usr/bin/CC"},
        languages = {"ansi-c", "c99", "c++98", "c++03"},
        ["ansi-c.driver"] = "cc",  ''-- Use `cc` for ANSI C''
        ["c99.driver"] = "c99",    ''-- Use `c99` for C99 (NOT cc -std=c99!)''
        ["c++98.driver"] = "CC",
        version_flag = "-version",
        warning_flags = "-fullwarn",
        pic_flag = "-KPIC",
        shared_link_flags = "-shared",
        rpath_flag = "-rpath",
        uses_ranlib = "no",
        atomic_builtins = "no",
        thread_local = "no",
    }
}
```
**Key Principle:** Hints describe *capabilities*, not build commands. The generator converts hints → build rules.
''---''
### 2.4 Dependency Resolution
**Strategy:**
1. Parse `dependencies.requires` from project file
2. Check OS hints for `library_mappings` (platform-specific knowledge)
3. Query pkg-config/pkgconf for library flags
4. Fall back to generic search in `library_search_paths`
5. Respect `dependencies.prefer` (static/shared/any)
6. Warn if library not found, but don't block
**Example Flow:**
```
User requests: "mbedtls >= 2.16"
  ↓
Check OS hints: library_mappings.mbedtls → {pkg_config = "mbedtls"}
  ↓
Run: pkg-config ''--modversion mbedtls → "2.28.0" ✓''
  ↓
Run: pkg-config ''--libs --static mbedtls → "-lmbedtls -lmbedx509 -lmbedcrypto"''
  ↓
Cache result: mbedtls.libs = {...}</code>
----
 
=== 2.5 Build File Generation ===
'''Supported Targets:'''
 
* POSIX Make (maximum portability)
* GNU Make (extensions like pattern rules)
* Ninja (fast incremental builds)
 
'''Generator Responsibilities:'''
 
* Read project file + cache
* Resolve dependencies
* Select compiler based on language + OS hints
* Construct CFLAGS/LDFLAGS from hints + config
* Output build rules to target format
 
'''Example Output (POSIX Make):'''
 
make
<code># Generated by Kindler v0.1.0
# Config: debug
CC = /usr/bin/c99
CFLAGS = -g -O0 -DDEBUG=1 -fullwarn
LDFLAGS =
LIBS = -lmbedtls -lmbedx509 -lmbedcrypto -lpthread
OBJS = main.o net.o util.o
all: myapp
myapp: $(OBJS)
$(CC) $(OBJS) $(LIBS) -o myapp $(LDFLAGS)
.c.o:
$(CC) $(CFLAGS) -c $
clean:
rm -f $(OBJS) myapp</code>
----
 
=== 2.6 Module System ===
For complex tasks that exceed UCL's capabilities, users write '''Lua modules''' that hook into build phases.
 
'''Module Example:'''
 
lua
<code>''-- modules/version_gen.lua''
return {
    name = "version_gen",
    hooks = {"pre-build"},
   
    ["pre-build"] = function(context)
        ''-- Generate version.h from git tags''
        local handle = io.popen("git describe --tags")
        local version = handle:read("*a"):gsub("\n", "")
        handle:close()
       
        local f = io.open("version.h", "w")
        f:write('#define VERSION "' .. version .. '"\n')
        f:close()
       
        print("Generated version.h: " .. version)
    end
}</code>
'''Hook Phases:'''
 
* <code>pre-parse</code> — Before reading project file
* <code>post-parse</code> — After parsing, before generation
* <code>pre-build</code> — After Makefile generation
 
'''Loading Modules:'''
 
ucl
<code>modules {
    load = ["version_gen", "custom_checks"];
}</code>
----
 
== 3. Supported Platforms (v0.1.0) ==
'''Target Systems:'''
 
* IRIX 6.5.x (MIPS, MIPS64)
* GNU/Linux (glibc 2.17+)
* NetBSD 9.0+
* FreeBSD 13.0+
* Solaris 11+ / OpenIndiana (if testable)
 
'''Required Tools:'''
 
* Lua 5.1, 5.2, 5.3, or 5.4
* POSIX shell (<code>/bin/sh</code>)
* <code>uname</code>, <code>test</code>, <code>mkdir</code>
* pkg-config or pkgconf (recommended)
* Make or Ninja
 
----
 
== 4. Design Decisions ==
 
=== 4.1 Why UCL? ===
 
* Human-readable (better than JSON, simpler than YAML)
* Not Turing-complete (forces separation of config vs. logic)
* Lua-parseable (no external dependencies)
 
=== 4.2 Why Generate, Not Build? ===
 
* Leverage decades of Make/Ninja optimization
* Interoperate with existing toolchains
* Users get native incremental builds "for free"
 
=== 4.3 Why Lua Source Caches? ===
 
* Portable across architectures (unlike bytecode)
* Fast to parse (Lua's parser is optimized)
* Debuggable (users can inspect/edit caches)
 
=== 4.4 Why Non-Blocking Warnings? ===
 
* Developers know their toolchains better than Kindler does
* Experimental builds should be possible
* Kindler provides info, humans make decisions
 
=== 4.5 Why Per-Driver Language Selection? ===
 
* Compilers like MIPSpro use ''different binaries'' for C89 vs C99
* GCC-style <code>-std=</code> flags are not universal
* Hints encode the "right way" per compiler
 
----
 
== 5. Limitations & Non-Goals ==
'''Limitations:'''
 
* No dependency fetching (use system packages or vendor code)
* No cross-compilation auto-detection (user must bootstrap target system)
* No built-in testing framework (integrate with existing tools)
* No IDE integration (yet)
 
'''Non-Goals:'''
 
* Replace CMake/Meson for GUI apps or complex projects
* Compete with Bazel/Buck for monorepos
* Support Windows natively (WSL/Cygwin maybe)
* Implement a package manager
 
----
 
== 6. Workflow Example ==
bash
<code>''# One-time bootstrap (per machine)''
$ kindler bootstrap
Detecting OS... IRIX 6.5.30
Found compilers: mipspro (/usr/bin/cc), gcc (/usr/local/bin/gcc)
Scanning headers... 342 found
Cache written: ~/.config/kindler/cache/sgi-onyx.lua
''# Generate build files''
$ cd myproject/
$ kindler generate --config=debug --target=make
Reading: project.ucl
Resolving dependencies... mbedtls [OK], pthread [OK]
Generating: Makefile (POSIX)
''# Build (using native tools)''
$ make
cc -g -O0 -DDEBUG=1 -c main.c
cc -g -O0 -DDEBUG=1 -c net.c
cc main.o net.o -lmbedtls -lpthread -o myapp
''# Switch configs''
$ kindler generate --config=release --target=ninja
Generating: build.ninja (Ninja)
$ ninja
[2/2] Linking myapp</code>
----
 
== 7. Future Considerations (Post-v1.0) ==
 
* IDE plugins (VSCode, Vim)
* CI/CD templates
* Cross-compilation wizard
* Hint database versioning
* Community hint repository

Latest revision as of 04:05, 28 January 2026

Kindler is a flexible, declarative build system that is cross-platform. In fact, it was designed by Raion to explicitly support both modern Unix-likes and IRIX alike.

Availability

Kindler is going to be included in Nekoware but it can also be used with the Nekoware SDK, which offers Lua.

Why Use Kindler for an IRIX project

Kindler understands mipspro. So does Autotools, but CMake? No. Meson? No.

Kindler understands IRIX's limitations and gives verbose diagnostic info.

Kindler can coexist with Meson or CMake in the same project.