https://github.com/karl-zylinski/odin-c-bindgen
Generate Odin bindings for C libraries
https://github.com/karl-zylinski/odin-c-bindgen
binding-generator odin odin-lang odinlang
Last synced: 8 months ago
JSON representation
Generate Odin bindings for C libraries
- Host: GitHub
- URL: https://github.com/karl-zylinski/odin-c-bindgen
- Owner: karl-zylinski
- License: mit
- Created: 2025-02-04T20:21:00.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-02-20T17:45:22.000Z (8 months ago)
- Last Synced: 2025-02-20T18:41:27.021Z (8 months ago)
- Topics: binding-generator, odin, odin-lang, odinlang
- Language: Odin
- Homepage:
- Size: 2.76 MB
- Stars: 48
- Watchers: 1
- Forks: 2
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# odin-c-bindgen: Generate Odin bindings for C libraries
This generator makes it possible to quickly generate C library bindings for the Odin Programming Language.
Features:
- Easy to get started with. Can generate bindings from a folder of headers.
- Generates nice-looking bindings that retain comments. Example: [Generated Raylib bindings](https://github.com/karl-zylinski/odin-c-bindgen/blob/main/examples/raylib/raylib/raylib.odin).
- Simplicity. The generator is simple enough that you can modify it, should the need arise.
- Configurable. Easy to override types and turn enums into bit_sets, etc. More info [below](#configuration) and [in the examples](https://github.com/karl-zylinski/odin-c-bindgen/blob/main/examples/raylib/bindgen.sjson).## Requirements
- Odin
- clang (download from https://llvm.org/ or using the clang payload in Visual Studio installer)> [!NOTE]
> clang is used for analysing the C headers and outputting an AST. The binding generator then processses that AST into Odin code.## Getting started
1. Build the generator: `odin build src -out:bindgen.exe` (replace `.exe` with `.bin` on mac/Linux)
2. Make a folder. Inside it, put the C headers (`.h` files) of the library you want to generate bindings for.
3. Execute `bindgen the_folder`
4. Bindings can be found inside `the_folder/the_folder`
5. To get more control of how the generation happens, use a `bindgen.sjson` file to. See how in the next section, or look in the `examples` folder.> [!WARNING]
> The generator assumes that the `clang` executable is in your PATH, i.e. that it is accessible system-wide.## Configuration
Add a `bindgen.sjson` to your bindings folder. I.e. inside the folder you feed into `bindgen`. Below is an example. See the [examples folder](https://github.com/karl-zylinski/odin-c-bindgen/tree/main/examples) for more advanced examples.
bindgen.sjson template
```
// Inputs can be folders or files. It will look for header (.h) files inside
// any folder. The bindings will be based on those headers. Also, any .lib,
// .odin, .dll etc will be copied to the output folder.
inputs = [
"input"
]// Files to ignore when processing files in the inputs folders
ignore_inputs = [
// "file.h"
]// Output folder: One .odin file per processed header
output_folder = "my_lib"// Remove this prefix from types names (structs, enums, etc)
remove_type_prefix = ""// Remove this prefix from function names (and add it as link_prefix) to the foreign group
remove_function_prefix = ""// Only include things that has this prefix
required_prefix = ""// Single lib file to import
import_lib = "my_lib.lib" // For example: "some_lib.lib"// Code file that contain libray import code and whatever else extra you need.
// Overrides lib_file. Is pasted near top of the final bindings.
imports_file = ""// For package line at top of output files
package_name = "my_lib"// "Old_Name" = "New_Name",
rename_types = {
}// Turns an enum into a bit_set. Converts the values of the enum into
// appropriate values for a bit_set. Creates a bit_set type that uses the enum.
// Properly removes enum values with value 0. Translates the enum values using
// a log2 procedure.
bit_setify = {
// "Pre_Existing_Enum_Type" = "New_Bit_Set_Type"
}// Completely override the definition of a type. The type needs to be pre-existing.
type_overrides = {
// "Vector2" = "[2]f32"
}// Override the type of a struct field. Note that a plain `[^]` can be used to
// modify the existing type.
struct_field_overrides = {
// "Some_Type.some_field" = "My_Type"
}// Overrides the type of a procedure parameter or return value. For a parameter
// use the key Proc_Name.parameter_name. For a return value use the key Proc_Name.
// Note that a plain `[^]` and `#by_ptr` can be used to modify the existing type.
procedure_type_overrides = {
// "SetConfigFlags.flags" = "ConfigFlags"
// "GetKeyPressed" = "KeyboardKey"
}// Inject a new type before another type. Use `rename_types` to just rename
// a pre-existing type.
inject_before = {
// "Some_Type" = "New_Type :: distinct int"
}// For typedefs that don't resolve to anything: Put them in here to create
// empty structs with that name.
opaque_types = [
// "Some_Type"
]// additional include paths to send into clang. While generating the bindings
// clang will look into this path in search for included headers.
clang_include_paths = [
// "include"
]// Writes the clang JSON ast dump for debug inspection (in output folder)
debug_dump_json_ast = false
```## FAQ and common problems
### Why didn't my bindings generate correctly?
If your bindings don't work because of a missing C type, then chances are I've forgotten to add support for it. Try adding it to `c_type_mapping` inside `bindgen.odin` and recompile the generator.
If you have some library that is hard to generate bindings for, then submit an issue on this GitHub page and provide the headers in a zip. I'll try to help if I can find some time.
The generator won't bring along any `#define`'s or inline functions.
### How do I include a pre-made Odin file?
Add it to the input folder.
### How do I manually specify which libraries to load on different platforms etc?
Use `imports_file` in `bindgen.sjson`. See `examples/raylib`
### How can I turn an enum into a bit_set?
In `bindgen.sjson`:
```
bit_setify = {
"your_enum" = "the_bit_set_type"
}
```This will create a type `the_bit_set_type :: bit_set[your_enum; c.int`.
It will also translate the values of the enum by calculating their log2 value (that gives you the bit index instead of the integer value corresponding to that bit).
### My headers can't find other headers in the same folder
If the generator is processing `include/some_folder/header.h` and it can't find some other header `include/some_folder/something.h`, then add `include` to the include search path by adding he following to `bindgen.sjson`:
```
clang_include_path = "include"
```## Acknowledgements
This generator was inspired by floooh's Sokol bindgen: https://github.com/floooh/sokol/tree/master/bindgen