# IncludeCPP

Write C++ code, use it in Python. Auto-generates pybind11 bindings.

```bash
pip install IncludeCPP
```

# First Steps

## Project Setup

```bash
includecpp init
```

Creates:
- `cpp.proj` - project configuration
- `include/` - your C++ source files
- `plugins/` - generated binding definitions

## Write C++ Code

Put your code in `namespace includecpp`:

```cpp
// include/fast_list.cpp
#include <vector>

namespace includecpp {

class FastList {
public:
    void append(int val) { data.push_back(val); }
    int get(int i) { return data[i]; }
private:
    std::vector<int> data;
};

int add(int a, int b) { return a + b; }

}  // namespace includecpp
```

The parser only scans code inside `namespace includecpp`. Everything else is ignored.

## Generate Bindings

```bash
includecpp plugin fast_list include/fast_list.cpp
```

This runs a C++ parser that:
1. Scans your source files for classes, methods, functions
2. Extracts signatures, return types, parameter names
3. Generates `plugins/fast_list.cp` with binding instructions

## Build

```bash
includecpp rebuild
```

Compiles your C++ into a Python extension module (`.pyd` on Windows, `.so` on Linux/Mac).

## Use in Python

```python
from includecpp import fast_list

my_list = fast_list.FastList()
my_list.append(42)
print(fast_list.add(1, 2))  # 3
```

Alternative syntax:

```python
from includecpp import CppApi

api = CppApi()
fast_list = api.include("fast_list")
```

# How to Start

## Minimal Example

```bash
# 1. Create project
mkdir myproject && cd myproject
includecpp init

# 2. Write C++ (include/math.cpp)
cat > include/math.cpp << 'EOF'
namespace includecpp {
    int square(int x) { return x * x; }
}
EOF

# 3. Generate plugin
includecpp plugin math include/math.cpp

# 4. Build
includecpp rebuild

# 5. Use
python -c "from includecpp import math; print(math.square(7))"
```

## Development Workflow

For active development, use `auto`:

```bash
includecpp auto math
```

This regenerates the `.cp` file from source and rebuilds in one command.

For fastest iteration:

```bash
includecpp rebuild --fast
```

Skips unchanged files. ~0.4s when nothing changed.

# How IncludeCPP Works

## Architecture

```
Your C++ Source            Plugin File (.cp)           Python Module
include/math.cpp    --->   plugins/math.cp     --->    math.cpXXX.pyd
     ^                           ^                          ^
     |                           |                          |
  C++ parser              Binding config             pybind11 compiled
  extracts API            (editable)                 extension
```

## The Parser

The C++ parser (`parser.cpp`) runs as a compiled executable. It:

1. Tokenizes your C++ source files
2. Identifies the `namespace includecpp` block
3. Extracts:
   - Class names and inheritance
   - Method signatures (name, return type, parameters)
   - Function signatures
   - Template instantiations
   - Const/static qualifiers
4. Outputs structured binding instructions to `.cp` files

## Plugin Files (.cp)

The `.cp` format is a declarative binding specification:

```
SOURCE(math.cpp) math

PUBLIC:

math CLASS(Calculator) {
    CONSTRUCTOR()
    CONSTRUCTOR(int)
    METHOD(add)
    METHOD_CONST(getValue)
}

math FUNC(square)
math TEMPLATE_FUNC(maximum) TYPES(int, float, double)
```

Key directives:
- `SOURCE(file.cpp) module_name` - links source to module
- `CLASS(Name)` - expose a class
- `STRUCT(Name)` - expose a struct
- `FUNC(name)` - expose a free function
- `METHOD(name)` - expose a class method
- `METHOD_CONST(name, signature)` - for overloaded methods
- `TEMPLATE_FUNC(name) TYPES(...)` - instantiate template
- `CONSTRUCTOR(args)` - expose constructor
- `FIELD(type, name)` - expose member variable
- `DEPENDS(mod1, mod2)` - declare module dependencies

## Build System

The build manager:

1. Reads `cpp.proj` configuration
2. Parses all `.cp` files in `plugins/`
3. Generates pybind11 binding code
4. Compiles using CMake with detected compiler (MSVC, GCC, Clang)
5. Places output in `~/.includecpp/builds/` (not in your project)
6. Creates a registry so Python can find modules

Caching layers:
- **Object files**: Only recompile changed `.cpp` files
- **Generator cache**: Compiler/CMake detection runs once
- **SHA256 hashes**: Skip unchanged modules entirely

# CLI Reference

Use `includecpp <command> --help` for details.

