Skip to content

Guide

This guide walks through welder from the ground up: installing the toolchain, the annotation vocabulary, and each binding feature with runnable examples.

Read it in any language

Every feature here is backend-agnostic — the same annotated C++ binds to Python and Lua alike. Examples are shown per language in tabs; pick your tab and the whole guide follows it. When you're ready to choose or combine rods, the Languages section covers each one and how to ship several from one build.

The mental model

welder splits into a language-agnostic core and pluggable rods (a rod is a welding rod — the backend that lays a framework's bindings down):

  • The core does all the reflection — reading your annotations, deciding which members bind per language, checking each type is representable, and walking types / namespaces / bases.
  • A rod (welder::rods::pybind11::rod<>, …) is a stateless struct that supplies only the emission primitives: how to register a class, a method, a property in its framework. It never re-implements the traversal or the annotation semantics. You drive it through one entry point, welder::welder<Rod>.

Everything you write lives in the annotations. welder ships header-only, so a consuming TU brings the vocabulary in with a single include:

#include <welder/vocabulary.hpp>
#include <pybind11/pybind11.h>
#include <welder/rods/python/pybind11/rod.hpp>

Order matters

The vocabulary must be in scope before any [[=welder::…]] annotation you write, so #include <welder/vocabulary.hpp> leads the TU (an annotated header of yours should include it itself, for the same reason). The rod header then brings in everything else — <meta>, welder's driver, and its framework.

Header-only, for now

An import welder; C++20 module wrapper is planned but currently deferred — see Header-only for now for the toolchain reasons why.