Automatically turns LuaJIT FFI declarations into valid Lua-Language-Server meta files.
- LuaJIT
- LLVM (for
libclang
) - C compiler (to compile
utilities.c
)
First, compile utilities.c
cc $(llvm-config --cflags) utilities.c -shared -o utilities.so -L$(llvm-config --libdir) -lclang
Then, run the script:
luajit ffi-to-lls.lua <input defs.h> [-o <output file>] [--remove-prefix <prefix>] [--no-auxiliary-types] [--module-name <name>]
<input defs.h>
: The header file containing the FFI declarations.-o <output file>
: The output file to write the LLS meta file to. If not specified, the output will be written to stdout.--remove-prefix <prefix>
: Remove the specified prefix from the function names in the output. This is useful when the FFI declarations are prefixed with a common string, such aslua_
orlj_
.--no-auxiliary-types
: Do not generate auxiliary types such asc.pointer<T>
. This is useful when the generated file is used with another file that already defines these types.--module-name <name>
: The name of the module to be usede in generation
Given the a definitions file such as:
struct MyStruct {
int a;
int b;
};
struct MyStruct *mylib_MyStruct_create(int a, int b);
void mylib_MyStruct_free(struct MyStruct *s);
We can generate definitions with
luajit ffi-to-lls.lua mylib.h -o mylib.lua --remove-prefix mylib_
A file like this would be generated:
---Automatically generated bindings generated by ffi-to-lls.lua (https://github.com/Frityet/ffi-to-lls/)
---You can edit this file!
---The following prefix was removed: `mylib_`
---Lua language server will autocomplete both with and without the prefix.
---@meta mylib
---You may remove this, or generate this file again with --no-auxiliary-types, to supress redefinition warnings
---@class c.pointer<T> : { [integer] : T }, ffi.cdata*
---@class mylib
local mylib = {}
---@class MyStruct
---@field a integer
---@field b integer
---@param a integer
---@param b integer
---@return c.pointer<MyStruct>
function mylib.mylib_MyStruct_create(a, b) end
mylib.MyStruct_create = mylib.mylib_MyStruct_create
---@param s c.pointer<MyStruct>
---@return nil
function mylib.mylib_MyStruct_free(s) end
mylib.MyStruct_free = mylib.mylib_MyStruct_free
return mylib