Skip to content

Instantly share code, notes, and snippets.

@zicklag
Last active February 15, 2023 18:01
Show Gist options
  • Save zicklag/6c2828cda4e8282c850d97ac8a3a0de5 to your computer and use it in GitHub Desktop.
Save zicklag/6c2828cda4e8282c850d97ac8a3a0de5 to your computer and use it in GitHub Desktop.
Khabind Documentation

Khabind: Binding C++ Libraries To Kha For JS/HashLink

NOTE: This is documentation for the feature I added for binding C++ libraries to Haxe for Kha for the Krom and HashLink targets. The discussion is at armory3d/haxebullet#25. This can be moved over to a Wiki page for the Kha repo when the feature gets merged.

Kha has a method for binding C++ libraries to Haxe for use in Kha for its Krom, HTML5, and HashLink targets. It uses Emscripten and the webidl binding library to automatically create Haxe bindings based on a WebIDL file that defines the interfaces to bind. A full example of a Khabind library is haxebullet which is used by the Armory3D project for 3D physics.

Note: When targeting a JavaScript platform such as Krom or HTML5, the C++ library you are binding to will be compiled to JavaScript using Emscripten, so the C++ library must be compatible with Emscripten.

Seting up a Library for Khabind

The components required to setup a Khabind library are:

  • The C++ sources for the library you want to bind to.
  • A WebIDL file defining the interfaces to bind to.
  • A khabind.json file that configures Kha for compiling and including the library.

An example file structure:

mykhalib/
    libsometing/
        file1.cpp
        file1.h
        file2.cpp
        file2.h
    libsomething.idl
    khabind.json

The khabind.json has the following options:

{
    "idlFile": "libsomething.idl", // The WebIDL file
    "nativeLib": "libsomething", // The name of the library
    "sourcesDir": "libsomething", // The dir to look for C++ sources in
    "chopPrefix": "", // An optional prefix to strip from class names
    "autoGC": false, // Automatically clean-up references ( otherwise you have to manually `delete()` them )
    "includes": [ // Headers to include during compilation
        "<file1.h>",
        "<file2.h>"
    ],
    "emccOptimizationLevel": "2", // The compiler optimization level: https://emscripten.org/docs/tools_reference/emcc.html#emcc-compiler-optimization-options
    "emccArgs": [ // Arguments to emcc while linking library
        "-s NO_EXIT_RUNTIME=1"
    ]
}

Using the Library

You add the library to your Kha project the same as you would any other Kha library ( see Libraries ).

When you run Khamake to build the project, Khamake will create a Sources/ directory in your library folder that will contain the Haxe externs for the library. The bindings will be put in a package with the same name as the nativeLib setting in your khabind.json file. For each interface in your WebIDL file, it will create a Haxe class with externs for that interface.

Khamake will also create a khabind/ directory. The khabind/ dir will at least have a libsomething.cpp file that is generated from the WebIDL file. If you are targeting Krom or HTML5, Khamake will also compile the C++ sources, to JavaScript. In order for it to do this you must have Emscripten installed. Khamake will compile all .c and .cpp files in your sourcesDir and create a JavaScript library at khabind/libsomething.js. Finally a korefile.js is added to the library. This file is used during HL builds to include your C++ code.

The Sources/, khabind/, and korefile.js files and folders can safely be added to your .gitignore file. If any of them are missing, they will be automatically created. You may still want to add those files to your Git repo if you do not want any users of the library to need to install Emscripten to use it.

For JavaScript targets, Kha will automatically include the compiled JavaScript library into you Kha project so there is no need to load it manually. For Krom, HTML5, and HashLink, you should now be able to use the library in your Kha project just like it was any other Kha library!

The Compiler Cache

The first time that you build a Kha project with a Khabind library, you will have to wait for the C++ sources of the library to be compiled. Subsequent builds, though, will use the already built library and will not add any compilation time. If you modify the WebIDL file, Khamake will regenerate the Haxe/C++ bindings and it will have to recompile the libsomething.cpp file and re-link the JavaScript library, but it will not have to re-compile the whole library. Any modifications to the sources will only re-compile what has changed. The exception to this is if you change the khabind.json file which will cause Khamake to re-compile the whole library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment