{"id":15022426,"url":"https://github.com/revng/llvmcpy","last_synced_at":"2025-05-16T02:07:24.145Z","repository":{"id":47470231,"uuid":"76602166","full_name":"revng/llvmcpy","owner":"revng","description":"Python bindings for LLVM auto-generated from the LLVM-C API","archived":false,"fork":false,"pushed_at":"2025-04-08T09:19:39.000Z","size":74,"stargazers_count":216,"open_issues_count":4,"forks_count":23,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-04-08T13:08:42.740Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","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/revng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2016-12-15T22:45:26.000Z","updated_at":"2025-04-08T09:19:43.000Z","dependencies_parsed_at":"2024-10-13T05:41:00.903Z","dependency_job_id":"e73a5622-7c3a-4690-bf1a-7e396fb41340","html_url":"https://github.com/revng/llvmcpy","commit_stats":{"total_commits":45,"total_committers":8,"mean_commits":5.625,"dds":0.6,"last_synced_commit":"9b7e56f3fe2ac30aa5b9dc2f56d4d2121df2cef1"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revng%2Fllvmcpy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revng%2Fllvmcpy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revng%2Fllvmcpy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revng%2Fllvmcpy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/revng","download_url":"https://codeload.github.com/revng/llvmcpy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254453652,"owners_count":22073617,"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":[],"created_at":"2024-09-24T19:57:56.104Z","updated_at":"2025-05-16T02:07:24.123Z","avatar_url":"https://github.com/revng.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `llvmcpy`\n\n`llvmcpy` automatically generates Python wrappers for the [LLVM-C API](http://llvm.org/docs/doxygen/html/group__LLVMC.html).\n\n## Goal\n\nThe main goal of `llvmcpy` is to provide Python bindings for the LLVM project that are fast and require the lowest possible maintainance effort.\nTo achive this, we use CFFI to parse the (slightly adapted) LLVM-C API header files and automatically generate a set of classes and functions to interact with them in a Pythonic way.\n\nThis project is in an early stage, but allows you to run the following code:\n\n```python\nimport sys\nfrom llvmcpy import LLVMCPy\n\nllvm = LLVMCPy()\nbuffer = llvm.create_memory_buffer_with_contents_of_file(sys.argv[1])\ncontext = llvm.get_global_context()\nmodule = context.parse_ir(buffer)\nfor function in module.iter_functions():\n    for bb in function.iter_basic_blocks():\n        for instruction in bb.iter_instructions():\n            instruction.dump()\n```\n\nIt's tested on all LLVM versions from 5 to 19 and on Python from 3.7 to 3.13.\nSupporting newer versions of the LLVM-C API should be basically effortless.\n\nTo try it out, install LLVM and install `llvmcpy`:\n\n```bash\nsudo apt-get install llvm\npython -m venv venv\nsource venv/bin/activate\npip install llvmcpy\n```\n\n## Naming of the generated classes/functions\n\nThe basic idea behind this project is to take the LLVM-C API, create a class for each data type and create a method for that class for each function in the API taking an argument of that data type as first argument.\n\nThis means that the following functions:\n\n```c++\nLLVMModuleRef LLVMCloneModule (LLVMModuleRef M)\n```\n\nWill become:\n\n```python\nclass Module(object):\n    def clone(self):\n        # ...\n```\n\nNote the change in the case.\nUse `help(Module.clone)` to see which LLVM-C API function a certain method is using.\n\nEach class in `llvmcpy` is basically a wrapper around a pointer to an LLVM object.\n\nIf an API function doesn't take an LLVM object as a first argument, it will be part of the `llvm` module.\n\nAdditionally, we have some generated properties and generators for certain well known patterns in the API.\n\n### Properties\n\nFor each function starting with `LLVMGet` or `LLVMSet` in the LLVM-C API, we generate a property. For example, consider the following two functions:\n\n```c\nvoid LLVMSetValueName (LLVMValueRef Val, const char *Name);\nconst char* LLVMGetValueName(LLVMValueRef Val);\n```\n\nIn `llvmcpy` the `Get`/`Set` prefixes disappear, along with `Value` (the name of the class) and you can use them as properties of the `Value` class, e.g.:\n\n```python\nmy_value.name = \"sum\"\nprint(my_value.name)\n```\n\n### Generators\n\nThe LLVM-C API has a recurrent pattern which allows you to navigate through the hierarchy of its class hierarchy, i.e. the pair of `LLVMGetSomething` and `LLVMGetNextSomething` functions.\n`Something` can be `Function`, `BasicBlock` and so on. `llvmcpy` identifies these patterns and produces a generator method which allows you to iterate over these objects in a Pythonic way:\n\n```python\nfor function in module.iter_functions():\n    for bb in function.iter_basic_blocks():\n        for instruction in bb.iter_instructions():\n            # ...\n```\n\n## Where are my bindings?\n\nBindings are automatically generated in a lazy way.\nMultiple installations of LLVM are supported, just set the `LLVM_CONFIG` environment variable to the `llvm-config` program in the `bin/` directory of your LLVM installation and everything should work fine.\n\nThe bindings are generated in a Python script which is stored in `$XDG_CACHE_DIR/llvmcpy/` (typically `~/.cache/llvmcpy`) in a directory whose name is obtained by hashing the full path of the output of `llvm-config --prefix` concatenated with the LLVM version number.\nFor example, for LLVM 19 installed in `/usr` you'll find the API bindings in `~/.cache/llvmcpy/7fea08f2e9d5108688f692e686c8528b914eda563e7069b25ef18c49ba96d7f2-19`.\n\nTo generate the bindings, a working C preprocessor must be available in the system. By default, `cpp` (the C preprocessor part of GCC) is used. If it's not available we check if `clang` is available in the LLVM installation and use it.\n\n## License and credits\n\nThis project is developed and maintained by rev.ng Labs as part of the rev.ng project, and it's released under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frevng%2Fllvmcpy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frevng%2Fllvmcpy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frevng%2Fllvmcpy/lists"}