Hello - I'm trying to use Futhark to create bindings for various things. I'm starting with CozoDB as I'm interested in it and the API is tiny. https://github.com/cozodb/cozo/blob/main/cozo-lib-c/example.c
I've been struggling to link the provided DLLs in the compiler.
With the below code it seems to try and link statically when using the lib files,but this way is taking a very long time . Maybe this is because the library itself is a hefty 250mb, I assume because it brings with it mysql and rocksdb backend by default.
import futhark
import strutils
# Tell futhark where to find the C libraries you will compile with, and what
# header files you wish to import.
importc:
path "./lib/c"
"cozo_c.h"
{.passL: "-Llib/static -llibcozo_c".}
proc query(db_id: int32, query: cstring) =
let empty_params = "{}"
var res: cstring
res = cozo_run_query(db_id, query, empty_params, false)
echo $res
cozo_free_str(res)
proc main() =
var db_id: int32
var err: cstring
err = cozo_open_db("mem", "", "{}", addr db_id)
if err != nil :
echo $err
cozo_free_str(err)
return
query(db_id, "?[] <- [[1, 2, 3]]")
echo cozo_close_db(db_id)
main()
So I have two questions:
- How can I adapt this to use DLLs? And how do I link/bind to DLLs in general?
- Will using DLLs in this specific case prevent the very slow compile step that seems to occur?
Thanks :)
You're very close, the only thing missing is a tiny bit of C linking experience. I dropped the .h file and the .so (Linux's version of a .dll) in the same folder as this Nim file:
import futhark
import strutils
# Tell futhark where to find the C libraries you will compile with, and what
# header files you wish to import.
importc:
path "."
"cozo_c.h"
{.passL: "-L. -lcozo_c".}
proc query(db_id: int32, query: cstring) =
let empty_params = "{}"
var res: cstring
res = cozo_run_query(db_id, query, empty_params, false)
echo $res
cozo_free_str(res)
proc main() =
var db_id: int32
var err: cstring
err = cozo_open_db("mem", "", "{}", addr db_id)
if err != nil :
echo $err
cozo_free_str(err)
return
query(db_id, "?[] <- [[1, 2, 3]]")
echo cozo_close_db(db_id)
main()
Then it's a simple nim c <ourfile>.nim to build the binary. Now this is dynamically linked to libcozo_c.so, but running it will throw an error (on Linux, on Windows you're fine since the library is in the same folder). We need to tell it to look for the dynamic library in the local folder and not just in the system folders: LD_LIBRARY_PATH=. ./<ourfile>. And there you go, a dynamically linked library which runs fine.
Of course you could clean it up a little bit while we're at it:
import futhark
import strutils
# Tell futhark where to find the C libraries you will compile with, and what
# header files you wish to import.
proc renameCallback(name, kind: string, partOf = ""): string =
result = name
result.removePrefix("cozo_")
importc:
renameCallback renameCallback
path "."
"cozo_c.h"
{.passL: "-L. -lcozo_c".}
proc query(dbId: cint, query: cstring) =
let
emptyParams = "{}"
res = dbId.runQuery(query, emptyParams, false)
echo $res
freeStr(res)
var
dbId: cint
err = openDb("mem", "", "{}", addr dbId)
if err != nil:
echo $err
freeStr(err)
quit 1
dbId.query("?[] <- [[1, 2, 3]]")
echo dbId.closeDb