odin-blend2d

Odin bindings to Blend2D
Log | Files | Refs | README | LICENSE

README.md (7914B)


      1 # odin-c-bindgen: Generate Odin bindings for C libraries
      2 
      3 This generator makes it possible to quickly generate C library bindings for the Odin Programming Language.
      4 
      5 Features:
      6 - Easy to get started with. Can generate bindings from a folder of headers.
      7 - 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).
      8 - Simplicity. The generator is simple enough that you can modify it, should the need arise.
      9 - 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).
     10 
     11 > If you find this generator helpful and want to say thanks, then please consider [donating](https://github.com/sponsors/karl-zylinski).
     12 >
     13 > Discuss and ask questions on [my Discord server](https://discord.gg/4FsHgtBmFK).
     14 
     15 ## Requirements
     16 - Odin
     17 - libclang version 16 or higher
     18 	- On Windows: Download libclang 20.1.8 from here: https://github.com/llvm/llvm-project/releases/download/llvmorg-20.1.8/clang+llvm-20.1.8-x86_64-pc-windows-msvc.tar.xz -- Copy the following from that archive:
     19 		- `lib/libclang.lib` into the generator's 'libclang' folder
     20 		- `bin/libclang.dll` into the root of the generator (next to where the bindgen executable will end up).
     21 	- On Linux/mac, please install libclang. For example using `apt install libclang-dev` on Ubuntu/Debian/Mint. Anything from clang version 16 and new should work.
     22 
     23 > [!NOTE]
     24 > libclang is used for analysing the C headers and deciding what Odin code to output.
     25 
     26 ## Getting started
     27 
     28 1. Build the generator: `odin build src -out:bindgen.exe` (replace `.exe` with `.bin` on mac/Linux)
     29 2. Make a folder. Inside it, put the C headers (`.h` files) of the library you want to generate bindings for.
     30 3. Execute `bindgen the_folder`
     31 4. Bindings can be found inside `the_folder/the_folder`
     32 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.
     33 
     34 ## Configuration
     35 
     36 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.
     37 
     38 > NOTE: Config uses the function/type names as found in header files.
     39 
     40 ```sjson
     41 // Inputs can be folders or files. If you provide a folder name, then the generator will look for
     42 // header (.h) files inside it. The bindings will be based on those headers. For each header,
     43 // you can create a `header_footer.odin` file with some additional code to append to the finished
     44 // bindings. If the header is called `raylib.h` then the footer would be `raylib_footer.odin`.
     45 inputs = [
     46 	"input"
     47 ]
     48 
     49 // Output folder. In there you'll find one .odin file per processed header.
     50 output_folder = "my_lib"
     51 
     52 // Remove this prefix from types names (structs, enums, etc)
     53 remove_type_prefix = ""
     54 
     55 // Remove this prefix from macro names
     56 remove_macro_prefix = ""
     57 
     58 // Remove this prefix from function names (and add it as link_prefix) to the foreign group
     59 remove_function_prefix = ""
     60 
     61 // Remove this suffix from type names (such as '_t' etc)
     62 remove_type_suffix = ""
     63 
     64 // Set to true translate type names to Ada_Case
     65 force_ada_case_types = false
     66 
     67 // Single lib file to import. Will be ignored if `imports_file` is set.
     68 import_lib = "my_lib.lib"
     69 
     70 // The filename of a file that contains the foreign import declarations. In it you can do
     71 // platform-specific library imports etc. The contents of it will  be placed near the top of the
     72 // file.
     73 imports_file = ""
     74 
     75 // `package something` to put at top of each generated Odin binding file.
     76 package_name = "my_lib"
     77 
     78 // "Old_Name" = "New_Name"
     79 rename = {
     80 }
     81 
     82 // Turns an enum into a bit_set. Converts the values of the enum into appropriate values for a
     83 // bit_set (translates the enum values using a log2 procedure).
     84 //
     85 // Note that the enum will be turned into a bit_set type. There will be a new type created that
     86 // contains the actual enum, which the bit_set then references.
     87 bit_setify = {
     88 	// "Enum_To_Turn_Into_Bitset" = "New_Enum_Type_Name"
     89 }
     90 
     91 // Completely override the definition of a type.
     92 type_overrides = {
     93 	// "Vector2" = "[2]f32"
     94 }
     95 
     96 // Override the type of a struct field.
     97 // 
     98 // You can also use `[^]` to augment an already existing type.
     99 struct_field_overrides = {
    100 	// "Some_Type.some_field" = "My_Type"
    101 	// "Some_Other_Type.field" = "[^]"
    102 	// "Some_Other_Type.another_file" = "[^]cstring"
    103 }
    104 
    105 // Put these tags on the specified struct field
    106 struct_field_tags = {
    107 	// "BoneInfo.name" = "fmt:\"s,0\""
    108 }
    109 
    110 // Remove a specific enum member. Write the C name of the member. You can also use wildcards
    111 // such as *_Count
    112 remove_enum_members = [
    113 	// "MAGICAL_ENUM_ALL"
    114 	// "_*Count"
    115 ]
    116 
    117 // Overrides the type of a procedure parameter or return value. For a parameter use the key
    118 // Proc_Name.parameter_name. For a return value use the key Proc_Name.
    119 //
    120 // You can also use `[^]`, `#by_ptr` and `#any_int` to augment an already existing type.
    121 procedure_type_overrides = {
    122 	// "SetConfigFlags.flags" = "ConfigFlags"
    123 	// "GetKeyPressed"        = "KeyboardKey"
    124 }
    125 
    126 // Add in a default value to a procedure parameter. Use `Proc_Name.parameter_name` as key and
    127 // write the plain-text Odin value as value.
    128 //
    129 // You can also add defaults for proc parameters within structs. In that case you do:
    130 // `Struct_Name.proc_field.parameter_name` -- This does not currently support nested structs.
    131 procedure_parameter_defaults = {
    132 	// "DrawTexturePro.tint" = "RED"
    133 	// "Some_Struct.a_field_that_is_a_proc.some_parameter" = "5"
    134 }
    135 
    136 // Put the names of declarations in here to remove them.
    137 remove = [
    138 	// "Some_Declaration_Name"
    139 ]
    140 
    141 // Group all procedures at the end of the file.
    142 procedures_at_end = false
    143 
    144 // Additional include paths to send into clang. While generating the bindings clang will look into
    145 // this path in search for included headers.
    146 clang_include_paths = [
    147 	// "include"
    148 ]
    149 
    150 // Pass these compiler defines into clang. Can be used to control clang pre-processor
    151 clang_defines = {
    152 	// "UFBX_REAL_IS_FLOAT" = "1"
    153 }
    154 ```
    155 
    156 ## FAQ and common problems
    157 
    158 ### Why didn't my bindings generate correctly?
    159 
    160 Please look through the list of configuration options listed above and see if they help you. Also,
    161 see the the examples folder for additional inspiration.
    162 
    163 If you fail to make any progress on generating bindings for a certain library, 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.
    164 
    165 ### How can I add some extra code to a generated file?
    166 
    167 If the source header is called `raylib.h` then add a a file called `raylib_footer.odin` next to it
    168 and put your code in there.
    169 
    170 ### How do I manually specify which libraries to load on different platforms etc?
    171 
    172 Use `imports_file` in `bindgen.sjson`. See `examples/raylib`
    173 
    174 ### How can I turn an enum into a bit_set?
    175 
    176 In `bindgen.sjson`:
    177 
    178 ```
    179 bit_setify = {
    180 	"your_enum" = "the_bit_set_type"
    181 }
    182 ```
    183 
    184 This will create a type `the_bit_set_type :: bit_set[your_enum; c.int`.
    185 
    186 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).
    187 
    188 ### My headers can't find other headers in the same folder
    189 
    190 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`:
    191 
    192 ```
    193 clang_include_paths = [
    194 	"include"
    195 ]
    196 ```
    197 
    198 ## Acknowledgements
    199 
    200 Big thanks to [Xandaron](https://github.com/xandaron/) for figuring out a lot of the libclang stuff.
    201 
    202 This generator was inspired by floooh's Sokol bindgen: https://github.com/floooh/sokol/tree/master/bindgen