{"id":23222696,"url":"https://github.com/pmunch/futhark","last_synced_at":"2025-05-16T06:07:17.237Z","repository":{"id":37941696,"uuid":"409231853","full_name":"PMunch/futhark","owner":"PMunch","description":"Automatic wrapping of C headers in Nim","archived":false,"fork":false,"pushed_at":"2025-04-28T10:21:21.000Z","size":335,"stargazers_count":436,"open_issues_count":39,"forks_count":28,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-28T11:36:38.747Z","etag":null,"topics":["hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PMunch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-22T14:14:08.000Z","updated_at":"2025-04-28T10:21:25.000Z","dependencies_parsed_at":"2024-01-12T04:46:04.614Z","dependency_job_id":"e32c0d2b-b4db-4843-b0e4-8e46a7d00b9d","html_url":"https://github.com/PMunch/futhark","commit_stats":null,"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PMunch%2Ffuthark","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PMunch%2Ffuthark/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PMunch%2Ffuthark/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PMunch%2Ffuthark/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PMunch","download_url":"https://codeload.github.com/PMunch/futhark/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254478190,"owners_count":22077676,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest"],"created_at":"2024-12-18T23:14:04.343Z","updated_at":"2025-05-16T06:07:12.227Z","avatar_url":"https://github.com/PMunch.png","language":"Nim","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Futhark logo](https://github.com/PMunch/futhark/blob/master/futhark.png)\n\nHave your eyes set on the perfect C library for your project? Can't find a\nwrapper for it in Nim? Look no further! Futhark aims to allow you to simply\nimport C header files directly into Nim, and allow you to use them like you\nwould from C without any manual intervention. It's still in a beta state, but it\nalready wraps most header files without any rewrites or pre-processing and has\nsuccessfully been used to wrap complex projects.\n\n```nim\nimport futhark, strutils\n\n# Remove the `stbi_` prefix since Nim doesn't struggle as much with collisions as C\nproc renameCb(n: string, k: SymbolKind, p: string, overloading: var bool): string =\n  n.replace \"stbi_\", \"\"\n\n# Tell futhark where to find the C libraries you will compile with, and what\n# header files you wish to import.\nimportc:\n  path \"./stb\"\n  define STB_IMAGE_IMPLEMENTATION # This define is required by the STB library\n  renameCallback renameCb\n  rename FILE, CFile # Rename `FILE` that STB uses to `CFile` which is the Nim equivalent\n  \"stb_image.h\"\n\n# Tell Nim how to compile against the library. If you have a dynamic library\n# this would simply be a `--passL:\"-l\u003clibrary name\u003e`\nstatic:\n  writeFile(\"test.c\", \"\"\"\n  #define STB_IMAGE_IMPLEMENTATION\n  #include \"./stb/stb_image.h\"\n  \"\"\")\n{.compile: \"test.c\".}\n\n# Use the library just like you would in C!\nvar width, height, channels: cint\n\nvar image = load(\"futhark.png\", width.addr, height.addr, channels.addr, STBI_default.cint)\nif image.isNil:\n  echo \"Error in loading the image\"\n  quit 1\n\necho \"Loaded image with a width of \", width, \", a height of \", height, \" and \", channels, \" channels\"\nimage_free(image)\n```\n\n# So are all C wrappers now obsolete?\nNot quite. Futhark only tells you what the C headers define and allows you to\nuse them. This means that the interface is still very C-like. A lot of great\nNim wrappers will take a C library and wrap it into something that is a little\nmore simple to use from Nim land. But Futhark can definitely be used to help\nwith wrapping C libraries. Since it reads the C files directly you are\nguaranteed that all the types match up with their C counterparts, no matter\nwhat platform you're on, or what defines you want to pass. This is a huge\nbenefit over hand-wrapped code. Futhark and Øpir will also cache their results,\nso after the initial compilation it's just as fast to use as it simply grabs\nthe pre-generated Nim file from the cache. Both files could of course also be\nedited or included as-is in a project if you want users to not have to run Øpir\nor Futhark themselves.\n\n# How does it work?\nBasically Futhark comprises of two parts, a helper program called Øpir (or\n`opir` just to ensure that it works everywhere) and a module called `futhark`\nthat exposes a `importc` macro. Øpir is compiled with libclang and uses Clang\nto parse and understand the C files, it then creates a big JSON output of\neverything that is defined in the headers with Nim friendly types. The macro\nthen reads this file and applies any overrides to types and names before it\ngenerates all the Nim definitions.\n\n## Basic usage\nA lot of people coming from other wrapping tools start out a bit confused about\nFuthark. With other tools it is common to wrap things into a Nim module first,\nthen import that module into your program. This is not the way Futhark is\nsupposed to be used. With Futhark you handle your C imports in the `importc`\nblock and just import the module in which you have that block. This is to ensure\nthat all defines, configurations, and platform specific things will match up\nbetween your code and the C code. It is however possible to use Futhark to\ngenerate a wrapper, this is detailed in the \"Shipping wrappers\" section of this\nREADME.\n\nThe four main things you need to know to use Futhark is `sysPath`, `path`,\n`compilerArgs`, and normal imports (the `\"stb_image.h\"` part in the above\nexample).\n- `sysPath` denotes system paths, these will be passed to Øpir to make sure\n  Clang knows where to find all the definitions. This can also be passed with\n  `-d:sysPath:\u003cpath 1\u003e:\u003cpath 2\u003e` if you want to automatically generate these. By\n  default Futhark tries to find the `sysPath` automatically and you don't need\n  to specify this yourself.\n- `path` denotes library paths, these will also be passed to Øpir, but anything\n  found in these files which is used by anything in the explicitly imported\n  files will be wrapped by Futhark as well.\n- `compilerArgs` specifies additional flags that should be passed to Clang\n  when parsing the C headers.\n- Files listed in quotes in the importc are equivalent to `#include \"file.h\"`\n  in C. Futhark will generate all definitions in these files, and if `file.h`\n  imports more files found in any of the paths passed in by `path` these files\n  will also be imported.\n\nNote: The difference between `sysPath` and `path` is simply about how Futhark\nhandles definitions found in these paths. `sysPath` are paths which are fed to\nØpir and Clang in order to make Clang able to read all the types. `path` are\nthe paths Futhark takes into account when generating definitions. This\ndifference exists to make sure Futhark doesn't import all kinds of low-level\nsystem stuff which is already available in Nim. A subpath of `sysPath` can be\npassed in with `path` without trouble. So `sysPath \"/usr/include\"` followed by\n`path \"/usr/include/X11\"` is fine and Futhark will only generate code for the\nexplicitly mentioned files, and any files it requires from `/usr/include/X11`.\n\n## Hard names and overrides\nNim, unlike C, is case and underscore insensitive and doesn't allow you to have\nidentifiers starting or ending with `_`, or identifiers that have more than one\nconsecutive `_` in them. Nim also has a set of reserved keywords like `proc`,\n`addr`, and `type` which would be inconvenient to have as names. Because of\nthis Futhark will rename these according to some fairly simple rules.\n\n| Name issue       | Nim rename                                          |\n| ---------------- | --------------------------------------------------- |\n| struct type      | `struct_` prefix                                    |\n| union type       | `union_` prefix                                     |\n| enum type        | `enum_` prefix                                      |\n| `_` prefix       | `internal_` prefix                                  |\n| `__` prefix      | `compiler_` prefix                                  |\n| `_` postfix      | `_private` postfix                                  |\n| `__` in name     | All consecutive underscores collapsed into one      |\n| Reserved keyword | Append kind to name, `proc`, `const`, `struct` etc. |\n\nApart from this the name is kept as it appears in the C sources, but note that\nbecause of Nims style insensitivity you can still call `some_proc` as `someProc`\nwithout any issues. This renaming scheme, along with Nims style-insensitivity,\ndoes however mean that some identifiers might collide. In this case the name\nwill further have the kind appended, and if it still collides it will append\nthe hash of the original identifier. This shouldn't happen often in real\nprojects and exists mostly to create a foolproof renaming scheme. Note that\nstruct and union types also get a prefix, this is normally resolved\nautomatically by C typedef-ing the `struct struct_name` to `struct_name_t`, but\nin case you need to use a `struct struct_name` type just keep in mind that in\nNim it will be `struct_struct_name`.\n\nIf you want to rename an object or a field you can use the `rename` directive.\nSimply put `rename \u003cfrom\u003e, \u003cto\u003e` along with your other options. `\u003cfrom\u003e` can be\neither just an object name (before any other renaming) as a string or ident, or\na field in the format `\u003cobject\u003e.\u003cfield\u003e` both the original C names either as\ntwo identifiers, or the whole thing as a single string. `\u003cto\u003e` is always a\nsingle identifier and is the new name.\n\nIf you want to implement more complex renaming you can use the `renameCallback`\ndirective and pass in a callback function that takes the original name, a\nstring denoting what kind of identifier this is, and an optional string\ndenoting which object or procedure this identifier occurs in, and which returns\na new string. This callback will be inserted into the renaming logic and will\nbe called on the original C identifier before all the other rules are applied.\nSee the Deeper control \u003e Rename callback section for more information.\n\n## Redefining types\nC tends to use a lot of void pointers, pointers to characters, and pointers to\na single element which is supposed to be a collection of said element. In Nim\nwe like to be a bit more strict about our types. For this you can use the\n`retype` directive. It takes the form `retype \u003cobject\u003e.\u003cfield\u003e, \u003cNim type\u003e` so\nfor example to retype the C array type defined as `some_element* some_field` to\nan indexable type in Nim you can use\n`retype some_object.some_field, ptr UncheckedArray[some_element]`. The names\nfor the object and field are both their renamed Nim identifiers.\n\nIf you need to redefine an entire object, instead of just specific fields\nFuthark by default also guards every type and procedure definiton in simple\n`when declared(SomeType)` statements so that if you want to override a\ndefinition you can simply define your type before the `importc` macro\ninvocation and Futhark won't override your definition. It is up to you however\nto ensure that this type actually matches in size and layout with the original\nC type.\n\n## Compatibility features and readability\nFuthark by default tries to ensure the highest amount of compatibility with\npre-wrapped libraries (e.g. the `posix` standard library module) and other user\ncode. Because of this the output which Futhark generates isn't very pretty,\nbeing littered with `when defined` statements and weird numbered\nidentifiers for renaming things. These features are intended to make Futhark\neasier to use in a mostly automatic fashion, but you might not need them. If\nyou want to read the generated output, build documentation of a Futhark\ngenerated module, or possibly get an improved editor experience you might want\nto disable some of these features for a prettier, more readable output.\n\nThere are basically three things you can control with define switches:\n\n| Define        | Effect                                                      |\n| ------------- | ----------------------------------------------------------- |\n| nodeclguards  | Disables the object rename/override functionality           |\n| noopaquetypes | Disables opaque types used for unknown objects              |\n| exportall     | Exports all fields (including renamed ones)                 |\n\n### Object rename/override functionality\nThis declares types in such a way that earlier declarations by the same name\nwill not be overriden or collide. With this feature you can declare an object,\nfunction, enum, etc. before the call to Futhark and these declarations will be\nused instead of the auto-generated ones. This is also what enables the feature\nat the end of the \"Redifining types\" section. Disabling this feature will\nremove all of the `when declared` but you might run into Futhark trying to\nredeclare existing things, including built in types and names.\n\n### Opaque type functionality\nIf a type is not fully declared in your C headers but is still required for\nyour project Futhark will generate a `type SomeType = object` dummy\ntype for it. Since most C libraries will pass things by pointer this makes sure\nthat a `ptr SomeType` can exist and be passed around without having to know\nanything about `SomeType`. Disabling this feature will remove these definitions\nbut might mean some procedure definitions now have invalid parameters or return\ntypes. This is mostly useful in conjunction with `nodeclguards` and manually\ndeclaring these types.\n\n### Hiding symbols functionality\nTo avoid editors showing the renamed identifiers used by the object\nrename/override functionality they are hidden by default. If however you want\nto generate documentation for a Futhark generated module these fields won't be\nvisible and the documentation mostly useless. With `exportall` these symbols\nwill be exported as well and documentation will be readable. This is mostly\nuseful if you want to export documentation but can't use `nodeclguards` (which\nmakes even more readable documentation).\n\n## Inline functions\nWhen using Futhark with dynamic libraries it doesn't make sense to wrap inline\nfunctions. However if you are compiling your code directly against some C code\nthese might be useful to you. In this case you can pass `-d:generateInline` to\ngenerate function definitions for inline functions.\n\n## Pre-ANSI C function declarations\nAlso known as K\u0026R style functions. By definition C code like\n```c\nint* myfunc();\n```\nis a pre-ansi C function declaration that says `myfunc` returns a pointer to an\ninteger *and takes any number of arguments*. This last part is a historic thing\nyou can read more about [here](https://jameshfisher.com/2016/11/27/c-k-and-r/),\nbut suffice to say this is misused in quite a lot of C libraries to mean that\nthe function takes no arguments. Since this is fairly obscure, and Nim will\ncreate bad C code if the varargs pragma is attached to a function without\narguments this is ignored by default. However if you for some reason require\nthis you might add `-d:preAnsiFuncDecl` while compiling.\n\n## Deeper control\n### Rename callback\nIf you want to rename identifiers, for example removing common prefixes,\npostfixes, or other similar things you can use a rename callback. This can be\ndefined by adding `renameCallback \u003cprocedure name\u003e` to your `importc` block. The\nsignature of the callback is:\n```\nproc(name: string, kind: SymbolKind, partof: string, overloading: var bool): string\n```\nwhere `name` is the original name as present in the C code, `kind` is the kind\nof the identifier such as `Enum`, `Proc`, `Arg`, `Field`, etc. The argument\n`partof` is only used for field names in a structure.\n\nIn order to avoid name collisions the normal anti-collision transformations are\ndone after the rename callback. And if not disabled the resulting checks would\nalso have declaration guards preventing overloading. To circumvent this you can\nset `overloading = true` in your `renameCallback` on a per-identifier level to\nallow for example functions to overload each other or other pre-existing\nidentifiers.\n\n### Pragma callback\nIf you want to add a pragma to anything Futhark outputs you can add\n`pragmasCallback \u003cprocedure name\u003e` to your `importc` block. The signature of the\ncallback is:\n\n```\nproc(name: string, kind: SymbolKind, pragmas: var seq[NimNode])\n```\n\nThe `name` and `kind` arguments are the same as for the `renameCallback`, and\n`pragmas` is a list of pragmas that will be added. This list will be\npre-populated with the pragmas Futhark already attaches, and can be completely\nmodified in the callback. Futhark will not perform any further checks on the\npragmas you put in the sequence. This can be useful if you want to e.g. add\n`discardable` to procedures that would be safe to ignore the return value of. It\nwould also be possible to attach custom pragmas or macros and this way\ncompletely redefine the definition.\n\n### Øpir callbacks\nIn case you face issues that aren't easily solveable there is one last option\nfor making modifications, and this is Øpir hooks. Since Øpir converts your C\nimports to a JSON format you're able to register hooks that will be run before\nFuthark consumes this JSON. These are simple procedures which takes a `JsonNode`\nand returns a `JsonNode`. With this you're able to change every aspect of the\nJSON, and even add or remove definitions. The callbacks are a list, so modules\nto perform certain commonly done transformations (e.g. combine similarly named\nconstants into an enum) could be added to the list of callbacks easily. To add\nthese simply add in `addOpirCallback \u003cprocedure name\u003e` to your `importc` block.\n\n## Destructors\nIf you are using a C library you will probably want to wrap destructor calls.\nFuthark makes all C objects `{.pure, inheritable.}` which means you can quite\neasily use somewhat idiomatic Nim to achieve destructors.\n\nAn example usecase from MiniAudio bindings is as follows:\n```nim\ntype TAudioEngine = object of maEngine # Creates a new object in this scope\n                                       # maEngine is a type wrapped by Futhark\n                                       # TAudioEngine can now have a destructor\n                                       # attached to it\n\nproc `=destroy`(engine: var TAudioEngine) = # Define a destructor as normal\n  maEngineUninit(engine.addr)\n```\n\n## Dynamic libraries and implementing headers\nIf you are making a dynamic or static library to be loaded or linked with\nanother program you are often given a header file to implement. This file\ntypically includes the types and functions you are able to call from the main\nprogram, along with the procedures that your application has to implement in\norder to be loaded and run correctly. Futhark normally imports all headers on\nthe assumption that things will be made available from C while compiling, ie.\nit adds the `importc` pragma to them. But in order to support this scenario you\ncan also get it to create forward declarations with the `exportc` pragma. This\nallows Nim to know that there has to exist an implementation for a given\nprocedure in your application, and as such will fail to compile if you're\nmissing an implementation. It will also make sure that your signature is\nexported correctly and matches the intended C header. To do this simply define\nthe procedures to be forward declared like this along with your other options:\n\n```nim\nimportc:\n  forward \"proc_to_forward\"\n```\n\nFutark will automatically add the `dynlib` pragma to this declaration if you're\nbuildin with `--app:lib`, but if you need to add more pragmas you can list them\nafter the name like so:\n\n```nim\nmacro customPragma(msg: static[string], body: untyped): untyped =\n  echo \"Saying: \", msg\n  return body\n\nimportc:\n  forward \"proc_to_forward\", customPragma(\"Hello world\"), used\n```\n\nIf you want to see what code Futhark generated for your forward declarations,\nand therefore the signature you need to match (even the argument names), you\ncan pass `-d:echoForwards` and they will be written out in the terminal while\ncompiling.\n\nNOTE: Since the forward declaration has all the pragmas for passing it on as C\ncompatible symbols you don't actually need to have these pragmas attached to\nyour implementation which makes it a bit cleaner. And the procedure can of\ncourse be written in camelCase if you prefer, it will still match the forward\ndeclaration.\n\n# Shipping wrappers\nYou've built wrappers with Futhark, expanded them with a nice Nim interface and\nit's time to share them with the world! This section will give some\nbest-practices on how to ship wrappers. Since the Øpir tool requires Clang to\nbe installed it can be a bit tricky to get Futhark installed. In addition to\nthis Futhark obviously requires access to the C header files, which might be\ninstalled in different places based on the system. Because of these things you\nmight not want to have Futhark as a dependency for your bindings. To help with\nthis Futhark has an `outputPath` argument which can be added to the `importc`\nblock. This path is where the completed bindings will be stored, and also where\nFuthark will look for existing bindings to avoid rebuilding them. This means\nthat with the `outputPath` set to a file you will need to use\n`-d:futharkRebuild` to update the file when you make changes in the `importc`\nblock. If you set `outputPath` to a folder then `futhark` will store the files\nwith the appended hash in this folder instead of in the `nimcache` folder and\ncaching will work as usual. By using this feature you will be able to set a\npath local to your project and check the generated Futhark file into your\nversion control system. But that is only half the job, because to be aware of\nthe cache file Futhark still needs to be installed. The recommended way to get\naround this is to do a `when defined(useFuthark)` switch to check whether the\nuser wants to use Futhark directly or to use the shipped wrapper. It is\nrecommended to use the exact name `useFuthark`, this way the user can turn on\nFuthark for the entire project (in case you have imported another library which\nalso uses Futhark). If you want to give the user the option to switch on\nFuthark for only your project it is recommended to use an additional switch\nwith `useFutharkFor\u003cproject name\u003e`.\n\nA complete sample would look a bit something like this:\n\n```nim\nwhen defined(useFuthark) or defined(useFutharkForExample):\n  import futhark, os\n\n  importc:\n    outputPath currentSourcePath.parentDir / \"generated.nim\"\n    path \"\u003cpath to library\u003e\"\n    \"libfile.h\"\nelse:\n  include \"generated.nim\"\n```\n\nKeep in mind that when your package is installed the generated Futhark output\nwould be placed in the folder of your package using this code. If the\n`/ \"generated.nim\"` part is left of then the file would be named\n`futhark_\u003chash\u003e.nim` as described above, this means that your `include` could\nuse the one specified in your package installation, while users doing\n`useFuthark` would generate one based on its hash (or reuse yours if the hash\nmatches).\n\n## Project mode\nFuthark is best used when it is allowed to see the C files while compiling. This\nallows it to make sure that all platform specific stuff matches up perfectly.\nHowever this is not always possible, or for whatever other reason wanted. One\nscenario where this is the case is for embedded projects. The Futhark macro\ndoesn't work when targeting platforms without proper OS support, so using it the\nrecommended way is simply not possible.\n\nBecause of this it is also possible to use Futhark in \"project mode\". In project\nmode you simply don't specify any files to import. Instead you only specify\nwhich `path`'s you want to search. Futhark will then recreate the original\nfolder structure of the header files it finds and generate Nim files in their\nplace. These try to properly import and export each other so the behaviour is as\nsimilar to C and if Futhark finds `.c` files next to the `.h` files of the same\nname it also adds `{.passL:\"-I\u003cpath\u003e\".}` and `{.compile: \"\u003cfile\u003e\".}` pragmas to\nautomatically import and compile the required C files. This means that a\nseparate dummy wrapper project can be set up which just generates this folder\nstructure, and the main project can simply import files from this folder as if\nthey where normal modules.\n\nWhile this is quite a nice feature it isn't as bullet-proof as the traditional\nway to use Futhark. It might require some pre-processing of the C project, and\nit often means more work with getting everything compiled properly. But when\nnormal Futhark usage isn't possible or desired this is a decent option.\n\nTo minimize the pre-processing burden this mode also adds a new option `ignore`\nto the `importc` block. This is simply a file or folder to ignore while\ntraversing the given paths. Futhark will not try to generate any input for this\nfile/folder, but it will look at the headers inside to resolve other parts of\nthe project. This is mainly useful if you have folders with examples or other\ncode you're not actually supposed to import.\n\n# But why not use c2nim or nimterop?\nBoth c2nim and nimterop have failed me in the past when wrapping headers. This\nboils down to how they are built. c2nim tries to read and understand C files\non its own, something which might appear simple, but C is notoriously hard to\nparse and c2nim fails on macros and other slightly complex things. nimterop\nuses treesitter and performs slightly better. It is theoretically able to parse\nall C syntax, but the C semantics is still up to nimterop to implement. Which\nmeans it can't do macros or things like IFDEF automatically.\n\nFuthark on the other hand uses clang, which is very good at both understand C\nsyntax, but also C semantics. This means that it resolves all macros and IFDEF\nstatements, and just gives us the definitions for everything. This means much\nless work in actually trying to understand C, which means that all this work\ncan be spent on quality Nim translation.\n\n# Sounds great, what's the catch?\nFuthark is currently in an beta state, it works really well but you might run\ninto occasional bugs or hickups. It also doesn't support C++ at the moment, and\nit doesn't understand things like function-style macros. It might also mess up\non strange C things which haven't been encountered yet, although this is more\nand more rare as people use it. All of these shortcomings are things I hope to\nget fixed up over time.\n\n# Installation\nTo install Futhark you first need to have clang installed. Installing clang on\nLinux is as simple as just grabbing it from your package manager (e.g. \n(Debian-based distributions: `sudo apt install clang libclang-dev`,\nVoid Linux: `sudo xbps-install clang clang17-devel libclang`). \nTo install clang on Windows you need to install\n[LLVM](https://github.com/llvm/llvm-project/releases/tag/llvmorg-15.0.7) (you\nprobably want to grab the `LLVM-15.0.7-win64.exe` version). To install clang on\nmacOS, run `xcode-select --install` in the terminal. Opir should then detect\nit automatically. Have a look at [opir.nims](src/futhark/opir.nims) if you're\ncurious how the Windows and macOS detection works.\n\nIf you have Clang installed in your system path you can now simply run:\n```\nnimble install futhark\n```\n\nOtherwise you need to tell Opir how to link with libclang. Do this by either\ncopying the `libclang.lib` and `libclang.dll` into the Futhark project dir or\nuse `passL` to pass the folder that `libclang.lib` (or libclang.so on Linux\nmachines) lives in to the linker:\n\n```\nnimble install --passL:\"-L\u003cpath to lib directory containing libclang.so file\u003e\" futhark\n#e.g.: nimble install --passL:\"-L/usr/lib/llvm-6.0/lib\" futhark\n```\n\n# Known wrappers made with Futhark\nBy the nature of Futhark wrappers can be made on the fly for a specific project.\nI've wrapped many large C projects with Futhark, but just for use in specific,\nand sometimes proprietary, codebases. That being said this list contains\nwrappers that are made with Futhark which have been published in some shape or\nform. These can very from just a simple file with some Futhark instructions, to\nfull projects that add nice-to-have features on top of an existing C library. If\nyou have a project of your own you want to show off, please make a PR!\n\n- [MAPM](https://github.com/PMunch/mapm-nim): Fully wrapped with destructors and a nice Nim interface\n- [libfuse](https://github.com/PMunch/libfuse-nim/blob/master/libfuse.nim): Quick and dirty wrapper for libfuse to play around with filesystems\n- [VapourSynth](https://github.com/mantielero/vs.nim): Uses Futhark to create the initial wrapper, then builds a nice Nim library on top\n- [python_nim_libmem](https://github.com/Hypnootika/python_nim_libmem): Futhark and helper scripts to generate Nim and Python bindings for \"Libmem\"\n- [box2d.nim](https://github.com/jon-edward/box2d.nim): Nim bindings for Erin Catto's Box2D physics engine. \n\n## TODO\n- Proper handling of C macros (inherently hard because C macros are typeless)\n- Find way to not require C compiler include paths\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmunch%2Ffuthark","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpmunch%2Ffuthark","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmunch%2Ffuthark/lists"}