C3 library which translates C header files to C3 bindings. It's main idea is to generate C3 binding with minimal manual efforts via one single function.
Caution
Currently c3c is in development so it's not stable. To be sure that you are using a correct version of the compiler, look at the flake.lock: "nodes" -> "c3c" -> "lock" -> "rev".
This library is distributed with source code so you don't have to additionally with it link statically or dynamically.
- Install dependencies.
- Copy
bindgen.c3ldirectory the dependency directory of your c3 project (libby default). - You can now set
bindgendependency for any project target by doing, for example (for more information plesase refer to C3 wiki):
{
"targets": {
"myfoo": {
"dependencies": [ "bindgen" ],
},
},
}- Import module
bindgeninto your project:
import bindgen;- The most basic file if we want to translate a single file foo.h to foo.c3i without any additional work:
import bindgen;
fn void main() {
bg::translate_header("foo.h", { .out_name = "foo.c3i" })!!;
}Note
As you can see, you must prefix functions with bg, not bindgen. For instance: bg::hello() but not bindgen::hello() - it is made for shorty sake.
There are two types of tests:
- Function tests - testing separate API parts. Run through
c3c run ftest-runner. - Unit tests - testing library implementation parts. Run through
c3c test unit.
All API functions are concentrated in bindgen.c3i file with more detailed documentation.
Main library function is bg::translate_header. Mainly it takes a set of headers and translation functions, which you have to write manually. Mostly these functions takes the name of an entity and must return how must this entity be called in C3 file. There is also extra functionality which you can see at the docs.
For better user experience there is additional API for string transformations, which is a submodule of bindgen. These functions are also defined as methods for String for convenience:
bgstr::<case1>_to_<case2>- a ton of functions to convert one case to another. For instance,bgstr::pascal_to_snake("HelloWorld")will return"hello_world".bgstr::mixed_to_<case2>- the logic of using it is the same asbgstr::<case1>_to_<case2>but it practically sequentially apply both translations for snake and camel case. For instance,bgstr::mixed_to_screaming("LLVMDisassembler_ReferenceType_In_ARM64_LDRXui")will return"LLVM_DISASSEMBLER_REFERENCE_TYPE_IN_ARM64_LDR_XUI".bgstr::is_between- detects whether a name is located between two given names in respect to the order of their translation. WARNING: because macros are translated at first even if they are located between, for instance, function declarations, you have to consider it while using this function.
There are several examples located in examples directory. To check them out, run the following command in root directory of the repository:
- Sandbox to try out library:
c3c run sandbox- it will write to stdout - My dummy:
c3c run dummy -- ./build/dummy.c3iorc3c run dummy- it will print output to stdout - Vulkan:
c3c run vulkan -- ./build/vulkan.c3i - GLFW:
c3c run glfw -- ./build/glfw.c3i - Raylib:
c3c run raylib -- ./build/raylib.c3i
Bit fields in C are not really ABI-compatible with C3. One thing bindgen do is the summing of the sequence of bit fields and emitting the bitstruct represented by a type, which size equals the size of these bit fields. Currently bindgen can't consider all the platform ABIs to generate the correct layout, but at least tries to do it in the most simple way. To be confident about the correctness of bit fields translation you need to test the bindings out on various platforms.
If your platform is not currently supported, you are free to submit an issue or PR. I am using linux so I don't know how to link with libclang under various platforms, so I would really appreciate your help with that.
First of all, read a short article on C3 wiki about library packaging. Then you will need to modify bindgen.c3l/manifest.json with adding your target and linking arguments.
Join and contact me in C3 discord channel.
- Fix multiple definitions for macros
- Inline definition of records and enums inside of function parameters
- Allow user to write any attributes on an entity based on WriteAttrs
- Improve tokens analyzation in macros translation
- Multiple translation units support
- Add kind parameter to if_condition and module_wrap functions: function, structure, member, etc.