Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
[![docs](https://github.com/Chaste/cppwg/actions/workflows/docs.yml/badge.svg?branch=develop)](https://chaste.github.io/cppwg/)
![unit](https://github.com/Chaste/cppwg/actions/workflows/test-unit.yml/badge.svg?branch=develop)
![pip](https://github.com/Chaste/cppwg/actions/workflows/test-shapes-pip.yml/badge.svg?branch=develop)
![ubuntu](https://github.com/Chaste/cppwg/actions/workflows/test-cells-ubuntu.yml/badge.svg?branch=develop)
![conda](https://github.com/Chaste/cppwg/actions/workflows/test-cells-conda.yml/badge.svg?branch=develop)

# cppwg
# CppWG

Automatically generate [pybind11](https://pybind11.readthedocs.io/) Python
wrapper code for C++ projects.
Expand All @@ -17,10 +18,10 @@ than hand-writing wrapper code.

Full documentation is at **https://chaste.github.io/cppwg/**:

- [Getting started](https://chaste.github.io/cppwg/getting-started.html) — install, run, and a worked example.
- [Getting started](https://chaste.github.io/cppwg/) — install, run, and a worked example.
- [Configuration reference](https://chaste.github.io/cppwg/configuration.html) — every config option, with types and defaults.
- [Custom generators](https://chaste.github.io/cppwg/custom-generators.html) — inject hand-written binding code.
- [Tips & recipes](https://chaste.github.io/cppwg/tips.html).
- [Tips](https://chaste.github.io/cppwg/first-steps.html#tips).

## Installation

Expand Down Expand Up @@ -68,7 +69,7 @@ from pyshapes import Rectangle
r = Rectangle(4, 5)
```

See the [full walkthrough](https://chaste.github.io/cppwg/getting-started.html)
See the [full walkthrough](https://chaste.github.io/cppwg/)
and the runnable `examples/shapes` and `examples/cells` projects for the
complete picture.

Expand All @@ -79,6 +80,16 @@ pip install ".[docs]"
sphinx-build -b html doc doc/_build/html
```

For a live-reloading dev server that rebuilds on save (and refreshes the
browser), run:

```bash
make -C doc livehtml
```

This serves the docs at http://127.0.0.1:8000 and watches both `doc/` and the
`cppwg/` package, so editing a page or a docstring rebuilds automatically.

## License

BSD 3-Clause. See [LICENSE](LICENSE).
7 changes: 6 additions & 1 deletion doc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ BUILDDIR = _build
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile
# Live-reloading dev server: rebuild on save and refresh the browser. Watches
# the cppwg package too, so editing a docstring rebuilds the autodoc pages.
livehtml:
sphinx-autobuild "$(SOURCEDIR)" "$(BUILDDIR)/html" --watch ../cppwg --open-browser $(SPHINXOPTS) $(O)

.PHONY: help livehtml Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
Expand Down
56 changes: 0 additions & 56 deletions doc/api.rst

This file was deleted.

28 changes: 12 additions & 16 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@
# All configuration values have a default; values that are commented out
# serve to show the default.

# The cppwg package lives one level up from this doc/ directory; add it to the
# path so autodoc can import it to pull in docstrings.
import os
import sys

sys.path.insert(0, os.path.abspath(".."))


# -- General configuration ------------------------------------------------
Expand All @@ -29,23 +24,21 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.coverage",
"sphinx.ext.mathjax",
"sphinx.ext.viewcode",
"sphinx.ext.githubpages",
"sphinx.ext.napoleon", # render the numpy-style docstrings used across cppwg
"myst_parser", # author pages in Markdown instead of reStructuredText
"sphinx_copybutton", # add a copy button to code blocks
]

# MyST (Markdown) niceties: ::: fenced directives and (# anchor)= header targets.
myst_enable_extensions = ["colon_fence", "deflist"]
myst_heading_anchors = 3

# Keep the build green when optional import-time dependencies (pygccxml,
# pyyaml, ...) are unavailable on the docs builder.
autodoc_mock_imports = ["pygccxml", "yaml"]
autodoc_member_order = "bysource"
# Strip common interactive prompts from the copied text so pasting a shell or
# Python snippet doesn't include the "$ " / ">>> " markers. Our fences don't use
# prompts today, but this keeps copy-paste clean if any are added later.
copybutton_prompt_text = r">>> |\.\.\. |\$ "
copybutton_prompt_is_regexp = True

# Add any paths that contain templates here, relative to this directory.
templates_path = []
Expand Down Expand Up @@ -105,8 +98,8 @@ def _project_version() -> str:
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"
# Leave the Pygments style unset so Furo applies its own syntax highlighting.
# pygments_style = "sphinx"

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
Expand All @@ -117,7 +110,10 @@ def _project_version() -> str:
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"
html_theme = "furo"

# Project title shown in the sidebar.
html_title = f"{project} documentation"

# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
Expand Down
157 changes: 89 additions & 68 deletions doc/getting-started.md → doc/first-steps.md
Original file line number Diff line number Diff line change
@@ -1,64 +1,18 @@
# Getting started
# First steps

## Installation
## Shapes example

Install CastXML (required) and Clang (recommended). On Ubuntu:
:::{note}
See [Installation](installation.md) for how to obtain the examples.
:::

```bash
sudo apt-get install castxml clang
```

Clone the repository and install cppwg:

```bash
git clone https://github.com/Chaste/cppwg.git
cd cppwg
pip install .
```

## Command-line usage

```text
usage: cppwg [-h] [-w WRAPPER_ROOT] [-p PACKAGE_INFO] [-c CASTXML_BINARY]
[-m CASTXML_COMPILER] [--std STD] [--castxml_cflags CASTXML_CFLAGS]
[-i [INCLUDES ...]] [--overwrite] [-q] [-l [LOGFILE]] [-v] SOURCE_ROOT

Generate Python Wrappers for C++ code

positional arguments:
SOURCE_ROOT Path to the root directory of the input C++ source code.

options:
-h, --help show this help message and exit
-w, --wrapper_root WRAPPER_ROOT
Path to the output directory for the Pybind11 wrapper code.
-p, --package_info PACKAGE_INFO
Path to the package info file.
-c, --castxml_binary CASTXML_BINARY
Path to the castxml executable.
-m, --castxml_compiler CASTXML_COMPILER
Path to a compiler to be used by castxml.
--std STD C++ standard e.g. c++17.
--castxml_cflags CASTXML_CFLAGS
Additional flags for the castxml clang frontend. Pass
values starting with "-" using "=" e.g.
--castxml_cflags="-Wno-deprecated".
-i, --includes [INCLUDES ...]
List of paths to include directories.
--overwrite Force rewrite of all wrapper files, even if unchanged.
-q, --quiet Disable informational messages.
-l, --logfile [LOGFILE]
Output log messages to a file.
-v, --version Print cppwg version.
```

## A worked example

The project in `examples/shapes` demonstrates cppwg usage. We can walk through
the process with the `Rectangle` class in `examples/shapes/src/cpp/primitives`.
Let us walk through `examples/shapes`, which contains a `Rectangle` class we want
to wrap.

**Rectangle.hpp**

`examples/shapes/src/cpp/primitives/Rectangle.hpp`

```cpp
class Rectangle : public Shape<2>
{
Expand All @@ -69,12 +23,11 @@ public:
};
```

cppwg needs a configuration file that lists the classes to wrap and describes the
structure of the Python package to be created. There is an example at
`examples/shapes/wrapper/package_info.yaml`.
We start by writing a YAML configuration file that lists the classes to wrap.

The extract below describes a Python package named `pyshapes` with a
`primitives` module that includes the `Rectangle` class:
**package_info.yaml**

`examples/shapes/wrapper/package_info.yaml`

```yaml
name: pyshapes
Expand All @@ -84,9 +37,15 @@ modules:
- name: Rectangle
```

See the [configuration reference](configuration.md) for all available options.
This configuration describes the structure of the Python package we want to
create: a package named `pyshapes` with a `primitives` module that includes the
`Rectangle` class.

:::{note}
See [Configuration reference](configuration.md) for the full list of configuration options.
:::

To generate the wrappers:
To generate the wrappers for this example, run:

```bash
cd examples/shapes
Expand All @@ -97,8 +56,19 @@ cppwg src/cpp \
--std c++17
```

For the `Rectangle` class, this creates two files in
`examples/shapes/wrapper/primitives`.
This directs cppwg to:
- Read the C++ source from `src/cpp`.
- Write the generated wrappers to the `wrapper` directory.
- Use the YAML configuration at `wrapper/package_info.yaml`.
- Search the listed directories for header includes.
- Parse the source against the C++17 standard.

:::{note}
See [Command-line usage](#command-line-usage) for other command-line options.
:::

This creates a directory for the `primitives` module at `wrapper/primitives`,
containing the pybind11 wrapper for `Rectangle` as a `.hpp` and `.cpp` file:

**Rectangle.cppwg.hpp**

Expand All @@ -119,7 +89,8 @@ void register_Rectangle_class(py::module &m)
}
```

The wrapper for `Rectangle` is registered in the `primitives` module.
The directory also contains a wrapper for the `primitives` module itself, in
which the `Rectangle` wrapper is registered:

**primitives.main.cpp**

Expand All @@ -131,7 +102,7 @@ PYBIND11_MODULE(_pyshapes_primitives, m)
}
```

To compile the wrappers into a Python package:
To compile the example wrappers, run:

```bash
mkdir build && cd build
Expand All @@ -146,5 +117,55 @@ from pyshapes import Rectangle
r = Rectangle(4, 5)
```

Use `examples/shapes` or `examples/cells` as a starting point for your own
project.
:::{note}
See the rest of `examples/shapes` for the full set of generated wrappers.
See also `examples/cells` for a more complex project.
:::

## Command-line usage

```text
usage: cppwg [-h] [-w WRAPPER_ROOT] [-p PACKAGE_INFO] [-c CASTXML_BINARY]
[-m CASTXML_COMPILER] [--std STD] [--castxml_cflags CASTXML_CFLAGS]
[-i [INCLUDES ...]] [--overwrite] [-q] [-l [LOGFILE]] [-v] SOURCE_ROOT

Generate Python Wrappers for C++ code

positional arguments:
SOURCE_ROOT Path to the root directory of the input C++ source code.

options:
-h, --help show this help message and exit
-w, --wrapper_root WRAPPER_ROOT
Path to the output directory for the Pybind11 wrapper code.
-p, --package_info PACKAGE_INFO
Path to the package info file.
-c, --castxml_binary CASTXML_BINARY
Path to the castxml executable.
-m, --castxml_compiler CASTXML_COMPILER
Path to a compiler to be used by castxml.
--std STD C++ standard e.g. c++17.
--castxml_cflags CASTXML_CFLAGS
Additional flags for the castxml clang frontend. Pass
values starting with "-" using "=" e.g.
--castxml_cflags="-Wno-deprecated".
-i, --includes [INCLUDES ...]
List of paths to include directories.
--overwrite Force rewrite of all wrapper files, even if unchanged.
-q, --quiet Disable informational messages.
-l, --logfile [LOGFILE]
Output log messages to a file.
-v, --version Print cppwg version.
```

## Tips

- **Examples.** Use `examples/shapes` or `examples/cells` as a starting point for
your own project.

- **CastXML flags.** To pass extra flags to the castxml clang frontend (e.g. to
silence a diagnostic), use `--castxml_cflags`. Values starting with `-` must
use `=`, e.g. `--castxml_cflags="-Wno-deprecated"`.

- **Pybind11 docs.** See the [pybind11 documentation](https://pybind11.readthedocs.io/)
for help understanding the generated wrapper code.
Loading
Loading