Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/klitsche/ffigen
ffigen is a simple cli helper to quickly generate and update PHP FFI bindings for C libraries.
https://github.com/klitsche/ffigen
ffi generator php
Last synced: about 2 months ago
JSON representation
ffigen is a simple cli helper to quickly generate and update PHP FFI bindings for C libraries.
- Host: GitHub
- URL: https://github.com/klitsche/ffigen
- Owner: klitsche
- License: mit
- Created: 2020-05-08T20:14:26.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2023-01-21T22:36:06.000Z (almost 2 years ago)
- Last Synced: 2024-11-06T02:52:52.650Z (about 2 months ago)
- Topics: ffi, generator, php
- Language: PHP
- Homepage:
- Size: 130 KB
- Stars: 13
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# ffigen - a FFI bindings generator for PHP
[![Build Status](https://github.com/klitsche/ffigen/actions/workflows/test.yml/badge.svg)](https://github.com/klitsche/ffigen/actions/workflows/test.yml)
[![Test Coverage](https://api.codeclimate.com/v1/badges/74ba131ab73c58dc2864/test_coverage)](https://codeclimate.com/github/klitsche/ffigen/test_coverage)
[![Maintainability](https://api.codeclimate.com/v1/badges/74ba131ab73c58dc2864/maintainability)](https://codeclimate.com/github/klitsche/ffigen/maintainability)
[![Packagist Version](https://img.shields.io/packagist/v/klitsche/ffigen)](https://packagist.org/packages/klitsche/ffigen)`ffigen` is a simple cli helper to quickly generate and update low level PHP FFI bindings for C libraries.
It generates two PHP files out of provided C header file(s):
* `constants.php` - holding constant values
* `Methods.php` - holding function bindings as static methods plus phpdoc in a traitIt is heavily inspired by [FFIMe](https://github.com/ircmaxell/FFIMe) and depends on [PHPCParser](https://github.com/ircmaxell/php-c-parser) by ircmaxell.
__WIP__: Expect breaking changes along all 0.* pre-releases.
## Requirements
* PHP ^7.4 || ^8.0
* For examples: FFI extension must be available and enabled## Quick Start
Install in your project:
composer require --dev klitsche/ffigen
Install a c library (eg. uuid).Add a config file to your project root:
.ffigen.yml
Tweak this config file (example):```yaml
headerFiles:
- uuid/uuid.h
libraryFile: libuuid.so.1
parserClass: Klitsche\FFIGen\Examples\UUID\FFIGen\Parser
outputPath: ./
excludeConstants:
- /^(?!(FFI|UUID)_).*/
excludeMethods:
namespace: Klitsche\FFIGen\Examples\UUID
```Optional: add your own Parser class to customize pre oder post processing logic (example):
```php
context->defineInt('_SYS_TYPES_H', 1);
$this->context->defineInt('_SYS_TIME_H', 1);
$this->context->defineInt('_TIME_H', 1);
}protected function parseHeaderFile(string $file): array
{
$file = $this->searchHeaderFilePath($file);$prependHeaderFile = '
typedef long time_t;
';
$tmpfile = tempnam(sys_get_temp_dir(), 'ffigen');
file_put_contents($tmpfile, $prependHeaderFile . file_get_contents($file));$declarations = parent::parseHeaderFile($tmpfile);
unlink($tmpfile);
return $declarations;
}private function searchHeaderFilePath(string $file): string
{
if (file_exists($file)) {
return $file;
}
foreach ($this->context->headerSearchPaths as $headerSearchPath) {
if (file_exists($headerSearchPath . '/' . $file)) {
return $headerSearchPath . '/' . $file;
}
}throw new \RuntimeException(sprintf('File not found: %s', $file));
}
}
```Do not forget to register the Parser namespace in your composer.json for autoloading (dev is okay):
```json
"autoload-dev": {
"psr-4": {
"Klitsche\\FFIGen\\Examples\\": "examples"
}
},
```Dump autoloading with
composer dump-autoload
Run ffigen to generate binding files
vendor/bin/ffigen
This generates the two files in the output path:* `constants.php` - add this to your autoloading
* `Methods.php` - add this to your own class context and use it within your own high level php libraryDo not forget to add `constants.php` to your compose.json for autoloading:
```json
"autoload": {
"files": [
"tweak-path-to/constants.php",
]
},
```## Play with examples
Build docker image with preinstalled c libraries (uuid, snappy & librdkafka):
docker-compose build php74
Run uuid exampledocker-compose run --rm php74 php bin/ffigen generate -c examples/UUID/.ffigen.yml
docker-compose run --rm php74 php examples/UUID/test.php
Run snappy example (see Snappy class for a simple high level example)docker-compose run --rm php74 bin/ffigen generate -c examples/Snappy/.ffigen.yml
docker-compose run --rm php74 php examples/Snappy/test.php
Run rdkafka example (librdkafka 1.5.2 & mock cluster)docker-compose run --rm php74 bin/ffigen generate -c examples/RdKafka/.ffigen.yml
docker-compose run --rm php74 php examples/RdKafka/test.php
## Todos* [x] Add travis
* [x] Add more tests
* [ ] Add documentation
* [ ] Add support for Windows, macOS
* [ ] Add more examples (and learn from them)
* [ ] Think about multi version support
* [ ] Think about custom interface / class generation for types
* [ ] Think about clang / cpp / readelf adapter (cpp defines only & clean file, clang -c11 ast-dump=json, readelf --dyn-syms)