Name | llvmcpy JSON |
Version |
0.2.0
JSON |
| download |
home_page | None |
Summary | Python bindings for LLVM auto-generated from the LLVM-C API |
upload_time | 2024-11-22 16:30:45 |
maintainer | None |
docs_url | None |
author | None |
requires_python | None |
license | MIT License |
keywords |
llvm
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# `llvmcpy`
`llvmcpy` automatically generates Python wrappers for the [LLVM-C API](http://llvm.org/docs/doxygen/html/group__LLVMC.html).
## Goal
The main goal of `llvmcpy` is to provide Python bindings for the LLVM project that are fast and require the lowest possible maintainance effort.
To 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.
This project is in an early stage, but allows you to run the following code:
```python
import sys
from llvmcpy import LLVMCPy
llvm = LLVMCPy()
buffer = llvm.create_memory_buffer_with_contents_of_file(sys.argv[1])
context = llvm.get_global_context()
module = context.parse_ir(buffer)
for function in module.iter_functions():
for bb in function.iter_basic_blocks():
for instruction in bb.iter_instructions():
instruction.dump()
```
It's tested on all LLVM versions from 5 to 19 and on Python from 3.7 to 3.13.
Supporting newer versions of the LLVM-C API should be basically effortless.
To try it out, install LLVM and install `llvmcpy`:
```bash
sudo apt-get install llvm
python -m venv venv
source venv/bin/activate
pip install llvmcpy
```
## Naming of the generated classes/functions
The 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.
This means that the following functions:
```c++
LLVMModuleRef LLVMCloneModule (LLVMModuleRef M)
```
Will become:
```python
class Module(object):
def clone(self):
# ...
```
Note the change in the case.
Use `help(Module.clone)` to see which LLVM-C API function a certain method is using.
Each class in `llvmcpy` is basically a wrapper around a pointer to an LLVM object.
If an API function doesn't take an LLVM object as a first argument, it will be part of the `llvm` module.
Additionally, we have some generated properties and generators for certain well known patterns in the API.
### Properties
For each function starting with `LLVMGet` or `LLVMSet` in the LLVM-C API, we generate a property. For example, consider the following two functions:
```c
void LLVMSetValueName (LLVMValueRef Val, const char *Name);
const char* LLVMGetValueName(LLVMValueRef Val);
```
In `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.:
```python
my_value.name = "sum"
print(my_value.name)
```
### Generators
The 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.
`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:
```python
for function in module.iter_functions():
for bb in function.iter_basic_blocks():
for instruction in bb.iter_instructions():
# ...
```
## Where are my bindings?
Bindings are automatically generated in a lazy way.
Multiple 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.
The 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.
For example, for LLVM 19 installed in `/usr` you'll find the API bindings in `~/.cache/llvmcpy/7fea08f2e9d5108688f692e686c8528b914eda563e7069b25ef18c49ba96d7f2-19`.
To 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.
## License and credits
This project is developed and maintained by rev.ng Labs as part of the rev.ng project, and it's released under the MIT license.
Raw data
{
"_id": null,
"home_page": null,
"name": "llvmcpy",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "llvm",
"author": null,
"author_email": "Alessandro Di Federico <ale.llvmcpy@clearmind.me>",
"download_url": "https://files.pythonhosted.org/packages/87/0e/b9916a03db73008659282bd74927915c7d65ff4afea62468135a41bf6c94/llvmcpy-0.2.0.tar.gz",
"platform": null,
"description": "# `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",
"bugtrack_url": null,
"license": "MIT License",
"summary": "Python bindings for LLVM auto-generated from the LLVM-C API",
"version": "0.2.0",
"project_urls": {
"Repository": "https://github.com/revng/llvmcpy"
},
"split_keywords": [
"llvm"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "14bb519b3f62b7e7112391d5a4aea2d18f7876d87cd9489f858c5d6cdc97b05e",
"md5": "272878853f3134ba8ae3f7da4ad60805",
"sha256": "263c8879db81cceed5d15ec909184273664b80eff247b7c6c5b007096264e6b3"
},
"downloads": -1,
"filename": "llvmcpy-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "272878853f3134ba8ae3f7da4ad60805",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 15578,
"upload_time": "2024-11-22T16:30:43",
"upload_time_iso_8601": "2024-11-22T16:30:43.824065Z",
"url": "https://files.pythonhosted.org/packages/14/bb/519b3f62b7e7112391d5a4aea2d18f7876d87cd9489f858c5d6cdc97b05e/llvmcpy-0.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "870eb9916a03db73008659282bd74927915c7d65ff4afea62468135a41bf6c94",
"md5": "2732af909f2a6101017a13dc0a7d3dc0",
"sha256": "46d066518ea7fc879ae936b94a7dec2bdd4893efc5bc0d4d10688c99f696a3cb"
},
"downloads": -1,
"filename": "llvmcpy-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "2732af909f2a6101017a13dc0a7d3dc0",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 16328,
"upload_time": "2024-11-22T16:30:45",
"upload_time_iso_8601": "2024-11-22T16:30:45.710942Z",
"url": "https://files.pythonhosted.org/packages/87/0e/b9916a03db73008659282bd74927915c7d65ff4afea62468135a41bf6c94/llvmcpy-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-22 16:30:45",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "revng",
"github_project": "llvmcpy",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "llvmcpy"
}