Morglod / bun-ffi-gen

FFI bindings generator for Bun
MIT License
24 stars 1 forks source link

Issues with libvirt.h #2

Closed recanman closed 6 months ago

recanman commented 7 months ago

I am using libvirt.h

Code I used (almost identical to the example code):

import { ClangTypeInfoCache, clangGetAstJson, CodeGen, parseClangAst, clangClean } from "bun-ffi-gen";

const HEADER_PATH = "libvirt.h";
const TYPE_CACHE_PATH = "./bindings_cache";

const ast = clangGetAstJson(HEADER_PATH);
const clangTypeInfoCache = await ClangTypeInfoCache.create(TYPE_CACHE_PATH);
const result = parseClangAst(ast, HEADER_PATH, clangTypeInfoCache);

await clangTypeInfoCache.save();

const codeGen = new CodeGen();

codeGen.generateAll(result);

if (codeGen.failedSymbols.size) {
    console.log("ffi failed for:");
    console.log(Array.from(codeGen.failedSymbols));
}

// write output
codeGen.writeToFile("./libvirt.ts");

// cleanup
await clangTypeInfoCache.save();
await clangClean();

I ran it in Bun's alpine Docker image, and I got the following error:

sizeof cache not found, it may take some time
offsetof cache not found, it may take some time
overwrite decl name= undefined item= {
  type: "enum",
  size: 4,
  name: undefined,
  fields: Map(7) {
    "VIR_TYPED_PARAM_INT": {
      type: "int",
      value: "1",
    },
    "VIR_TYPED_PARAM_UINT": {
      type: "int",
      value: "2",
    },
    "VIR_TYPED_PARAM_LLONG": {
      type: "int",
      value: "3",
    },
    "VIR_TYPED_PARAM_ULLONG": {
      type: "int",
      value: "4",
    },
    "VIR_TYPED_PARAM_DOUBLE": {
      type: "int",
      value: "5",
    },
    "VIR_TYPED_PARAM_BOOLEAN": {
      type: "int",
      value: "6",
    },
    "VIR_TYPED_PARAM_STRING": {
      type: "int",
      value: "7",
    },
  },
}
overwrite decl name= undefined item= {
  type: "enum",
  size: 4,
  name: undefined,
  fields: Map(1) {
    "VIR_TYPED_PARAM_STRING_OKAY": {
      type: "expr",
      value: "(1 << 2)",
    },
  },
}
<stdin>:6:38: error: use of undeclared identifier '_virTypedParameter'
            printf("[ %lu ]", sizeof(_virTypedParameter));
                                     ^
1 error generated.
 6 |     const result = execSync(cmd).toString();
 7 |     return JSON.parse(result).inner;
 8 | }
 9 | 
10 | export function clangCompileAndRunReadOut(code: string) {
11 |     execSync("clang -x c - -o ./generate-bindings_tmp_exec", {
         ^
error: <stdin>:6:38: error: use of undeclared identifier '_virTypedParameter'
            printf("[ %lu ]", sizeof(_virTypedParameter));
                                     ^
1 error generated.

   errno: -1
   code: "1"
 syscall: "spawnSync"
   path: "/bin/sh"

      at new SystemError (node:child_process:823:27)
      at node:child_process:175:47
      at node:child_process:224:45
      at clangCompileAndRunReadOut (/usr/src/app/node_modules/bun-ffi-gen/src/clang.ts:11:5)
      at clangGetSizeOf (/usr/src/app/node_modules/bun-ffi-gen/src/clang.ts:71:31)
      at parseClangAst (/usr/src/app/node_modules/bun-ffi-gen/src/parser.ts:260:32)
      at /usr/src/app/index.ts:8:16

Dockerfile:

FROM oven/bun:alpine as base
WORKDIR /usr/src/app
COPY . .

RUN apk add --no-cache clang musl-dev libvirt-dev && bun install && bun run index.ts
Morglod commented 7 months ago

Found that I'm missing static arrays parsing, working on

recanman commented 6 months ago

Any estimate as to when this will be completed? This is an extremely useful library. I've been manually writing a list of symbols for libvirt.h until this hopefully can be fixed.

Morglod commented 6 months ago

Just created new branch union_array_support

Can you test it please? Currently implemented unions and arrays as Buffers for serialization. If current implementation works good, than (may be) I'll add some wrappers for unions/arrays

Also added addIncludeDir, just call it like this before anything else:

import path from "path";
addIncludeDir(path.resolve("./include"));
Morglod commented 6 months ago

Here is my generated result:

libvirt.ts.zip

recanman commented 6 months ago

Thank you very much. I'll test it out today and let you know if there are any issues.

recanman commented 6 months ago

I see that mylib.so/dylib is hardcoded as the name. That initially gave me some issues. Otherwise, everything worked.

Morglod commented 6 months ago

You can specify it like this:

new CodeGen({
    // .so / .dylib / .dll will be appended by bun's suffix
    funcSymbolsImportLibPath: `import.meta.dir + "/libvirt"`,
})

Or replace whole code around it (without suffix append):

new CodeGen({

funcSymbolsImportLibPathCode(out) {
    out.push(`
        let _LIB_PATH: string = "";

        if (process.platform == "darwin") {
            _LIB_PATH =
                import.meta.dir +
                "/../wgpu/libwgpu_native.dylib";
        } else {
            throw new Error("not supported wgpu bindings platform");
        }
    `);

    // return variable name that hold path to lib
    return "_LIB_PATH";
}

})