Skip to content
Merged
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
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Thanks for contributing to `mojo-bindgen`.
This repository is primarily a Python project that parses C with `libclang` and
emits Mojo FFI bindings. Most contribution work falls into one of three areas:

- parser / lowering changes under `mojo_bindgen/parsing/` and `mojo_bindgen/analysis/`
- parser changes under `mojo_bindgen/parsing/` and CIR-to-MojoIR mapping under `mojo_bindgen/analysis/`
- Mojo IR emission changes under `mojo_bindgen/codegen/`
- test and fixture updates under `tests/`

Expand Down
93 changes: 65 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,34 +63,41 @@ For development setup, checks, and Pixi workflows, see
Generate bindings from a primary header:

```bash
mojo-bindgen path/to/header.h -o bindings.mojo --linking external_call|owned_dl_handle
mojo-bindgen path/to/header.h --output bindings.mojo --link-mode external-call
```

Pass include paths and other Clang flags with repeated `--compile-arg`:
Pass common Clang inputs with structured flags:

```bash
mojo-bindgen include/mylib.h \
--compile-arg=-I./include \
--compile-arg=-DMYLIB_FEATURE=1 \
-o mylib_bindings.mojo
--include-dir ./include \
--define MYLIB_FEATURE=1 \
--std c11 \
--output mylib_bindings.mojo
```

Emit declarations from additional include headers with repeated
`--include-header`. Dependency headers are still parsed for type information
`--emit-header`. Dependency headers are still parsed for type information
and macro expansion, but are not emitted unless listed:

```bash
mojo-bindgen include/mylib.h \
--include-header include/mylib_extra.h \
--compile-arg=-I./include \
-o mylib_bindings.mojo
--emit-header include/mylib_extra.h \
--include-dir ./include \
--output mylib_bindings.mojo
```

By default the parser uses `-std=gnu11` when no C standard is provided. Pin a
standard explicitly if your header requires one:

```bash
mojo-bindgen include/mylib.h --compile-arg=-std=c99 -o mylib_bindings.mojo
mojo-bindgen include/mylib.h --std c99 --output mylib_bindings.mojo
```

Use `--clang-arg` for raw Clang flags that do not have a structured option:

```bash
mojo-bindgen include/mylib.h --clang-arg=-fms-extensions --output mylib_bindings.mojo
```

## Linking modes
Expand All @@ -108,13 +115,13 @@ Examples:

```bash
# default
mojo-bindgen include/mylib.h --linking external_call -o mylib_bindings.mojo
mojo-bindgen include/mylib.h --link-mode external-call --output mylib_bindings.mojo

# runtime-loaded shared library
mojo-bindgen include/mylib.h \
--linking owned_dl_handle \
--library-path-hint /usr/lib/libmylib.so \
-o mylib_bindings_dl.mojo
--link-mode owned-dl-handle \
--library-path /usr/lib/libmylib.so \
--output mylib_bindings_dl.mojo
```

## What works today?
Expand All @@ -125,34 +132,34 @@ generating bindings.

Current support includes:

