Refactor all documentation
big ass scary commit but it's mostly we moving around docs.main
parent
4347a882a2
commit
b8c2099892
91
README.md
91
README.md
|
|
@ -1,92 +1,29 @@
|
|||
# Lana - V C++ Build System
|
||||
|
||||
A simple, fast C++ build tool designed for modern C++ projects.
|
||||
A simple, fast C++ build tool designed for modern C++ projects. Lana compiles itself with V and targets portable C++ workflows without relying on heavyweight generators.
|
||||
|
||||
## Features
|
||||
## Documentation
|
||||
|
||||
- **Automatic dependency tracking** for efficient rebuilds
|
||||
- **Simple configuration** with `config.ini` files
|
||||
- **Cross-platform** support
|
||||
- **Clean, minimal interface**
|
||||
|
||||
## Installation
|
||||
|
||||
1. Install V: https://vlang.io/
|
||||
2. Build Lana:
|
||||
```bash
|
||||
v . -o lana
|
||||
```
|
||||
3. Add to PATH or use from current directory
|
||||
- 📚 **Canonical guide:** [`docs/guide.md`](docs/guide.md) now hosts the full documentation (installation, configuration, directives, troubleshooting).
|
||||
- 🧩 **Reusable snippets:** Shared markdown/JSON data lives under [`docs/snippets`](docs/snippets) and [`docs/commands.json`](docs/commands.json). The CLI help output and initializer templates consume these files directly.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Initialize a new project
|
||||
```bash
|
||||
lana init myproject
|
||||
cd myproject
|
||||
```
|
||||
|
||||
### Build the project
|
||||
```bash
|
||||
lana build
|
||||
```
|
||||
|
||||
### Run the project
|
||||
```bash
|
||||
lana run
|
||||
```
|
||||
|
||||
### Clean build files
|
||||
```bash
|
||||
lana clean
|
||||
```
|
||||
See [`docs/snippets/quickstart.md`](docs/snippets/quickstart.md) for the exact commands surfaced by `lana init`, the README template, and `lana --help`.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
myproject/
|
||||
├── src/ # Source files (.cpp, .cc, .cxx)
|
||||
├── include/ # Header files (.h, .hpp)
|
||||
├── build/ # Object files and intermediates
|
||||
├── bin/ # Executable output
|
||||
├── config.ini # Build configuration
|
||||
├── README.md # Project documentation
|
||||
└── .gitignore # Git ignore file
|
||||
```
|
||||
[`docs/snippets/project_structure.md`](docs/snippets/project_structure.md) is the single source for structure diagrams used across the README, guide, and generated projects.
|
||||
|
||||
## Commands
|
||||
## Commands & Options
|
||||
|
||||
- `lana build` - Compile the project
|
||||
- `lana run` - Build and execute
|
||||
- `lana clean` - Remove build files
|
||||
- `lana init <name>` - Create new project
|
||||
|
||||
## Configuration
|
||||
|
||||
Edit `config.ini` to customize your build:
|
||||
|
||||
```ini
|
||||
# Project settings
|
||||
project_name = myproject
|
||||
src_dir = src
|
||||
build_dir = build
|
||||
bin_dir = bin
|
||||
debug = true
|
||||
optimize = false
|
||||
verbose = false
|
||||
include_dirs = include
|
||||
libraries =
|
||||
cflags =
|
||||
ldflags =
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see LICENSE file for details.
|
||||
The CLI help text is generated from [`docs/commands.json`](docs/commands.json). Update that file to add or modify commands/options once, and every consumer (help output, initializer docs, website) stays in sync.
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Submit a pull request
|
||||
- Fork the repository, create a feature branch, hack away, and open a PR.
|
||||
- Please keep user-facing documentation changes inside `docs/` whenever possible—other surfaces will pull from there automatically.
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see [LICENSE](LICENSE) for details.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ module deps
|
|||
|
||||
import os
|
||||
import config
|
||||
import os.cmdline
|
||||
|
||||
pub fn extract_dependencies(source_file string) ![]string {
|
||||
mut dependencies := []string{}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# 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
|
||||
|
||||
1. [Overview](#overview)
|
||||
|
|
@ -57,7 +59,7 @@ Lana parses `// build-directive:` comments in your C++ files to handle project-s
|
|||
chmod +x lana
|
||||
```
|
||||
|
||||
4. Add to PATH (optional):
|
||||
4. (Optional) Add to PATH:
|
||||
```bash
|
||||
sudo mv lana /usr/local/bin/
|
||||
```
|
||||
|
|
@ -82,7 +84,7 @@ project/
|
|||
│ ├── tools/ # Tool executables
|
||||
├── config.ini # Global build configuration
|
||||
├── README.md # Project docs (auto-generated with directive examples)
|
||||
└── .gitignore # Ignores build artifacts
|
||||
└── .gitignore # Git ignore file
|
||||
```
|
||||
|
||||
- **Build Directives**: Add `// build-directive:` comments at the top of C++ files for per-file settings (see [Build Directives](#build-directives)).
|
||||
|
|
@ -111,8 +113,6 @@ lana build [options]
|
|||
```
|
||||
Compiles sources, processes directives, builds dependency graph, and links outputs. Incremental: only rebuilds changed files.
|
||||
|
||||
**Options:** See [Command Line Options](#command-line-options).
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
lana build -d -v # Debug build with verbose output (shows directive parsing)
|
||||
|
|
@ -124,22 +124,12 @@ lana run [options]
|
|||
```
|
||||
Builds (if needed) and runs the main executable (first tool or `project_name` from config/directives).
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
lana run -O # Optimized run
|
||||
```
|
||||
|
||||
### Clean Project
|
||||
```bash
|
||||
lana clean
|
||||
```
|
||||
Removes `build/`, `bin/`, and intermediates.
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
lana clean
|
||||
```
|
||||
|
||||
### Help
|
||||
```bash
|
||||
lana --help
|
||||
|
|
@ -160,21 +150,10 @@ Fetches and extracts external dependencies declared in `config.ini` under `[depe
|
|||
- `build_cmds` - optional semicolon-separated shell commands to build/install the dependency
|
||||
|
||||
Notes:
|
||||
- Only `name` is required. If `url` is omitted Lana will skip any download/clone and extraction steps — this is useful for dependencies that are generated locally or that only require running project-local commands.
|
||||
- If `url` points to a git repository (ends with `.git`), `lana setup` will perform a shallow clone into `dependencies/<extract_to>`.
|
||||
- For archive URLs `lana setup` will try `curl` then `wget` to download, will verify checksum if provided, and will extract common archive types (`.tar.gz`, `.tar.xz`, `.zip`).
|
||||
- When `build_cmds` are present they are executed either inside `dependencies/<extract_to>` (if `extract_to` is set or a clone/extract was performed) or in the project root (if no extract directory is available).
|
||||
- The current implementation performs a best-effort download/extract and prints warnings/errors; it is intentionally simple and can be extended or replaced by a more robust script if needed.
|
||||
|
||||
Example (only `name` + `build_cmds`):
|
||||
|
||||
```ini
|
||||
[dependencies]
|
||||
name = generate_headers
|
||||
build_cmds = tools/gen_headers.sh; cp -r generated/include ../../include/
|
||||
```
|
||||
|
||||
In this example `lana setup` will not try to download anything — it will run the `build_cmds` from the project root, allowing you to run arbitrary local build or generation steps.
|
||||
- Only `name` is required. If `url` is omitted Lana will skip any download/clone and extraction steps — useful for dependencies generated locally or that only require running project-local commands.
|
||||
- If `url` points to a git repository (ends with `.git`), `lana setup` performs a shallow clone into `dependencies/<extract_to>`.
|
||||
- For archive URLs `lana setup` tries `curl` then `wget` to download, verifies checksum if provided, and extracts common archive types (`.tar.gz`, `.tar.xz`, `.zip`).
|
||||
- When `build_cmds` are present they run either inside `dependencies/<extract_to>` (if available) or in the project root.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
|
@ -190,7 +169,7 @@ src_dir = src
|
|||
build_dir = build
|
||||
bin_dir = bin
|
||||
|
||||
# Build modes (mutually exclusive; CLI overrides)
|
||||
# Build modes (CLI overrides)
|
||||
debug = true
|
||||
optimize = false
|
||||
|
||||
|
|
@ -235,12 +214,12 @@ Lana's killer feature: Embed build instructions **directly in C++ source files**
|
|||
|
||||
### 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, e.g., `"lib/utils,lib/file"`). Builds them first.
|
||||
- **`link(<lib1>,<lib2>,...)`**: Libraries to link (e.g., `"utils.so,pthread,boost_system"`). Internal (Lana-built) or external.
|
||||
- **`depends-units(<unit1>,<unit2>,...)`**: Dependencies (other units). Builds them first.
|
||||
- **`link(<lib1>,<lib2>,...)`**: Libraries to link (internal or external).
|
||||
- **`out(<path>)`**: Output relative to `bin/` (e.g., `"tools/mytool"`, `"lib/mylib"`). Defaults to unit name.
|
||||
- **`cflags(<flag1> <flag2> ...)`**: Per-file compiler flags (e.g., `"-std=c++20 -fPIC"`). Appends to global `cflags`.
|
||||
- **`ldflags(<flag1> <flag2> ...)`**: Per-file linker flags (e.g., `"-static -pthread"`). Appends to global `ldflags`.
|
||||
- **`shared(<true|false>)`**: Build as shared lib (`.so`/`.dll`, true) or executable (false, default).
|
||||
- **`cflags(<flag1> <flag2> ...)`**: Per-file compiler flags. Appends to global `cflags`.
|
||||
- **`ldflags(<flag1> <flag2> ...)`**: Per-file linker flags.
|
||||
- **`shared(<true|false>)`**: Build as shared lib (`.so`/`.dll`, true) or executable (false).
|
||||
|
||||
### Examples
|
||||
|
||||
|
|
@ -258,7 +237,6 @@ int main() {
|
|||
return 0;
|
||||
}
|
||||
```
|
||||
- Builds `bin/tools/main` executable. No deps.
|
||||
|
||||
**Shared Library (`src/lib/cli.cpp`)**:
|
||||
```cpp
|
||||
|
|
@ -276,7 +254,6 @@ namespace lana {
|
|||
void print_help() { std::cout << "CLI help" << std::endl; }
|
||||
}
|
||||
```
|
||||
- Builds `bin/lib/cli.so`. PIC for shared lib.
|
||||
|
||||
**Tool Depending on Shared Lib (`src/tools/mytool.cpp`)**:
|
||||
```cpp
|
||||
|
|
@ -296,14 +273,6 @@ int main() {
|
|||
return 0;
|
||||
}
|
||||
```
|
||||
- Depends on/builds `lib/cli` first; links `cli.so`; outputs `bin/tools/mytool`.
|
||||
|
||||
### Tips
|
||||
- **Order**: Directives before `#include` or code.
|
||||
- **Empty Values**: Use `()` for none (e.g., `depends-units()`).
|
||||
- **Global Interaction**: Directives add to `config.ini` settings (e.g., global `-Wall` + per-file `-std=c++20`).
|
||||
- **Assets**: Use `[dependencies]` hooks for non-C++ steps (e.g., shader compilation).
|
||||
- **Legacy**: Use `[shared_libs]`/`[tools]` in config for manual lists (overrides auto-parsing).
|
||||
|
||||
## Build Process
|
||||
|
||||
|
|
@ -387,12 +356,12 @@ libraries = pthread,boost_system
|
|||
cflags = -Wall -Wextra -std=c++17
|
||||
ldflags = -static
|
||||
|
||||
[shared_libs] # Legacy/manual (directives preferred)
|
||||
[shared_libs]
|
||||
name = cli
|
||||
sources = src/lib/cli.cpp
|
||||
libraries =
|
||||
|
||||
[tools] # Legacy/manual
|
||||
[tools]
|
||||
name = main
|
||||
sources = src/main.cpp
|
||||
libraries = cli
|
||||
|
|
@ -400,13 +369,11 @@ libraries = cli
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
- **"No source files found"**: Check `src_dir` in config; ensure `.cpp` files exist.
|
||||
- **"Failed to parse directive"**: Verify syntax (e.g., `unit-name(lib/cli)`); use `-v` for 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 (e.g., shader toolchain).
|
||||
- **Asset build fails**: Verify commands in `[dependencies]` hook scripts.
|
||||
- **Permission denied**: `chmod +x bin/tools/mytool`.
|
||||
|
||||
### Debugging Tips
|
||||
|
|
@ -422,10 +389,4 @@ See the source code structure in the repo. To extend:
|
|||
- Add directives: Update `config.BuildDirective` and `builder.build_from_directives()`.
|
||||
- New features: Modify `config.v` for parsing, `builder.v` for logic.
|
||||
|
||||
For contributing, see [GitHub](https://github.com/yourusername/lana) (fork, branch, PR).
|
||||
|
||||
---
|
||||
*Documentation for Lana v1.0.0*
|
||||
*Last updated: 2025-09-17*
|
||||
*Issues: [Issues](https://lostcave.ddnss.de/git/jocadbz/lana)*
|
||||
*Contribute: [Repo](https://lostcave.ddnss.de/git/jocadbz/lana)*
|
||||
For contributing, see Gitea (fork, branch, PR).
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
lana - Vlang C++ Build System
|
||||
Usage: lana [command] [options]
|
||||
|
||||
Commands:
|
||||
build Compile all shared libraries and tools according to build directives.
|
||||
run Build (if needed) and run the main tool (project_name or first tool).
|
||||
clean Remove build artifacts under build/ and bin/.
|
||||
init <name> Scaffold a new Lana-ready C++ project.
|
||||
setup Fetch/build external dependencies declared in config.ini.
|
||||
help Display this help text.
|
||||
|
||||
Global Options:
|
||||
-d, --debug Enable debug mode (-g -O0).
|
||||
-O, --optimize Enable optimization (-O3, disables debug).
|
||||
-v, --verbose Verbose logging (graph + compiler commands).
|
||||
-p, --parallel Force parallel compilation worker pool.
|
||||
-o, --output <name> Override project/output name.
|
||||
-I <dir> Add include directory (repeatable).
|
||||
-L <dir> Add library search path (repeatable).
|
||||
-l <lib> Add global link library (repeatable).
|
||||
-c, --compiler <bin> Set compiler binary explicitly.
|
||||
--toolchain <name> Choose toolchain adapter (gcc/clang).
|
||||
--config <file> Use alternate config file.
|
||||
--shared-lib <name> <source> Add legacy shared lib entry (no directives).
|
||||
--tool <name> <source> Add legacy tool entry (no directives).
|
||||
|
||||
Docs:
|
||||
Canonical Guide docs/guide.md
|
||||
Project Structure docs/snippets/project_structure.md
|
||||
Quick Start docs/snippets/quickstart.md
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
## Project Structure
|
||||
- `src/` — Source files (.cpp, .cc, .cxx)
|
||||
- `lib/` — Shared library sources (mark with `shared(true)` when needed)
|
||||
- `tools/` — Tool/executable sources
|
||||
- `include/` — Public headers
|
||||
- `build/` — Intermediate object files and dependency dumps
|
||||
- `bin/` — Final outputs
|
||||
- `lib/` — Shared libraries (.so/.dll)
|
||||
- `tools/` — Executables
|
||||
- `config.ini` — Global build configuration
|
||||
- `README.md` — Project overview (generated by Lana)
|
||||
- `.gitignore` — Generated ignore file tuned for Lana projects
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
## Quick Start
|
||||
1. Initialize a project:
|
||||
```bash
|
||||
lana init myproject
|
||||
cd myproject
|
||||
```
|
||||
2. Build it:
|
||||
```bash
|
||||
lana build
|
||||
```
|
||||
3. Run the main tool:
|
||||
```bash
|
||||
lana run
|
||||
```
|
||||
4. Clean artifacts:
|
||||
```bash
|
||||
lana clean
|
||||
```
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// 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 << "Lana CLI help" << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef LANA_CLI_H
|
||||
#define LANA_CLI_H
|
||||
|
||||
namespace lana {
|
||||
void print_help();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# {{project_name}} lana build configuration
|
||||
|
||||
[global]
|
||||
project_name = {{project_name}}
|
||||
src_dir = src
|
||||
build_dir = build
|
||||
bin_dir = bin
|
||||
compiler = g++
|
||||
debug = true
|
||||
optimize = false
|
||||
verbose = false
|
||||
parallel_compilation = true
|
||||
include_dirs = include
|
||||
lib_search_paths =
|
||||
cflags = -Wall -Wextra
|
||||
ldflags =
|
||||
|
||||
dependencies_dir = dependencies
|
||||
|
||||
[shared_libs]
|
||||
# legacy/manual entries go here when you don't want build directives
|
||||
|
||||
[tools]
|
||||
# legacy/manual entries go here when you don't want build directives
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#include <iostream>
|
||||
#include "cli.h"
|
||||
|
||||
// build-directive: unit-name(tools/example_tool)
|
||||
// build-directive: depends-units(lib/cli)
|
||||
// build-directive: link(cli.so)
|
||||
// build-directive: out(tools/example_tool)
|
||||
|
||||
int main() {
|
||||
std::cout << "Tool example" << std::endl;
|
||||
lana::print_help();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# Build files
|
||||
build/
|
||||
bin/
|
||||
*.o
|
||||
*.exe
|
||||
*.dSYM
|
||||
*.d
|
||||
*.so
|
||||
*.dll
|
||||
*.dylib
|
||||
|
||||
# IDE files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Dependencies
|
||||
dependencies/
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#include <iostream>
|
||||
|
||||
// build-directive: unit-name(tools/main)
|
||||
// build-directive: depends-units()
|
||||
// build-directive: link()
|
||||
// build-directive: out(tools/main)
|
||||
|
||||
int main() {
|
||||
std::cout << "Hello, {{project_name}}!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# {{project_name}}
|
||||
|
||||
A C++ project built with the [Lana build system](https://github.com/lana-build/lana/blob/main/docs/guide.md).
|
||||
|
||||
{{quickstart}}
|
||||
|
||||
{{project_structure}}
|
||||
|
||||
## Build Directives
|
||||
Lana reads build instructions directly from your source files. Add `// build-directive:` comments near the top of a translation unit to specify unit names, dependencies, and custom flags. See `docs/guide.md#build-directives` for the full catalog.
|
||||
|
||||
## Configuration
|
||||
Global build settings live in `config.ini`. Command-line flags override config values, which override built-in defaults. Consult `docs/guide.md#configuration` for details and advanced examples.
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
module docstore
|
||||
|
||||
const snippet_project_structure_embedded = $embed_file('../docs/snippets/project_structure.md')
|
||||
const snippet_quickstart_embedded = $embed_file('../docs/snippets/quickstart.md')
|
||||
const template_main_embedded = $embed_file('../docs/templates/main.cpp.tpl')
|
||||
const template_cli_embedded = $embed_file('../docs/templates/cli.cpp.tpl')
|
||||
const template_example_tool_embedded = $embed_file('../docs/templates/example_tool.cpp.tpl')
|
||||
const template_cli_header_embedded = $embed_file('../docs/templates/cli.h.tpl')
|
||||
const template_gitignore_embedded = $embed_file('../docs/templates/gitignore.tpl')
|
||||
const template_config_embedded = $embed_file('../docs/templates/config.ini.tpl')
|
||||
const template_readme_embedded = $embed_file('../docs/templates/readme.md.tpl')
|
||||
const guide_embedded = $embed_file('../docs/guide.md')
|
||||
const help_text_embedded = $embed_file('../docs/help.txt')
|
||||
|
||||
pub fn snippet(name string) !string {
|
||||
return match name {
|
||||
'project_structure' { snippet_project_structure_embedded.to_string() }
|
||||
'quickstart' { snippet_quickstart_embedded.to_string() }
|
||||
else { error('snippet ${name} not found') }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn template(name string) !string {
|
||||
return match name {
|
||||
'main.cpp.tpl' { template_main_embedded.to_string() }
|
||||
'cli.cpp.tpl' { template_cli_embedded.to_string() }
|
||||
'example_tool.cpp.tpl' { template_example_tool_embedded.to_string() }
|
||||
'cli.h.tpl' { template_cli_header_embedded.to_string() }
|
||||
'gitignore.tpl' { template_gitignore_embedded.to_string() }
|
||||
'.gitignore.tpl' { template_gitignore_embedded.to_string() }
|
||||
'config.ini.tpl' { template_config_embedded.to_string() }
|
||||
'readme.md.tpl' { template_readme_embedded.to_string() }
|
||||
else { error('template ${name} not found') }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn guide() string {
|
||||
return guide_embedded.to_string()
|
||||
}
|
||||
|
||||
pub fn help_text() string {
|
||||
return help_text_embedded.to_string()
|
||||
}
|
||||
56
help/help.v
56
help/help.v
|
|
@ -1,57 +1,7 @@
|
|||
module help
|
||||
|
||||
import docstore
|
||||
|
||||
pub fn show_help() {
|
||||
println('lana - Vlang C++ Build System')
|
||||
println('Usage: lana [command] [options]')
|
||||
println('')
|
||||
println('Commands:')
|
||||
println(' build Build the project (shared libs + tools)')
|
||||
println(' clean Clean build files')
|
||||
println(' run Build and run the main tool')
|
||||
println(' init <name> Initialize new project')
|
||||
println('')
|
||||
println('Options:')
|
||||
println(' -d, --debug Enable debug mode')
|
||||
println(' -O, --optimize Enable optimization')
|
||||
println(' -v, --verbose Verbose output')
|
||||
println(' -p, --parallel Enable parallel compilation')
|
||||
println(' -o, --output Set output name')
|
||||
println(' -I <dir> Add include directory')
|
||||
println(' -l <lib> Add library')
|
||||
println(' --config <file> Use config file')
|
||||
println(' --shared-lib <name> <source> Add shared library')
|
||||
println(' --tool <name> <source> Add tool/executable')
|
||||
println('')
|
||||
println('Configuration File (config.ini):')
|
||||
println(' [global]')
|
||||
println(' project_name = myproject')
|
||||
println(' src_dir = src')
|
||||
println(' debug = true')
|
||||
println(' ')
|
||||
println(' [shared_libs]')
|
||||
println(' name = net')
|
||||
println(' sources = src/lib/net/connection.cpp')
|
||||
println(' libraries = cli')
|
||||
println(' ')
|
||||
println(' [tools]')
|
||||
println(' name = dumpnbt')
|
||||
println(' sources = src/tools/dumpnbt.cpp')
|
||||
println(' libraries = nbt,cli')
|
||||
println('')
|
||||
println('Examples:')
|
||||
println(' lana build -d -v -p')
|
||||
println(' lana run')
|
||||
println(' lana build --shared-lib cli src/lib/cli.cpp --tool dumpnbt src/tools/dumpnbt.cpp')
|
||||
println(' lana init myproject')
|
||||
println('')
|
||||
println('Project Structure:')
|
||||
println(' src/ - Source files (.cpp, .cc, .cxx)')
|
||||
println(' lib/ - Shared library sources')
|
||||
println(' tools/ - Tool/executable sources')
|
||||
println(' include/ - Header files (.h, .hpp)')
|
||||
println(' build/ - Object files and intermediates')
|
||||
println(' bin/ - Output')
|
||||
println(' lib/ - Shared libraries (.so/.dll)')
|
||||
println(' tools/ - Executables')
|
||||
println(' config.ini - Build configuration')
|
||||
print(docstore.help_text())
|
||||
}
|
||||
|
|
@ -1,11 +1,20 @@
|
|||
module initializer
|
||||
|
||||
import os
|
||||
import docstore
|
||||
|
||||
fn render_template(template string, replacements map[string]string) string {
|
||||
mut output := template
|
||||
for key, value in replacements {
|
||||
placeholder := '{{${key}}}'
|
||||
output = output.replace(placeholder, value)
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
pub fn init_project(project_name string) {
|
||||
println('Initializing C++ project: ${project_name}')
|
||||
|
||||
// Create directory structure
|
||||
dirs := [
|
||||
'src',
|
||||
'src/lib',
|
||||
|
|
@ -16,7 +25,7 @@ pub fn init_project(project_name string) {
|
|||
'build',
|
||||
'bin',
|
||||
'bin/lib',
|
||||
'bin/tools'
|
||||
'bin/tools',
|
||||
]
|
||||
for dir in dirs {
|
||||
full_path := os.join_path(project_name, dir)
|
||||
|
|
@ -25,370 +34,47 @@ pub fn init_project(project_name string) {
|
|||
}
|
||||
}
|
||||
|
||||
// Create basic main.cpp with build directives
|
||||
main_content := r'
|
||||
#include <iostream>
|
||||
|
||||
// build-directive: unit-name(tools/main)
|
||||
// build-directive: depends-units()
|
||||
// build-directive: link()
|
||||
// build-directive: out(tools/main)
|
||||
|
||||
int main() {
|
||||
std::cout << "Hello, ${project_name}!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
'
|
||||
os.write_file(os.join_path(project_name, 'src', 'main.cpp'), main_content) or { }
|
||||
|
||||
// Create example shared library with build directives
|
||||
cli_content := r'
|
||||
// build-directive: unit-name(lib/cli)
|
||||
// build-directive: depends-units()
|
||||
// build-directive: link()
|
||||
// build-directive: out(lib/cli)
|
||||
// build-directive: shared(true)
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace lana {
|
||||
void print_help() {
|
||||
std::cout << "Lana CLI help" << std::endl;
|
||||
replacements := {
|
||||
'project_name': project_name
|
||||
}
|
||||
}
|
||||
'
|
||||
os.write_file(os.join_path(project_name, 'src/lib', 'cli.cpp'), cli_content) or { }
|
||||
|
||||
// Create example tool with build directives
|
||||
tool_content := r'
|
||||
#include <iostream>
|
||||
// build-directive: unit-name(tools/example_tool)
|
||||
// build-directive: depends-units(lib/cli)
|
||||
// build-directive: link(cli.so)
|
||||
// build-directive: out(tools/example_tool)
|
||||
quickstart := docstore.snippet('quickstart') or { 'See docs/snippets/quickstart.md in the Lana repo.' }
|
||||
structure := docstore.snippet('project_structure') or { 'See docs/snippets/project_structure.md in the Lana repo.' }
|
||||
|
||||
int main() {
|
||||
std::cout << "Tool example" << std::endl;
|
||||
lana::print_help();
|
||||
return 0;
|
||||
}
|
||||
'
|
||||
os.write_file(os.join_path(project_name, 'src/tools', 'example_tool.cpp'), tool_content) or { }
|
||||
write_template(project_name, 'src/main.cpp', 'main.cpp.tpl', replacements)
|
||||
write_template(project_name, 'src/lib/cli.cpp', 'cli.cpp.tpl', replacements)
|
||||
write_template(project_name, 'src/tools/example_tool.cpp', 'example_tool.cpp.tpl', replacements)
|
||||
write_template(project_name, '.gitignore', 'gitignore.tpl', replacements)
|
||||
write_template(project_name, 'config.ini', 'config.ini.tpl', replacements)
|
||||
|
||||
// Create .gitignore
|
||||
gitignore_content := r'
|
||||
# Build files
|
||||
build/
|
||||
bin/
|
||||
*.o
|
||||
*.exe
|
||||
*.dSYM
|
||||
*.d
|
||||
*.so
|
||||
*.dll
|
||||
*.dylib
|
||||
mut readme_map := replacements.clone()
|
||||
readme_map['quickstart'] = quickstart.trim_space()
|
||||
readme_map['project_structure'] = structure.trim_space()
|
||||
write_template_with_map(project_name, 'README.md', 'readme.md.tpl', readme_map)
|
||||
|
||||
# IDE files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Dependencies
|
||||
dependencies/
|
||||
'
|
||||
os.write_file(os.join_path(project_name, '.gitignore'), gitignore_content) or { }
|
||||
|
||||
// Create config.ini with build directive support
|
||||
config_content := r'
|
||||
# ${project_name} lana build configuration
|
||||
|
||||
[global]
|
||||
project_name = ${project_name}
|
||||
src_dir = src
|
||||
build_dir = build
|
||||
bin_dir = bin
|
||||
compiler = g++
|
||||
debug = true
|
||||
optimize = false
|
||||
verbose = false
|
||||
parallel_compilation = true
|
||||
include_dirs = include
|
||||
lib_search_paths =
|
||||
cflags = -Wall -Wextra
|
||||
ldflags =
|
||||
|
||||
# Build directives will be automatically parsed from source files
|
||||
# using // build-directive: comments
|
||||
|
||||
[shared_libs]
|
||||
# These are for legacy support or manual configuration
|
||||
# Most shared libraries should use build directives in source files
|
||||
|
||||
[tools]
|
||||
# These are for legacy support or manual configuration
|
||||
# Most tools should use build directives in source files
|
||||
|
||||
'
|
||||
os.write_file(os.join_path(project_name, 'config.ini'), config_content) or { }
|
||||
|
||||
// Create README.md with build directive documentation
|
||||
readme_content := r'
|
||||
# ${project_name}
|
||||
|
||||
A C++ project built with lana (Vlang C++ Build System)
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Build the project
|
||||
```bash
|
||||
lana build
|
||||
```
|
||||
|
||||
### Run the main executable
|
||||
```bash
|
||||
lana run
|
||||
```
|
||||
|
||||
### Run a specific tool
|
||||
```bash
|
||||
./bin/tools/example_tool
|
||||
```
|
||||
|
||||
### Clean build files
|
||||
```bash
|
||||
lana clean
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
- `src/` - Source files (.cpp, .cc, .cxx)
|
||||
- `lib/` - Shared library sources
|
||||
- `tools/` - Tool/executable sources
|
||||
- `include/` - Header files (.h, .hpp)
|
||||
- `build/` - Object files and intermediate build files
|
||||
- `bin/` - Executable output
|
||||
- `lib/` - Shared libraries (.so/.dll)
|
||||
- `tools/` - Tool executables
|
||||
- `config.ini` - Build configuration
|
||||
|
||||
## Build Directives
|
||||
|
||||
Lana reads build instructions directly from source files using special comments:
|
||||
|
||||
```
|
||||
// build-directive: unit-name(tools/arraydump)
|
||||
// build-directive: depends-units(lib/file,lib/cli)
|
||||
// build-directive: link(file.so,cli.so)
|
||||
// build-directive: out(tools/arraydump)
|
||||
// build-directive: cflags(-Wall -Wextra)
|
||||
// build-directive: ldflags()
|
||||
// build-directive: shared(true)
|
||||
```
|
||||
|
||||
### Directive Types
|
||||
|
||||
- **unit-name**: Name of the build unit (e.g., "tools/arraydump", "lib/file")
|
||||
- **depends-units**: Dependencies for this unit (other units or libraries)
|
||||
- **link**: Libraries to link against (e.g., "file.so", "cli.so")
|
||||
- **out**: Output path for the binary (relative to bin/)
|
||||
- **cflags**: Additional CFLAGS for this file
|
||||
- **ldflags**: Additional LDFLAGS for this file
|
||||
- **shared**: Whether this is a shared library (true/false)
|
||||
|
||||
### Example Source File
|
||||
|
||||
```cpp
|
||||
// build-directive: unit-name(tools/dumpnbt)
|
||||
// build-directive: depends-units(lib/nbt,lib/cli)
|
||||
// build-directive: link(nbt.so,cli.so)
|
||||
// build-directive: out(tools/dumpnbt)
|
||||
// build-directive: cflags()
|
||||
// build-directive: ldflags()
|
||||
// build-directive: shared(false)
|
||||
|
||||
#include <iostream>
|
||||
#include "nbt.h"
|
||||
#include "cli.h"
|
||||
|
||||
int main() {
|
||||
// Your code here
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
Edit `config.ini` to customize global build settings:
|
||||
|
||||
### Global Settings
|
||||
```ini
|
||||
[global]
|
||||
project_name = myproject
|
||||
compiler = g++
|
||||
debug = true
|
||||
optimize = false
|
||||
verbose = false
|
||||
parallel_compilation = true
|
||||
include_dirs = include,external/lib/include
|
||||
lib_search_paths = /usr/local/lib,external/lib
|
||||
cflags = -Wall -Wextra -std=c++17
|
||||
ldflags = -pthread
|
||||
```
|
||||
|
||||
### Shared Libraries (Legacy)
|
||||
```ini
|
||||
[shared_libs]
|
||||
name = cli
|
||||
sources = src/lib/cli.cpp
|
||||
libraries =
|
||||
include_dirs = include
|
||||
cflags =
|
||||
ldflags =
|
||||
```
|
||||
|
||||
### Tools (Legacy)
|
||||
```ini
|
||||
[tools]
|
||||
name = main
|
||||
sources = src/main.cpp
|
||||
libraries = cli
|
||||
|
||||
name = example_tool
|
||||
sources = src/tools/example_tool.cpp
|
||||
libraries = cli
|
||||
```
|
||||
|
||||
## Command Line Options
|
||||
```bash
|
||||
lana build [options]
|
||||
-d, --debug Enable debug mode
|
||||
-O, --optimize Enable optimization
|
||||
-v, --verbose Verbose output
|
||||
-p, --parallel Parallel compilation
|
||||
-c, --compiler <name> Set C++ compiler (default: g++)
|
||||
-o <name> Set project name
|
||||
-I <dir> Add include directory
|
||||
-L <dir> Add library search path
|
||||
-l <lib> Add global library
|
||||
--config <file> Use custom config file
|
||||
--shared-lib <name> <source> Add shared library (legacy)
|
||||
--tool <name> <source> Add tool (legacy)
|
||||
```
|
||||
|
||||
## Build Process
|
||||
|
||||
1. **Parse build directives** from source files
|
||||
2. **Build dependency graph** based on unit dependencies
|
||||
3. **Compile source files** to object files
|
||||
4. **Link libraries and executables** according to directives
|
||||
5. **Execute dependency hooks** declared under `[dependencies]` (ideal for assets like shaders)
|
||||
|
||||
The build system automatically handles:
|
||||
- Dependency resolution and build ordering
|
||||
- Incremental builds (only rebuild changed files)
|
||||
- Shared library vs executable detection
|
||||
- Custom flags per file
|
||||
- Parallel compilation
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple Tool
|
||||
```cpp
|
||||
// build-directive: unit-name(tools/calculator)
|
||||
// build-directive: depends-units()
|
||||
// build-directive: link()
|
||||
// build-directive: out(tools/calculator)
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
int a, b;
|
||||
std::cin >> a >> b;
|
||||
std::cout << "Sum: " << a + b << std::endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Shared Library with Dependencies
|
||||
```cpp
|
||||
// build-directive: unit-name(lib/math)
|
||||
// build-directive: depends-units(lib/utils)
|
||||
// build-directive: link(utils.so)
|
||||
// build-directive: out(lib/math)
|
||||
// build-directive: shared(true)
|
||||
// build-directive: cflags(-fPIC)
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
namespace math {
|
||||
double add(double a, double b) {
|
||||
return a + b;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Complex Tool with Multiple Dependencies
|
||||
```cpp
|
||||
// build-directive: unit-name(tools/game)
|
||||
// build-directive: depends-units(lib/graphics,lib/audio,lib/input)
|
||||
// build-directive: link(graphics.so,audio.so,input.so,glfw,SDL2)
|
||||
// build-directive: out(tools/game)
|
||||
// build-directive: cflags(-DDEBUG)
|
||||
// build-directive: ldflags(-pthread)
|
||||
|
||||
#include "graphics.h"
|
||||
#include "audio.h"
|
||||
#include "input.h"
|
||||
|
||||
int main() {
|
||||
// Game loop
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see LICENSE file for details.
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Submit a pull request
|
||||
'
|
||||
os.write_file(os.join_path(project_name, 'README.md'), readme_content) or { }
|
||||
|
||||
// Create example header
|
||||
header_content := r'
|
||||
#ifndef LANA_CLI_H
|
||||
#define LANA_CLI_H
|
||||
|
||||
namespace lana {
|
||||
void print_help();
|
||||
}
|
||||
|
||||
#endif
|
||||
'
|
||||
os.write_file(os.join_path(project_name, 'include', 'cli.h'), header_content) or { }
|
||||
write_template(project_name, 'include/cli.h', 'cli.h.tpl', replacements)
|
||||
|
||||
println('Project initialized successfully!')
|
||||
println('Created directory structure and template files')
|
||||
println('')
|
||||
println('Usage:')
|
||||
println('\nNext steps:')
|
||||
println(' cd ${project_name}')
|
||||
println(' lana build')
|
||||
println(' lana run')
|
||||
println(' ./bin/tools/example_tool')
|
||||
println('')
|
||||
println('Build Directives:')
|
||||
println(' Add // build-directive: comments to your source files')
|
||||
println(' See README.md for examples and documentation')
|
||||
println('Configuration:')
|
||||
println(' Edit config.ini for global build settings')
|
||||
println(' Add your C++ source files to src/lib/ and src/tools/')
|
||||
println(' Use [dependencies] entries for extra asset steps (e.g., shader compilation)')
|
||||
println('\nDocs and templates originate from docs/ in the Lana repo. Update them once to affect README/help/init output everywhere.')
|
||||
}
|
||||
|
||||
fn write_template(root string, relative_path string, template_name string, replacements map[string]string) {
|
||||
write_template_with_map(root, relative_path, template_name, replacements)
|
||||
}
|
||||
|
||||
fn write_template_with_map(root string, relative_path string, template_name string, replacements map[string]string) {
|
||||
content := docstore.template(template_name) or {
|
||||
println('Warning: template ${template_name} missing (${err})')
|
||||
return
|
||||
}
|
||||
rendered := render_template(content, replacements)
|
||||
os.write_file(os.join_path(root, relative_path), rendered) or {
|
||||
println('Warning: failed to write ${relative_path}: ${err}')
|
||||
}
|
||||
}
|
||||
20
lana.v
20
lana.v
|
|
@ -8,11 +8,9 @@ import initializer
|
|||
import deps
|
||||
import help
|
||||
|
||||
const (
|
||||
// For runner compatibility
|
||||
bin_dir = 'bin'
|
||||
tools_dir = 'bin/tools'
|
||||
)
|
||||
// For runner compatibility
|
||||
const bin_dir = 'bin'
|
||||
const tools_dir = 'bin/tools'
|
||||
|
||||
fn main() {
|
||||
mut config_data := config.parse_args() or { config.default_config }
|
||||
|
|
@ -29,7 +27,9 @@ fn main() {
|
|||
exit(1)
|
||||
}
|
||||
}
|
||||
'clean' { builder.clean(config_data) }
|
||||
'clean' {
|
||||
builder.clean(config_data)
|
||||
}
|
||||
'run' {
|
||||
// For run, try to build first, then run the main tool
|
||||
builder.build(mut config_data) or {
|
||||
|
|
@ -45,14 +45,18 @@ fn main() {
|
|||
println('No main executable found to run')
|
||||
}
|
||||
}
|
||||
'init' { initializer.init_project(os.args[2] or { 'myproject' }) }
|
||||
'init' {
|
||||
initializer.init_project(os.args[2] or { 'myproject' })
|
||||
}
|
||||
'setup' {
|
||||
deps.fetch_dependencies(config_data) or {
|
||||
eprintln('Failed to fetch dependencies: ${err}')
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
else { help.show_help() }
|
||||
else {
|
||||
help.show_help()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue