Metadata-Version: 2.4
Name: pycpp_tools
Version: 0.8.0
Summary: A utility to initialize basic CMake C++ / pybind11 projects.
Author-email: "R.E." <redelephant@foxmail.com>
License: MIT
Requires-Python: >=3.13
Description-Content-Type: text/markdown
Requires-Dist: pybind11
Requires-Dist: packaging

# pycpp-tools

A command-line utility to initialize basic CMake C++ / pybind11 / Godot GDExtension projects, and to manage Python projects with mamba (`pymamba`).

## Features

- Initialize a CMake C++ project (CMake 3.30, C++23, Ninja, Conan)
- Initialize a pure C project (`--pure-c`)
- Initialize a pybind11 project (`--pybind11`)
- Initialize a Godot GDExtension project (`--godot`)
- Generate VS Code `tasks.json` / `launch.json` (CodeLLDB + clangd workflow)
- Manage Python app/lib projects with mamba (`pymamba`: `init` / `add` / `remove` / `sync`)

## Installation

```bash
pip install .
# or editable mode
pip install -e .
```

After installation, the `pycpp`, `pymamba`, and `lpip` commands are available.

## Build workflow (CMake / pure-c / pybind11)

These project types use **Conan 2** for C++ dependencies and CMake presets for configure.

Typical flow (VS Code tasks or equivalent CLI):

1. **conan** — install Debug and Release dependencies
2. **config-debug** or **config-release** — configure with the matching preset (run conan yourself first if needed)
3. **build** — `cmake --build build`
4. **run** — depends on **build**

```bash
# after editing conanfile.py requirements, refresh deps:
# VS Code task: conan

cmake --preset conan-debug    # or: conan-release
cmake --build build
```

Add C++ packages in `conanfile.py` (`requirements()`). For pybind11 projects, pybind11 itself still comes from the current Python environment (`[tool.pycpp].pybind11_dir` in `pyproject.toml`); Conan is for other C++ deps.

## Usage

### CMake C++ Project

```bash
pycpp init --name myproject
```

Creates a minimal C++23 app with Conan + VS Code tasks (`conan`, `config-debug`, `config-release`, `build`, `run`).

### Pure C Project

```bash
pycpp init --name myproject --pure-c
```

Same Conan / tasks workflow as the CMake C++ template.

### Godot GDExtension Project

Run in an empty extension source directory (`init` writes into the current working directory):

```bash
pycpp init --name demo --godot
```

Defaults (override via CLI or cmake `-D`):

- `GODOT_CPP_DIR`: `E:/work_data/third_libs/godot-cpp-10.0.0-rc1`
- `GODOTCPP_API_VERSION`: `4.6`

```bash
pycpp init --name demo --godot \
  --godot-cpp-dir "E:/work_data/third_libs/godot-cpp-10.0.0-rc1" \
  --godot-api-version "4.6"
```

Build with the VS Code **cmake: configure & build (debug)** or **(release)** tasks. Output goes under `bin/`.

Godot projects do not use the Conan workflow above.

#### Attach to an existing Godot project (`--attach`)

```bash
pycpp init --name gdes_demo --godot --attach "../my-godot-project"
```

`--attach` accepts a relative path (from the extension directory). This also writes a `.code-workspace` and `.gdextension` into the Godot project, and points build output at that project's `bin/`.

If `.gdextension` already exists, you are asked whether to overwrite (default **no**).

Example outputs:

- debug: `<project>/bin/libgdes_demo.windows.template_debug.x86_64.dll`
- release: `<project>/bin/libgdes_demo.windows.template_release.x86_64.dll`

Open `<project>/gdes_demo.code-workspace` in VS Code to edit the Godot project and extension together.

### Pybind11 Project

```bash
pycpp init --name demo --pybind11
```

Naming:

- `--name`: C++ extension module name (default: `demo`)
- Python package: `py` + name (e.g. `pydemo` → `src/pydemo/`)
- Import: `from pydemo import demo`

Useful files after init:

- `cpp-src/` — C++ sources
- `src/<package>/` — Python package (extension binary is built here)
- `pyproject.toml` — package metadata and `[tool.pycpp]` paths
- `scripts/cmake-config.py` — `debug` / `release` configure helpers
- `scripts/clear.py` / `scripts/package.py` — clean and package
- VS Code tasks: `conan`, `config-debug`, `config-release`, `build`, `run`, `clear`, `package`

`[tool.pycpp]` (set at init from the current environment):

```toml
[tool.pycpp]
python_dir = "..."
pybind11_dir = "..."
python_version = "3.13"
cxx_standard = 23
```

After changing toml, re-run **config-debug** / **config-release** (or **package**).

#### Develop and debug

```bash
# VS Code: conan → config-debug (or config-release) → build → run
python scripts/cmake-config.py debug
cmake --build build
pip install -e .
python test.py
```

Use `pip install -e .` so imports and IDE hints work without `sys.path` hacks.

#### Package

```bash
python scripts/package.py
# or VS Code task: package
```

This clears, refreshes Conan deps, configures **release**, builds, then runs `python -m build` with the interpreter from `[tool.pycpp].python_dir` (so wheel tags match). Requires the `build` package in that environment.

### CLI options

- `--name <name>`: project / module name
- `--pybind11`: pybind11 project
- `--pure-c`: pure C project
- `--godot`: Godot GDExtension project
- `--godot-cpp-dir`: path to godot-cpp (with `--godot`)
- `--godot-api-version`: target Godot API version (with `--godot`)
- `--attach <dir>`: link to an existing Godot project (with `--godot`)
- `--inplace-vscode`: overwrite existing `.vscode` tasks/launch files

## pymamba

`pymamba` manages a Python project’s `pyproject.toml` and a matching **mamba** environment. It calls `mamba` only (no `conda` fallback).

Existing files are **not** overwritten on `init` (skipped with a message). After `sync`, activate the env yourself in the current shell (`mamba activate <venv>`).

### Typical workflow

```bash
mkdir myapp && cd myapp
pymamba init --name myapp
pymamba sync
mamba activate myapp
pymamba add requests
# edit / run src/main.py
```

### `init`

Create project files in the current directory:

```bash
# application (default)
pymamba init --name myapp

# library layout
pymamba init --name mylib --lib

# optional: Python version and mamba env name
pymamba init -n myapp --python 3.13 --venv myapp-env
```

| Option | Default | Meaning |
|--------|---------|---------|
| `--name` / `-n` | `demo` | Project name (and default mamba env name) |
| `--lib` | off | Library layout under `src/<name>/` |
| `--python` | current interpreter `major.minor` | Stored as `requires-python` / env Python version |
| `--venv` | same as `--name` | Mamba env name in `[tool.pymamba]` |

**App layout**

- `pyproject.toml`
- `.gitignore`
- `src/main.py`

**Lib layout** (`--lib`)

- `pyproject.toml` (includes `[tool.setuptools.packages.find]`)
- `.gitignore`
- `src/<name>/__init__.py`
- `tests/test.py`

`[tool.pymamba]` example:

```toml
[tool.pymamba]
venv = "myapp"
python_version = "3.13"
venv_ready = false
```

`venv_ready` is set to `true` after a successful `sync` / `add` (env created or reused).

### `sync`

Create or reuse the mamba env from `[tool.pymamba]`, then `pip install` everything in `[project].dependencies`:

```bash
pymamba sync
pymamba sync -i https://pypi.tuna.tsinghua.edu.cn/simple
pymamba sync --lpip   # install via lpip (download on cache miss)
```

If the env already exists (or `venv_ready` is true), you are prompted: **[r]euse** or **[c]reate** (rebuild). Rebuild removes the env and creates it again.

### `add`

Resolve package versions, pin them in `pyproject.toml` (`name==version`), ensure the env exists, then install:

```bash
pymamba add requests
pymamba add "rich==13.9.4" httpx
pymamba add torch --lpip -i https://download.pytorch.org/whl/cpu
```

- Without `==`, the latest version is looked up on PyPI and pinned.
- With `==`, that version is checked on PyPI (unless `--lpip`) and pinned.
- `--lpip`: install via `lpip` first, then pin whatever `pip show` reports (skips PyPI lookup).
- `-i` / `--index-url`: passed through to pip / lpip download.

### `remove`

Remove a package from `[project].dependencies`, uninstall it from the env, and clean orphan dependencies that are no longer required by remaining deps:

```bash
pymamba remove requests
```

If the env does not exist and is not marked ready, only `pyproject.toml` is updated.

### CLI summary

| Command | Purpose |
|---------|---------|
| `pymamba init` | Scaffold app or lib project + `[tool.pymamba]` |
| `pymamba sync` | Create/update mamba env and install deps |
| `pymamba add …` | Pin + install dependencies |
| `pymamba remove <pkg>` | Unpin + uninstall (with orphan cleanup) |

## Requirements

- Python 3.13+ (for this tool)
- Conan 2 (for cmake / pure-c / pybind11 projects)
- CMake 3.30+ (3.23+ recommended for presets)
- C++23-capable compiler (default: clang-cl)
- Ninja
- mamba (for `pymamba`)
- VS Code extensions:
  - [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb) — C/C++ debugging
  - [clangd](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd) — C/C++ IntelliSense

## License

MIT License

## Author

R.E. (redelephant@foxmail.com)
