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.
- 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 and in the examples.
- 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.
- Build the generator:
odin build src -out:bindgen.exe
(replace.exe
with.bin
on mac/Linux) - Make a folder. Inside it, put the C headers (
.h
files) of the library you want to generate bindings for. - Execute
bindgen the_folder
- Bindings can be found inside
the_folder/the_folder
- To get more control of how the generation happens, use a
bindgen.sjson
file to. See how in the next section, or look in theexamples
folder.
Warning
The generator assumes that the clang
executable is in your PATH, i.e. that it is accessible system-wide.
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 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"
]
// Output folder: One .odin file per processed header
output_folder = "my_lib"
// Remove this prefix from type names and procedure names
remove_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"
]
// Writes the clang JSON ast dump for debug inspection (in output folder)
debug_dump_json_ast = false
The binding generator does not understand any kind of C macros or inline functions. Those you'll have to port manually.
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.
Add it to the input folder.
Use imports_file
in bindgen.sjson
. See examples/raylib
This generator was inspired by floooh's Sokol bindgen: https://github.com/floooh/sokol/tree/master/bindgen