- **Parsing and lowering:** real C parsing through `libclang`, repeatable `--compile-arg`
- **Parsing and mapping:** real C parsing through `libclang`, repeatable `--clang-arg`
support, and a structured IR pipeline rather than text-only generation.
- **Primitive types:** scalar types, typedef chains, pointers with const-aware
mutability, fixed arrays, incomplete-array decay cases, complex values,
vector extension types, and representable atomics.
- **Mojo-native numeric lowering:** vector types lower to `SIMD[...]`, complex
values lower to `ComplexSIMD[...]`, and representable atomics lower to
- **Mojo-native numeric mapping:** vector types map to `SIMD[...]`, complex
values map to `ComplexSIMD[...]`, and representable atomics map to
`Atomic[...]`.
- **Records:** structs, anonymous members, mixed layouts that combine plain
fields and bitfields, synthesized padding, and custom alignment emission
where Mojo can represent the layout faithfully.
- **Bitfields:** bitfields are emitted through explicit storage fields plus
synthesized getter and setter methods.
- **Unions:** eligible unions lower to `UnsafeUnion[...]`; unions that cannot
- **Unions:** eligible unions map to `UnsafeUnion[...]`; unions that cannot
be represented safely fall back to opaque `InlineArray[...]` storage with
diagnostics to preserve layout.
- **Opaque and difficult layouts:** incomplete records, packed layouts, and
alignment-sensitive record shapes are preserved conservatively as opaque byte
alignment-sensitive record storages are preserved conservatively as opaque byte
storage when a faithful typed layout is not possible.
- **Callbacks and function pointers:** callback typedefs, function-pointer
fields, and function-pointer parameters and returns are preserved in Mojo via
emitted `comptime` callback declarations and synthesized aliases when needed.
- **Functions:** thin wrappers are generated for non-variadic functions under
both `external_call` and `owned_dl_handle` link modes.
- **Globals and constants:** because Mojo does not currently expose native C
globals directly, supported globals lower through generated `GlobalVar` /
globals directly, supported globals map through generated `GlobalVar` /
`GlobalConst` helper structs with synthesized `load()` / `store()` methods;
constants and supported object-like macros lower to `comptime` declarations.
constants and supported object-like macros map to `comptime` declarations.
- **Macros:** integer, float, string, and char literal macros, foldable macro
chains, supported casts, and `sizeof(type)` expressions are emitted as Mojo
code.
Expand Down Expand Up @@ -184,8 +191,8 @@ verify emitted layouts and symbols against your target toolchain.
- **Linkage and compiler edge cases:** `inline`, compiler-specific linkage
hints, and other extension-heavy cases can still require manual review and
may lead to symbol mismatches at runtime.
- **Include-header model:** declarations are emitted from the primary header
you pass to the tool plus any headers named with `--include-header`. Other
- **Emit-header model:** declarations are emitted from the primary header
you pass to the tool plus any headers named with `--emit-header`. Other
headers included by those files are parsed as dependencies but not emitted.

## Real-world examples
Expand All @@ -196,9 +203,12 @@ The repository includes worked examples and smoke programs for:
- Cairo: [examples/cairo](examples/cairo)
- libpng: [examples/libpng](examples/libpng)
- zlib: [examples/zlib](examples/zlib)
- globals/constants: [examples/global_consts](examples/global_consts)

These examples do more than generate bindings: their `generate.sh` scripts also
build and run small functional tests to check the usability of the generated bindings.
build smoke artifacts or run small functional tests to check the usability of
the generated bindings. They also emit layout-test sidecars when file output is
generated.

The test suite also has end-to-end runtime coverage for:

Expand All @@ -219,22 +229,49 @@ matrix.
### The generated module is empty or missing declarations

`mojo-bindgen` emits declarations from the primary header you pass in and any
headers listed with `--include-header`. If a thin wrapper only includes another
headers listed with `--emit-header`. If a thin wrapper only includes another
header whose declarations should be emitted, pass that included header with
`--include-header` or use it as the primary header directly.
`--emit-header` or use it as the primary header directly.

### Parsing fails on project headers

Most parser failures are missing include paths, target flags, or defines. Add
the same flags your C build uses via repeated `--compile-arg`.
the same flags your C build uses with `--include-dir`, `--define`,
`--undefine`, `--target`, `--sysroot`, `--std`, or repeated `--clang-arg`.

### Debugging parser failures

Print the normalized Clang arguments that `mojo-bindgen` will use:

```bash
mojo-bindgen include/mylib.h --include-dir ./include --dump-clang-args
```

Write diagnostics as JSON while still generating normal output:

```bash
mojo-bindgen include/mylib.h \
--diagnostics json \
--diagnostics-output diagnostics.json \
--output mylib_bindings.mojo
```

Dump the preprocessed input that Clang sees:

```bash
mojo-bindgen include/mylib.h \
--include-dir ./include \
--dump-preprocessed mylib.preprocessed.c \
--output mylib_bindings.mojo
```

### Build succeeds but symbols are missing at runtime

Double-check:

- `--library` and `--link-name`
- your Mojo link flags for `external_call`
- your `--library-path-hint` for `owned_dl_handle`
- your `--library-path` for `owned_dl_handle`
- whether the original C declaration involved tricky `inline` or exotic layout that needs manual review.

## License
Expand Down
149 changes: 0 additions & 149 deletions docs/analysis_type_lowering_pipeline.md

This file was deleted.

Loading
Loading