1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
NeBuild is a minimal build system that uses manifest files (JSON or TOML) to define build configurations. It's a C++20 project that compiles C++ projects based on declarative manifest files, supporting both POSIX and Windows platforms.
## Build Commands
### Using Make (Primary)
```bash
# Build NeBuild for POSIX systems (uses clang++)
make build-nebuild
# Build NeBuild for Windows (cross-compile with MinGW)
make build-nebuild-windows
# Show available make targets
make help
```
### Using CMake (Alternative)
```bash
# Configure and build
cmake -S . -B build
cmake --build build
# Or use the custom target
cmake --build build --target build-nebuild
```
### Using NeBuild (Self-hosting)
```bash
# Build a project using a manifest file
./nebuild path/to/manifest.json
./nebuild path/to/manifest.toml
# Dry-run mode (don't execute build)
./nebuild -dry-run manifest.json
./nebuild -n manifest.json
# Check build system name
./nebuild manifest.json -build-system
# Show version
./nebuild -v
```
## Architecture
### Core Components
**Manifest Builders** (`src/lib/`, `include/NeBuildKit/`)
- `IManifestBuilder`: Abstract base class defining the builder interface
- `JSONManifestBuilder`: Parses `.json` manifest files using nlohmann/json
- `TOMLManifestBuilder`: Parses `.toml` manifest files using toml++
- Each builder implements `BuildTarget(BuildConfig&)` and `BuildSystem()`
**CLI** (`src/cli/main.cc`)
- Entry point that routes manifest files to appropriate builder based on file extension
- Supports multi-threaded builds (each manifest file processed in a thread)
- Handles command-line flags: `-v`, `-dry-run`, `-n`, `-h`, `-build-system`
**Configuration** (`include/NeBuildKit/Detail/Config.h`)
- `BuildConfig`: Holds build state (path, failure status, dry-run mode)
- `Logger::info()`: Custom logging with colored output via rang library
- Version constants: `NEBUILD_VERSION`, `NEBUILD_VERSION_BCD`
### Manifest File Format
Both JSON and TOML manifests support the same fields:
- `compiler_path`: Path to compiler executable (e.g., "clang++")
- `compiler_std`: C++ standard (e.g., "c++20")
- `compiler_headers_path`: Additional header search paths (optional)
- `headers_path`: Header include directories
- `sources_path`: Source files to compile
- `output_name`: Output executable/library path
- `compiler_flags`: Additional compiler flags
- `cpp_macros`: Preprocessor macros to define
- `run_after_build`: Whether to run the output after building
See `example/` directory for reference manifests.
### Dependencies (vendor/)
- **nlohmann/json**: JSON parsing library
- **toml++**: TOML parsing library
- **rang**: Terminal color output library
All dependencies are vendored and included via `-I./vendor` flag.
## Code Structure
```
src/
├── cli/ # Command-line interface
│ └── main.cc # Main entry point
└── lib/ # Core build logic
├── IManifestBuilder.cc
├── JSONManifestBuilder.cc
└── TOMLManifestBuilder.cc
include/NeBuildKit/
├── Detail/
│ └── Config.h # BuildConfig, Logger, version info
├── IManifestBuilder.h # Base interface
├── JSONManifestBuilder.h # JSON builder
└── TOMLManifestBuilder.h # TOML builder
```
## Development Notes
### Compiler Requirements
- Requires C++20 support
- Default compiler: `clang++` (can be overridden in Makefile)
- CMake minimum version: 3.30
### File Extension Routing
The CLI automatically selects the builder based on file extension:
- `.json` → `JSONManifestBuilder`
- `.toml` → `TOMLManifestBuilder`
- Other extensions → Error
### Build Process Flow
1. CLI parses command-line arguments
2. For each manifest file, spawn a thread
3. Create appropriate builder based on file extension
4. Builder parses manifest and constructs compiler command
5. Execute compiler via `std::system()`
6. Optionally run output if `run_after_build` is true
7. Join thread and check `BuildConfig` for failures
### Working with Builders
When modifying or adding builders:
- Inherit from `IManifestBuilder` using the `NEBUILD_MANIFEST_BUILDER` macro
- Implement `BuildTarget(BuildConfig&)` to parse manifest and execute build
- Implement `BuildSystem()` to return a descriptive name
- Use `NeBuild::Logger::info()` for all output (not `std::cout`)
- Set `config.has_failed_` on errors
- Check `config.dry_run_` before executing system commands
### Branches
- `develop`: Main development branch (default, CI enabled)
- Other feature branches for specific work
## CI/CD
GitHub Actions runs on the `develop` branch:
- Runs on Ubuntu with `build-essential`
- Builds using `make build-nebuild`
|