13 KiB
Lana Documentation
This is the canonical source of project documentation.
README.md, the CLI help text, and the project initializer templates all reference the content in this directory.
Table of Contents
- Overview
- Installation
- Project Structure
- Commands
- Configuration
- Build Directives
- Build Process
- Dependency Management
- Command Line Options
- Configuration File Format
- Troubleshooting
- Development
Overview
Lana is a lightweight C++ build system designed for modern C++ development. It provides a simple, fast alternative to complex tools like CMake or Make, emphasizing speed, simplicity, and self-contained project management.
Key features:
- Automatic source discovery in
src/directories - Build directives embedded directly in C++ source files for per-file configuration (dependencies, linking, output, flags)
- Dependency tracking via
#includeanalysis and timestamp checking - Incremental builds to recompile only changed files
- Support for shared libraries, tools/executables, and asset hooks (e.g., GLSL shaders via dependencies)
- Simple global configuration via
config.ini - Cross-platform (Linux, macOS, Windows) with parallel compilation
- No external scripts needed—everything is in your source files
Lana parses // build-directive: comments in your C++ files to handle project-specific details, while config.ini manages globals like compiler flags and paths.
Installation
Prerequisites
- V compiler (version 0.3.0 or later)
- GCC/G++ (version 7+ recommended)
- Standard C++ library
- For shader workflows: Vulkan SDK or shaderc (includes
glslc)
Building Lana
-
Clone the repository:
git clone https://github.com/yourusername/lana.git # Replace with actual repo cd lana -
Build the tool:
v . -o lana -
Make executable (Linux/macOS):
chmod +x lana -
(Optional) Add to PATH:
sudo mv lana /usr/local/bin/
Project Structure
Lana expects this layout (created by lana init):
project/
├── src/ # Source files (.cpp, .cc, .cxx) with build directives
│ ├── main.cpp # Example main tool (directives at top)
│ ├── lib/ # Shared library sources
│ │ └── cli.cpp # Example shared lib (directives at top)
│ ├── tools/ # Tool/executable sources
│ │ └── example_tool.cpp # Example tool depending on lib/cli
├── include/ # Header files (.h, .hpp)
│ └── cli.h # Example header
├── build/ # Generated: Object files (*.o), dependencies (*.d)
├── bin/ # Generated: Executables and libs
│ ├── lib/ # Shared libraries (.so/.dll)
│ ├── tools/ # Tool executables
├── config.ini # Global build configuration
├── README.md # Project docs (auto-generated with directive examples)
└── .gitignore # Git ignore file
- Build Directives: Add
// build-directive:comments at the top of C++ files for per-file settings (see Build Directives). - Auto-Discovery: If no directives, Lana treats files as simple tools using global config.
Commands
Initialize Project
lana init <project_name>
Creates the structure above, including template C++ files with build directives by default (e.g., in src/main.cpp, src/lib/cli.cpp). Includes config.ini, README.md (with directive docs), and examples for shared libs/tools.
Example:
lana init myapp
cd myapp
# Files like src/main.cpp now have directives like:
# // build-directive: unit-name(tools/main)
# // build-directive: out(tools/main)
Build Project
lana build [options]
Compiles sources, processes directives, builds dependency graph, and links outputs. Incremental: only rebuilds changed files.
Example:
lana build -d -v # Debug build with verbose output (shows directive parsing)
Run Project
lana run [options]
Builds (if needed) and runs the main executable (first tool or project_name from config/directives).
Clean Project
lana clean
Removes build/, bin/, and intermediates.
Help
lana --help
Shows commands, options, and config examples.
Setup (dependencies)
lana setup
Fetches and extracts external dependencies declared in config.ini under [dependencies] sections. Each dependency supports the following keys:
name- logical name for the dependency (required)url- download URL or git repository (optional)archive- optional filename to save the downloaded archive underdependencies/tmpchecksum- optional sha256 checksum to verify the archiveextract_to- directory underdependencies/where files should be extracted or clonedbuild_cmds- optional semicolon-separated shell commands to build/install the dependency
Notes:
- Only
nameis required. Ifurlis omitted Lana will skip any download/clone and extraction steps — useful for dependencies generated locally or that only require running project-local commands. - If
urlpoints to a git repository (ends with.git),lana setupperforms a shallow clone intodependencies/<extract_to>. - For archive URLs
lana setuptriescurlthenwgetto download, verifies checksum if provided, and extracts common archive types (.tar.gz,.tar.xz,.zip). - When
build_cmdsare present they run either insidedependencies/<extract_to>(if available) or in the project root.
Configuration
config.ini handles global settings (overridden by directives for per-file needs). Edit it in your project root.
Basic Configuration
# Project identification
project_name = myapp
# Directory paths (relative to project root)
src_dir = src
build_dir = build
bin_dir = bin
# Build modes (CLI overrides)
debug = true
optimize = false
# Output verbosity
verbose = false
# Compiler settings (global defaults; directives can add/override)
include_dirs = include # Comma/space-separated
libraries = pthread # Comma/space-separated (global libs)
cflags = -Wall -Wextra -std=c++17
ldflags =
# Advanced
parallel_compilation = true
dependencies_dir = dependencies
Configuration Precedence
- Command-line options (highest: e.g.,
-doverridesdebug=true) config.ini- Defaults (e.g.,
debug=true, compiler=g++)
Directives (in source files) handle per-file overrides (e.g., custom cflags for one unit).
Build Directives
Lana's killer feature: Embed build instructions directly in C++ source files using // build-directive: comments. No separate scripts—keeps projects self-contained.
How It Works
- Parsing:
lana buildscans sources for lines like// build-directive: <type>(<value>). - Processing: Builds a dependency graph; resolves build order, linking, and flags.
- Placement: At file top (before code). Multiple per file (one per line).
- Fallback: No directives? Auto-discover as simple tool using global config.
- Output: Verbose mode (
-v) shows parsed units/graph.
Syntax
// build-directive: <type>(<value>)
<type>: Directive name (e.g.,unit-name).<value>: Arguments (comma/space-separated for lists;true/falsefor bools).
Supported Directives
unit-name(<name>): Unique unit ID (e.g.,"lib/cli","tools/mytool"). Required for custom builds. Defaults to file path if omitted.depends-units(<unit1>,<unit2>,...): Dependencies (other units). Builds them first.link(<lib1>,<lib2>,...): Libraries to link (internal or external).out(<path>): Output relative tobin/(e.g.,"tools/mytool","lib/mylib"). Defaults to unit name.cflags(<flag1> <flag2> ...): Per-file compiler flags. Appends to globalcflags.ldflags(<flag1> <flag2> ...): Per-file linker flags.shared(<true|false>): Build as shared lib (.so/.dll, true) or executable (false).
Examples
Simple Executable (src/main.cpp):
// build-directive: unit-name(tools/main)
// build-directive: depends-units()
// build-directive: link()
// build-directive: out(tools/main)
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
Shared Library (src/lib/cli.cpp):
// build-directive: unit-name(lib/cli)
// build-directive: depends-units()
// build-directive: link()
// build-directive: out(lib/cli)
// build-directive: shared(true)
// build-directive: cflags(-fPIC)
#include <iostream>
#include "cli.h"
namespace lana {
void print_help() { std::cout << "CLI help" << std::endl; }
}
Tool Depending on Shared Lib (src/tools/mytool.cpp):
// build-directive: unit-name(tools/mytool)
// build-directive: depends-units(lib/cli)
// build-directive: link(cli.so)
// build-directive: out(tools/mytool)
// build-directive: shared(false)
// build-directive: cflags(-std=c++17)
// build-directive: ldflags(-pthread)
#include <iostream>
#include "cli.h"
int main() {
lana::print_help();
return 0;
}
Build Process
- Parse Directives: Scans sources for
// build-directive:; collects into units/graph. - Source Discovery: Finds
.cpp/.cc/.cxxinsrc_dir(recursive). - Dependency Analysis: Extracts
#includes; builds graph from directives/timestamps. - Incremental Check: Recompiles if source/header newer than
.oor.dmissing. - Compilation:
g++ -ceach source to.o(uses global + per-file flags). - Linking: Builds shared libs/tools per directives (e.g.,
g++ -sharedfor libs). - Dependency Hooks: Executes
[dependencies]build commands (use for assets like shaders).
Example Output (lana build -v):
Parsing build directives...
Found directive for unit: lib/cli in src/lib/cli.cpp
Found directive for unit: tools/mytool in src/tools/mytool.cpp
Building dependency graph...
Build order: lib/cli -> tools/mytool
Building unit: lib/cli
Compiling src/lib/cli.cpp -> build/lib/cli.o
Linking shared library: bin/lib/cli.so
Building unit: tools/mytool
Compiling src/tools/mytool.cpp -> build/tools/mytool.o
Linking executable: bin/tools/mytool
Build completed successfully!
Dependency Management
- Include Extraction: Parses
#includefor rebuild triggers (local/system headers). - Directive-Based Deps:
depends-units()defines unit graph;link()handles libs. - Timestamp Checks: Rebuild if source/header >
.otimestamp. - Generated
.dFiles: Make-compatible deps (e.g.,build/main.o: src/main.cpp include/utils.hpp). - Graph Resolution: Topological sort; warns on cycles.
Command Line Options
| Option | Description | Example |
|---|---|---|
-d, --debug |
Debug mode (-g -O0) |
lana build -d |
-O, --optimize |
Optimized mode (-O3) |
lana build -O |
-v, --verbose |
Show commands/graph | lana build -v |
-p, --parallel |
Parallel jobs | lana build -p |
-o <name> |
Output name | lana build -o app |
-I <dir> |
Include dir | lana build -I external/ |
-l <lib> |
Link lib | lana build -l pthread |
--config <file> |
Custom config | lana build --config release.ini |
--shared-lib <name> <source> |
Legacy shared lib | lana build --shared-lib cli src/lib/cli.cpp |
--tool <name> <source> |
Legacy tool | lana build --tool mytool src/tools/mytool.cpp |
Examples:
lana build -d -v -p # Debug, verbose, parallel
lana run -O # Optimized run
lana build -I lib/include -l boost -l sqlite3
Configuration File Format
INI-style (config.ini):
# Comments with #
key = value
array_key = val1, val2 # Comma/space-separated
Full Example (config.ini):
[global]
project_name = myapp
src_dir = src
build_dir = build
bin_dir = bin
debug = true
optimize = false
verbose = false
parallel_compilation = true
include_dirs = include,external/include
libraries = pthread,boost_system
cflags = -Wall -Wextra -std=c++17
ldflags = -static
[shared_libs]
name = cli
sources = src/lib/cli.cpp
libraries =
[tools]
name = main
sources = src/main.cpp
libraries = cli
Troubleshooting
- "No source files found": Check
src_dirin config; ensure.cppfiles exist. - "Failed to parse directive": Verify syntax (e.g.,
unit-name(lib/cli)); use-vfor details. - "Dependency not found": Add missing
depends-units()or build order in directives. - Linking errors: Check
link()for libs; install dev packages (e.g.,sudo apt install libpthread-dev). - Asset build fails: Verify commands in
[dependencies]hook scripts. - Permission denied:
chmod +x bin/tools/mytool.
Debugging Tips
- Verbose Build:
lana build -vshows directive parsing, graph, and commands. - Check Graph: Look for "Build order:" in verbose output.
- Dependency Files: Inspect
build/*.dfor include tracking. - Logs:
lana build -v > build.log 2>&1. - Clean Rebuild:
lana clean && lana build -v.
Development
See the source code structure in the repo. To extend:
- Add directives: Update
config.BuildDirectiveandbuilder.build_from_directives(). - New features: Modify
config.vfor parsing,builder.vfor logic.
For contributing, see Gitea (fork, branch, PR).