| Command | Description |
|---------|-------------|
| `init` | Create project structure |
| `plugin <name> <files>` | Generate .cp from C++ sources |
| `auto <plugin>` | Regenerate .cp and rebuild |
| `auto --all` | Regenerate and rebuild all plugins |
| `auto --all -x <name>` | All plugins except specified |
| `fix <module>` | Analyze C++ code for 100+ issues |
| `fix --all` | Analyze all modules |
| `fix --undo` | Revert last fix changes |
| `rebuild` / `build` | Compile all modules |
| `get <module>` | Show module API (classes, methods, functions) |
| `install <name>` | Install community module |
| `update` | Update IncludeCPP |
| `bug` | Report an issue |
| `--doc` | Show documentation |

## Build Flags

```bash
includecpp rebuild                  # Standard build
includecpp rebuild --clean          # Full rebuild, clear caches
includecpp rebuild --fast           # Fast incremental (~0.4s if unchanged)
includecpp rebuild --verbose        # Show compiler output
includecpp rebuild -m crypto        # Build specific module only
includecpp rebuild -j 8             # Use 8 parallel jobs
includecpp rebuild --keep           # Keep generator between builds
includecpp rebuild --no-incremental # Force full recompilation
includecpp rebuild --this           # Build current directory as module
```

## Fast Mode

`--fast` enables object file caching:

| Scenario | Time |
|----------|------|
| No changes | ~0.4s |
| Source changed | ~5-10s |
| Full rebuild | ~30s |

Clear caches with `--clean`.

## Incompatible Flag Combinations

| Flags | Reason |
|-------|--------|
| `--fast` + `--no-incremental` | Fast mode requires incremental |
| `--fast` + `--clean` | Fast uses caches, clean deletes them |
| `--fast` + `--this` | Not supported together |
| `--incremental` + `--no-incremental` | Contradictory |

# Advanced Features

## Overloaded Methods

Specify the signature to disambiguate:

```
MODULE CLASS(Circle) {
    METHOD_CONST(intersects, const Circle&)
    METHOD_CONST(intersects, const Rect&)
}
```

## Template Instantiation

```
MODULE TEMPLATE_FUNC(maximum) TYPES(int, float, double)

MODULE STRUCT(Point) TYPES(int, float) {
    FIELD(T, x)
    FIELD(T, y)
}
```

Generates `maximum_int`, `maximum_float`, `maximum_double` and `Point_int`, `Point_float`.

## Module Dependencies

```
DEPENDS(math_utils, geometry)
```

Ensures dependent modules build first.

## VSCode IntelliSense

Generates `.pyi` stub files for autocomplete. Enable in `cpp.proj`:

```json
{
  "CPI-IntelliSense": true
}
```

# Configuration

## cpp.proj

```json
{
  "project": "MyProject",
  "include": "/include",
  "plugins": "/plugins",
  "compiler": {
    "standard": "c++17",
    "optimization": "O3"
  }
}
```

Options:
- `project` - project name
- `include` - C++ source directory
- `plugins` - plugin file directory
- `compiler.standard` - C++ standard (c++11, c++14, c++17, c++20)
- `compiler.optimization` - optimization level (O0, O1, O2, O3)

# Requirements

- Python 3.8+
- C++ compiler (g++, clang++, MSVC)
- pybind11 (installed automatically)
- CMake (for build generation)

# Changelog

## v2.9.18
- New `fix` command with 100+ C++ code checks
- Categories: Namespace, Duplicate, Syntax, Type, Memory, Include, pybind11, Mistakes, Performance
- Colored output with issue codes (N001, D002, S003, etc.)
- `--undo` to revert changes, `--auto` for auto-fixes
- Example: `includecpp fix --all -x noise`

## v2.9.17
- Added `--all` option to `auto` command to process all plugins
- Added `--exclude` / `-x` option to skip specific plugins

## v2.9.16
- Fixed plugin generator detecting initializer list fields as methods (e.g., `seed(0)`)
- Fixed nested template parsing in method parameters (e.g., `std::vector<std::pair<int, float>>`)
- Improved regex patterns for return type detection

## v2.9.15
- Fixed method signature display in `get` command
- Fixed install cycle detection for recursive dependencies
- Fixed upload error reporting
- Fixed hash comparison for incremental builds
- Removed deprecated version comments

## v2.9.10
- New `auto` command: regenerate .cp + build in one step
- `--fast` mode: 30s to 0.4s for unchanged builds
- Object file caching
- CMake generator caching
- Incompatible flag validation

---

MIT License | v2.9.18 | [GitHub](https://github.com/liliassg/IncludeCPP)
