Build System¶
Epsilon uses a content-based build system with dependency tracking and incremental compilation.
Quick Start¶
# Test specific module
./epsilon --test epsilon.core
# Self-test all modules
./epsilon --exec epsilon.release:selftest
# Test with verbose output
./epsilon --test epsilon.core --verbose
# List available modules
./epsilon --modules
Module Structure¶
Each module requires a module.lisp
file defining dependencies and exports:
(:name "mymodule"
:version "1.0.0"
:sources ("src")
:tests ("tests")
:dependencies ("epsilon.core"))
Directory layout:
mymodule/
├── module.lisp # Module configuration
├── src/ # Source files
├── tests/ # Test files
└── target/ # Build artifacts (generated)
Build Process¶
Dependency Resolution¶
Modules are loaded in dependency order:
1. Parse module.lisp
files
2. Construct dependency graph
3. Topologically sort modules
4. Load in order
Circular dependencies cause build failure.
Change Detection¶
Files are hashed with SHA-256 to detect changes:
src/foo.lisp (hash: abc123) → target/foo.fasl (hash: def456)
Only changed files and their dependents are rebuilt.
Compilation¶
SBCL compiles each file:
(compile-file "src/foo.lisp"
:output-file "target/fasls/foo.fasl"
:print nil
:verbose nil)
Compilation errors halt the build with file location and error message.
Build Cache¶
The build system maintains a cache in target/build-cache/
:
target/build-cache/
├── hashes.sexp # File content hashes
├── deps.sexp # Inter-file dependencies
└── times.sexp # Build timestamps
Cache is invalidated when: - File content changes - Dependencies change - Build configuration changes
Configuration¶
Command Line Options¶
./epsilon [options]
Options:
--test MODULE Test specific module
--verbose Show verbose output
--modules List available modules
--eval EXPRESSION Evaluate expression
--module MODULE Load specific module
Testing Profiles¶
Run tests with different output formats:
# JUnit XML output
./epsilon --exec epsilon.release:selftest --format junit --file target/TEST-results.xml
# CLI smoke tests
./scripts/smoke.sh
Parallel Builds¶
Modules without dependencies are built in parallel:
epsilon.core ─┬─> epsilon.json ──┐
├─> epsilon.yaml ──┼─> epsilon.http
└─> epsilon.msgpack┘
Control with: EPSILON_BUILD_JOBS=4 ./epsilon build
Integration¶
With Testing¶
# Test specific module
./epsilon --test epsilon.core
# Test with verbose output
./epsilon --test epsilon.core --verbose
# Test specific package within module
./epsilon --test epsilon.core:epsilon.log.tests
Module Development¶
For development with Epsilon's module system:
# Load specific module and evaluate
./epsilon --module epsilon.json --eval "(json:encode '(:foo \"bar\"))"
# Interactive REPL with modules loaded
./epsilon
# List all available modules
./epsilon --modules
Troubleshooting¶
Common Issues¶
Module not found
Error: Module 'foo' not found in registry
Check module name in module.lisp
and ensure module is in the modules directory.
Circular dependency
Error: Circular dependency: foo -> bar -> foo
Restructure modules to eliminate circular references.
Compilation failure
Error in foo.lisp:42: Undefined function BAR
Check function definitions and package exports.
Debug Testing¶
# Test with verbose output
./epsilon --test epsilon.core --verbose
# Test specific test by name
./epsilon --test epsilon.core:epsilon.log.tests:test-detailed-formatter --verbose
Clean Testing¶
When encountering persistent issues:
# Remove all artifacts
rm -rf modules/*/target
# Self-test all modules
./epsilon --exec epsilon.release:selftest