| [](https://github.com/dart-lang/native/actions/workflows/ffigen.yml) | |
| [](https://coveralls.io/github/dart-lang/native?branch=main) | |
| [](https://pub.dev/packages/ffigen) | |
| [](https://pub.dev/packages/ffigen/publisher) | |
| ## Introduction | |
| Bindings generator for [FFI](https://dart.dev/guides/libraries/c-interop) bindings. | |
| > Note: FFIgen only supports parsing `C` headers, not `C++` headers. | |
| This bindings generator can be used to call C code or code in another language | |
| that compiles to C modules that follow the C calling convention, such as Go or | |
| Rust. For more details, see https://dart.dev/guides/libraries/c-interop. | |
| FFIgen also supports calling ObjC code. | |
| For details see https://dart.dev/guides/libraries/objective-c-interop. | |
| More FFIgen documentation can be found [here](doc/README.md). | |
| ## Getting Started | |
| This guide demonstrates how to call a custom C API from a standalone Dart | |
| application. It assumes that Dart has been set up | |
| ([instructions](https://dart.dev/get-dart)) and that LLVM is installed on the | |
| system ([instructions](#requirements)). Furthermore, it assumes that the Dart | |
| app has been created via `dart create ffigen_example`. | |
| 1. Add the utility package `package:ffi` as a dependency and the bindings | |
| generator `package:ffigen` as a dev_dependency to the pubspec of your app by | |
| running: `dart pub add ffi dev:ffigen`. | |
| 2. Write the C code and place it inside a subdirectory of your app. For this | |
| example we will place the following code in `src/add.h` and `src/add.c` | |
| respectively. It defines a simple API to add two integers in C. | |
| ```C | |
| // in src/add.h: | |
| int add(int a, int b); | |
| ``` | |
| ```C | |
| // in src/add.c: | |
| int add(int a, int b) { | |
| return a + b; | |
| } | |
| ``` | |
| 3. To generate the bindings, we will write a script using `package:ffigen` and | |
| place it under `tool/ffigen.dart`. The script instantiates and configures a | |
| `FfiGenerator`. Refer to the code comments below and the API docs to learn | |
| more about available configuration options. | |
| <!-- file://./example/add/tool/ffigen.dart --> | |
| ```dart | |
| import 'dart:io'; | |
| import 'package:ffigen/ffigen.dart'; | |
| Future<void> main() async { | |
| final packageRoot = Platform.script.resolve('../'); | |
| final generator = FfiGenerator( | |
| // Required. Output path for the generated bindings. | |
| output: Output( | |
| dart: DartOutput(path: packageRoot.resolve('lib/add.g.dart')), | |
| ), | |
| // Optional. Where to look for header files. | |
| input: Input(entryPoints: [packageRoot.resolve('src/add.h')]), | |
| // Optional. Transform and filter AST nodes. | |
| visitors: [Visitor(func: (node) => node.isIncluded = node.name == 'add')], | |
| ); | |
| await generator.generate(); | |
| } | |
| ``` | |
| 4. Run the script with `dart run tool/ffigen.dart` to generate the bindings. | |
| This will create the output `lib/add.g.dart` file, which can be imported by | |
| Dart code to access the C APIs. This command must be re-run whenever the | |
| FFIgen configuration (in `tool/ffigen.dart`) or the C sources for which | |
| bindings are generated change. | |
| 5. Import `add.g.dart` in your Dart app and call the generated methods to access | |
| the native C API: | |
| <!-- file://./example/add/lib/add.dart --> | |
| ```dart | |
| import 'add.g.dart'; | |
| void answerToLife() { | |
| print('The answer to the Ultimate Question is ${add(40, 2)}!'); | |
| } | |
| ``` | |
| 6. Before we can run the app, we need to compile the C sources. There are many | |
| ways to do that. For this example, we are using a | |
| [build hook](https://dart.dev/tools/hooks), which we define in | |
| `hook/build.dart` as follows. This build hook also requires a dependency | |
| on the `hooks`, `code_assets`, and `native_toolchain_c` helper packages, | |
| which we can add to our app by running | |
| `dart pub add hooks code_assets native_toolchain_c`. | |
| <!-- file://./example/add/hook/build.dart --> | |
| ```dart | |
| import 'package:code_assets/code_assets.dart'; | |
| import 'package:hooks/hooks.dart'; | |
| import 'package:native_toolchain_c/native_toolchain_c.dart'; | |
| void main(List<String> args) async { | |
| await build(args, (input, output) async { | |
| if (input.config.buildCodeAssets) { | |
| final builder = CBuilder.library( | |
| name: 'add', | |
| assetName: 'add.g.dart', | |
| sources: ['src/add.c'], | |
| ); | |
| await builder.run(input: input, output: output); | |
| } | |
| }); | |
| } | |
| ``` | |
| That's it! Run your app with `dart run` to see it in action! | |
| The complete and runnable example can be found in [example/add](example/add). | |
| ## More Examples | |
| The `code_asset` package contains [comprehensive examples](../code_assets/example) | |
| that showcase FFIgen. Additional examples that show how FFIgen can be used | |
| in different scenarios can also be found in the [example](example/) directory. | |
| ## Requirements | |
| LLVM (9+) must be installed on your system to use `package:ffigen`. Install it | |
| in the following way: | |
| ### Linux | |
| 1. Install libclangdev: | |
| * with apt-get: `sudo apt-get install libclang-dev`. | |
| * with dnf: `sudo dnf install clang-devel`. | |
| ### Windows | |
| 1. Install Visual Studio with C++ development support. | |
| 2. Install [LLVM](https://releases.llvm.org/download.html) or | |
| `winget install -e --id LLVM.LLVM`. | |
| #### macOS | |
| 1. Install Xcode. | |
| 2. Install Xcode command line tools: `xcode-select --install`. | |
| ## YAML Configuration Reference | |
| In addition to the Dart API shown in the "Getting Started" section, FFIgen can | |
| also be configured via YAML. Support for the YAML configuration will be | |
| eventually phased out, and using the Dart API is recommended. | |
| A YAML configuration can be either provided in the project's `pubspec.yaml` file | |
| under the key `ffigen` or via a custom YAML file. To generate bindings | |
| configured via YAML run either `dart run ffigen` if using the `pubspec.yaml` | |
| file or run `dart run ffigen --config config.yaml` where `config.yaml` is the | |
| path to your custom YAML file. | |
| The following configuration options are available: | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>Key</th> | |
| <th>Explanation</th> | |
| <th>Example</th> | |
| </tr> | |
| <colgroup> | |
| <col> | |
| <col style="width: 100px;"> | |
| </colgroup> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td>output<br><i><b>(Required)</b></i></td> | |
| <td>Output path of the generated bindings.</td> | |
| <td> | |
| ```yaml | |
| output: 'generated_bindings.dart' | |
| ``` | |
| or | |
| ```yaml | |
| output: | |
| bindings: 'generated_bindings.dart' | |
| ... | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>llvm-path</td> | |
| <td>Path to <i>llvm</i> folder.<br> FFIgen will sequentially search | |
| for `lib/libclang.so` on linux, `lib/libclang.dylib` on macOS and | |
| `bin\libclang.dll` on windows, in the specified paths.<br><br> | |
| Complete path to the dynamic library can also be supplied.<br> | |
| <i>Required</i> if FFIgen is unable to find this at default locations.</td> | |
| <td> | |
| ```yaml | |
| llvm-path: | |
| - '/usr/local/opt/llvm' | |
| - 'C:\Program Files\llvm` | |
| - '/usr/lib/llvm-11' | |
| # Specify exact path to dylib | |
| - '/usr/lib64/libclang.so' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>headers<br><i><b>(Required)</b></i></td> | |
| <td>The header entry-points and include-directives. Glob syntax is allowed.<br> | |
| If include-directives are not specified FFIgen will generate everything directly/transitively under the entry-points.</td> | |
| <td> | |
| ```yaml | |
| headers: | |
| entry-points: | |
| - 'folder/**.h' | |
| - 'folder/specific_header.h' | |
| include-directives: | |
| - '**index.h' | |
| - '**/clang-c/**' | |
| - '/full/path/to/a/header.h' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>name<br><i>(Prefer)</i></td> | |
| <td>Name of generated class.</td> | |
| <td> | |
| ```yaml | |
| name: 'SQLite' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>description<br><i>(Prefer)</i></td> | |
| <td>Dart Doc for generated class.</td> | |
| <td> | |
| ```yaml | |
| description: 'Bindings to SQLite' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>compiler-opts</td> | |
| <td>Pass compiler options to clang. You can also pass | |
| these via the command line tool.</td> | |
| <td> | |
| ```yaml | |
| compiler-opts: | |
| - '-I/usr/lib/llvm-9/include/' | |
| ``` | |
| and/or via the command line - | |
| ```bash | |
| dart run ffigen --compiler-opts "-I/headers | |
| -L 'path/to/folder name/file'" | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>compiler-opts-automatic.macos.include-c-standard-library</td> | |
| <td>Tries to automatically find and add C standard library path to | |
| compiler-opts on macOS.<br> | |
| <b>Default: true</b> | |
| </td> | |
| <td> | |
| ```yaml | |
| compiler-opts-automatic: | |
| macos: | |
| include-c-standard-library: false | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| functions<br><br>structs<br><br>unions<br><br>enums<br><br> | |
| unnamed-enums<br><br>macros<br><br>globals | |
| </td> | |
| <td>Filters for declarations.<br><b>Default: all are included.</b><br><br> | |
| Options -<br> | |
| - Include/Exclude declarations.<br> | |
| - Rename declarations.<br> | |
| - Rename enum, struct, and union members, function parameters, and ObjC | |
| interface and protocol methods and properties.<br> | |
| - Expose symbol-address for functions and globals.<br> | |
| </td> | |
| <td> | |
| ```yaml | |
| functions: | |
| include: # 'exclude' is also available. | |
| # Matches using regexp. | |
| - [a-z][a-zA-Z0-9]* | |
| # '.' matches any character. | |
| - prefix.* | |
| # Matches with exact name | |
| - someFuncName | |
| # Full names have higher priority. | |
| - anotherName | |
| rename: | |
| # Regexp groups based replacement. | |
| 'clang_(.*)': '$1' | |
| 'clang_dispose': 'dispose' | |
| # Removes '_' from beginning. | |
| '_(.*)': '$1' | |
| symbol-address: | |
| # Used to expose symbol address. | |
| include: | |
| - myFunc | |
| structs: | |
| rename: | |
| # Removes prefix underscores | |
| # from all structures. | |
| '_(.*)': '$1' | |
| member-rename: | |
| '.*': # Matches any struct. | |
| # Removes prefix underscores | |
| # from members. | |
| '_(.*)': '$1' | |
| enums: | |
| rename: | |
| # Regexp groups based replacement. | |
| 'CXType_(.*)': '$1' | |
| member-rename: | |
| '(.*)': # Matches any enum. | |
| # Removes '_' from beginning | |
| # enum member name. | |
| '_(.*)': '$1' | |
| # Full names have higher priority. | |
| 'CXTypeKind': | |
| # $1 keeps only the 1st | |
| # group i.e only '(.*)'. | |
| 'CXType(.*)': '$1' | |
| as-int: | |
| # These enums will be generated as Dart integers instead of Dart enums | |
| include: | |
| - MyIntegerEnum | |
| globals: | |
| exclude: | |
| - aGlobal | |
| rename: | |
| # Removes '_' from | |
| # beginning of a name. | |
| '_(.*)': '$1' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>typedefs</td> | |
| <td>Filters for referred typedefs.<br><br> | |
| Options -<br> | |
| - Include/Exclude (referred typedefs only).<br> | |
| - Rename typedefs.<br><br> | |
| Note: By default, typedefs that are not referred to anywhere will not be generated. | |
| </td> | |
| <td> | |
| ```yaml | |
| typedefs: | |
| exclude: | |
| # Typedefs starting with `p` are not generated. | |
| - 'p.*' | |
| rename: | |
| # Removes '_' from beginning of a typedef. | |
| '_(.*)': '$1' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>include-unused-typedefs</td> | |
| <td> | |
| Also generate typedefs that are not referred to anywhere. | |
| <br> | |
| <b>Default: false</b> | |
| </td> | |
| <td> | |
| ```yaml | |
| include-unused-typedefs: true | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>functions.expose-typedefs</td> | |
| <td>Generate the typedefs to Native and Dart type of a function<br> | |
| <b>Default: Inline types are used and no typedefs to Native/Dart | |
| type are generated.</b> | |
| </td> | |
| <td> | |
| ```yaml | |
| functions: | |
| expose-typedefs: | |
| include: | |
| # Match function name. | |
| - 'myFunc' | |
| # Do this to expose types for all function. | |
| - '.*' | |
| exclude: | |
| # If you only use exclude, then everything | |
| # not excluded is generated. | |
| - 'dispose' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>functions.leaf</td> | |
| <td>Set isLeaf:true for functions.<br> | |
| <b>Default: all functions are excluded.</b> | |
| </td> | |
| <td> | |
| ```yaml | |
| functions: | |
| leaf: | |
| include: | |
| # Match function name. | |
| - 'myFunc' | |
| # Do this to set isLeaf:true for all functions. | |
| - '.*' | |
| exclude: | |
| # If you only use exclude, then everything | |
| # not excluded is generated. | |
| - 'dispose' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>functions.variadic-arguments</td> | |
| <td>Generate multiple functions with different variadic arguments.<br> | |
| <b>Default: var args for any function are ignored.</b> | |
| </td> | |
| <td> | |
| ```yaml | |
| functions: | |
| variadic-arguments: | |
| myfunc: | |
| // Native C types are supported | |
| - [int, unsigned char, long*, float**] | |
| // Common C typedefs (stddef.h) are supported too | |
| - [uint8_t, intptr_t, size_t, wchar_t*] | |
| // Structs/Unions/Typedefs from generated code or a library import can be referred too. | |
| - [MyStruct*, my_custom_lib.CustomUnion] | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>structs.pack</td> | |
| <td>Override the @Packed(X) annotation for generated structs.<br><br> | |
| <i>Options - none, 1, 2, 4, 8, 16</i><br> | |
| You can use RegExp to match with the <b>generated</b> names.<br><br> | |
| Note: Ffigen can only reliably identify packing specified using | |
| __attribute__((__packed__)). However, structs packed using | |
| `#pragma pack(...)` or any other way could <i>potentially</i> be incorrect | |
| in which case you can override the generated annotations. | |
| </td> | |
| <td> | |
| ```yaml | |
| structs: | |
| pack: | |
| # Matches with the generated name. | |
| 'NoPackStruct': none # No packing | |
| '.*': 1 # Pack all structs with value 1 | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>comments</td> | |
| <td>Extract documentation comments for declarations.<br> | |
| The style and length of the comments recognized can be specified with the following options- <br> | |
| <i>style: doxygen(default) | any </i><br> | |
| <i>length: brief | full(default) </i><br> | |
| If you want to disable all comments you can also pass<br> | |
| comments: false. | |
| </td> | |
| <td> | |
| ```yaml | |
| comments: | |
| style: any | |
| length: full | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>structs.dependency-only<br><br> | |
| unions.dependency-only | |
| </td> | |
| <td>If `opaque`, generates empty `Opaque` structs/unions if they | |
| were not included in config (but were added since they are a dependency) and | |
| only passed by reference(pointer).<br> | |
| <i>Options - full(default) | opaque</i><br> | |
| </td> | |
| <td> | |
| ```yaml | |
| structs: | |
| dependency-only: opaque | |
| unions: | |
| dependency-only: opaque | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>sort</td> | |
| <td>Sort the bindings according to name.<br> | |
| <b>Default: false</b>, i.e keep the order as in the source files. | |
| </td> | |
| <td> | |
| ```yaml | |
| sort: true | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>use-supported-typedefs</td> | |
| <td>Should automatically map typedefs, E.g uint8_t => Uint8, int16_t => Int16, size_t => Size etc.<br> | |
| <b>Default: true</b> | |
| </td> | |
| <td> | |
| ```yaml | |
| use-supported-typedefs: true | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>use-dart-handle</td> | |
| <td>Should map `Dart_Handle` to `Handle`.<br> | |
| <b>Default: true</b> | |
| </td> | |
| <td> | |
| ```yaml | |
| use-dart-handle: true | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>ignore-source-errors</td> | |
| <td>Where to ignore compiler warnings/errors in source header files.<br> | |
| <b>Default: false</b> | |
| </td> | |
| <td> | |
| ```yaml | |
| ignore-source-errors: true | |
| ``` | |
| and/or via the command line - | |
| ```bash | |
| dart run ffigen --ignore-source-errors | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>silence-enum-warning</td> | |
| <td>Where to silence warning for enum integer type mimicking.<br> | |
| The integer type used for enums is implementation-defined, and not part of | |
| the ABI. FFIgen tries to mimic the integer sizes chosen by the most common | |
| compilers for the various OS and architecture combinations.<br> | |
| <b>Default: false</b> | |
| </td> | |
| <td> | |
| ```yaml | |
| silence-enum-warning: true | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>exclude-all-by-default</td> | |
| <td> | |
| When a declaration filter (eg `functions:` or `structs:`) is empty or | |
| unset, it defaults to including everything. If this flag is enabled, the | |
| default behavior is to exclude everything instead.<br> | |
| <b>Default: false</b> | |
| </td> | |
| <td> | |
| ```yaml | |
| exclude-all-by-default: true | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>preamble</td> | |
| <td>Raw header of the file, pasted as-it-is.</td> | |
| <td> | |
| ```yaml | |
| preamble: | | |
| // ignore_for_file: camel_case_types, non_constant_identifier_names | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>library-imports</td> | |
| <td>Specify library imports for use in type-map.<br><br> | |
| Note: ffi (dart:ffi) is already available as a predefined import. | |
| </td> | |
| <td> | |
| ```yaml | |
| library-imports: | |
| custom_lib: 'package:some_pkg/some_file.dart' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>type-map</td> | |
| <td>Map types like integers, typedefs, structs, unions to any other type.<br><br> | |
| <b>Sub-fields</b> - <i>typedefs</i>, <i>structs</i>, <i>unions</i>, <i>ints</i><br><br> | |
| <b><i>lib</i></b> must be specified in <i>library-imports</i> or be one of a predefined import. | |
| </td> | |
| <td> | |
| ```yaml | |
| type-map: | |
| 'native-types': # Targets native types. | |
| 'char': | |
| 'lib': 'pkg_ffi' # predefined import. | |
| 'c-type': 'Char' | |
| # For native-types dart-type can be be int, double or float | |
| # but same otherwise. | |
| 'dart-type': 'int' | |
| 'int': | |
| 'lib': 'custom_lib' | |
| 'c-type': 'CustomType4' | |
| 'dart-type': 'int' | |
| 'typedefs': # Targets typedefs. | |
| 'my_type1': | |
| 'lib': 'custom_lib' | |
| 'c-type': 'CustomType' | |
| 'dart-type': 'CustomType' | |
| 'structs': # Targets structs. | |
| 'my_type2': | |
| 'lib': 'custom_lib' | |
| 'c-type': 'CustomType2' | |
| 'dart-type': 'CustomType2' | |
| 'unions': # Targets unions. | |
| 'my_type3': | |
| 'lib': 'custom_lib' | |
| 'c-type': 'CustomType3' | |
| 'dart-type': 'CustomType3' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>ffi-native</td> | |
| <td> | |
| <b>WARNING:</b> Native support is EXPERIMENTAL. The API may change | |
| in a breaking way without notice. | |
| <br><br> | |
| Generate `@Native` bindings instead of bindings using `DynamicLibrary` or `lookup`. | |
| </td> | |
| <td> | |
| ```yaml | |
| ffi-native: | |
| asset-id: 'package:some_pkg/asset' # Optional, was assetId in previous versions | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>language</td> | |
| <td> | |
| <b>WARNING:</b> Other language support is EXPERIMENTAL. The API may change | |
| in a breaking way without notice. | |
| <br><br> | |
| Choose the input language. Must be one of 'c', or 'objc'. Defaults to 'c'. | |
| </td> | |
| <td> | |
| ```yaml | |
| language: 'objc' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>output.objc-bindings</td> | |
| <td> | |
| Choose where the generated ObjC code (if any) is placed. The default path | |
| is `'${output.bindings}.m'`, so if your Dart bindings are in | |
| `generated_bindings.dart`, your ObjC code will be in | |
| `generated_bindings.dart.m`. | |
| <br><br> | |
| This ObjC file will only be generated if it's needed. If it is generated, | |
| it must be compiled into your package, as part of a flutter plugin or | |
| build.dart script. If your package already has some sort of native build, | |
| you can simply add this generated ObjC file to that build. | |
| </td> | |
| <td> | |
| ```yaml | |
| output: | |
| ... | |
| objc-bindings: 'generated_bindings.m' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>output.symbol-file</td> | |
| <td>Generates a symbol file yaml containing all types defined in the generated output.</td> | |
| <td> | |
| ```yaml | |
| output: | |
| ... | |
| symbol-file: | |
| # Although file paths are supported here, prefer Package Uri's here | |
| # so that other pacakges can use them. | |
| output: 'package:some_pkg/symbols.yaml' | |
| import-path: 'package:some_pkg/base.dart' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td>import.symbol-files</td> | |
| <td>Import symbols from a symbol file. Used for sharing type definitions from other pacakges.</td> | |
| <td> | |
| ```yaml | |
| import: | |
| symbol-files: | |
| # Both package Uri and file paths are supported here. | |
| - 'package:some_pkg/symbols.yaml' | |
| - 'path/to/some/symbol_file.yaml' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| external-versions | |
| </td> | |
| <td> | |
| Interfaces, methods, and other API elements may be marked with | |
| deprecation annotations that indicate which platform version they were | |
| deprecated in. If external-versions is set, APIs that were | |
| deprecated as of the minimum version will be omitted from the | |
| generated bindings. | |
| <br><br> | |
| The minimum version is specified per platform, and an API will be | |
| generated if it is available on *any* of the targeted platform versions. | |
| If a version is not specified for a particular platform, the API's | |
| inclusion will be based purely on the platforms that have a specified | |
| minimum version. | |
| <br><br> | |
| Current support OS keys are ios and macos. If you have a use case for | |
| version checking on other OSs, please file an issue. | |
| </td> | |
| <td> | |
| ```yaml | |
| external-versions: | |
| # See https://docs.flutter.dev/reference/supported-platforms. | |
| ios: | |
| min: 12.0.0 | |
| macos: | |
| min: 10.14.0 | |
| ``` | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| ### Objective-C configuration options | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>Key</th> | |
| <th>Explanation</th> | |
| <th>Example</th> | |
| </tr> | |
| <colgroup> | |
| <col> | |
| <col style="width: 100px;"> | |
| </colgroup> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td> | |
| objc-interfaces<br><br> | |
| objc-protocols<br><br> | |
| objc-categories | |
| </td> | |
| <td> | |
| Filters for Objective-C interface, protocol, and category declarations. | |
| This option works the same as other declaration filters like `functions` | |
| and `structs`. | |
| </td> | |
| <td> | |
| ```yaml | |
| objc-interfaces: | |
| include: | |
| # Includes a specific interface. | |
| - 'MyInterface' | |
| # Includes all interfaces starting with "NS". | |
| - 'NS.*' | |
| exclude: | |
| # Override the above NS.* inclusion, to exclude NSURL. | |
| - 'NSURL' | |
| rename: | |
| # Removes '_' prefix from interface names. | |
| '_(.*)': '$1' | |
| objc-protocols: | |
| include: | |
| # Generates bindings for a specific protocol. | |
| - MyProtocol | |
| objc-categories: | |
| include: | |
| # Generates bindings for a specific category. | |
| - MyCategory | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| objc-interfaces.module<br><br> | |
| objc-protocols.module | |
| </td> | |
| <td> | |
| Adds a module prefix to the interface/protocol name when loading it | |
| from the dylib. This is only relevant for ObjC headers that are generated | |
| wrappers for a Swift library. See example/swift for more information. | |
| <br><br> | |
| This is not necessary for objc-categories. | |
| </td> | |
| <td> | |
| ```yaml | |
| headers: | |
| entry-points: | |
| # Generated by swiftc to wrap foo_lib.swift. | |
| - 'foo_lib-Swift.h' | |
| objc-interfaces: | |
| include: | |
| # Eg, foo_lib contains a set of classes prefixed with FL. | |
| - 'FL.*' | |
| module: | |
| # Use 'foo_lib' as the module name for all the FL.* classes. | |
| # We don't match .* here because other classes like NSString | |
| # shouldn't be given a module prefix. | |
| 'FL.*': 'foo_lib' | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| objc-interfaces.member-filter<br><br> | |
| objc-protocols.member-filter<br><br> | |
| objc-categories.member-filter | |
| </td> | |
| <td> | |
| Filters interface and protocol methods and properties. This is a map from | |
| interface name to a list of method include and exclude rules. The | |
| interface name can be a regexp. The include and exclude rules work exactly | |
| like any other declaration. See | |
| <a href="#how-does-objc-method-filtering-work">below</a> for more details. | |
| </td> | |
| <td> | |
| ```yaml | |
| objc-interfaces: | |
| member-filter: | |
| MyInterface: | |
| include: | |
| - "someMethod:withArg:" | |
| # Since MyInterface has an include rule, all other methods | |
| # are excluded by default. | |
| objc-protocols: | |
| member-filter: | |
| NS.*: # Matches all protocols starting with NS. | |
| exclude: | |
| - copy.* # Remove all copy methods from these protocols. | |
| objc-categories: | |
| member-filter: | |
| MyCategory: | |
| include: | |
| - init.* # Include all init methods. | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| include-transitive-objc-interfaces<br><br> | |
| include-transitive-objc-protocols | |
| </td> | |
| <td> | |
| By default, Objective-C interfaces and protocols that are not directly | |
| included by the inclusion rules, but are transitively depended on by | |
| the inclusions, are not fully code genned. Transitively included | |
| interfaces are generated as stubs, and transitive protocols are omitted. | |
| <br><br> | |
| If these flags are enabled, transitively included interfaces and protocols | |
| are fully code genned. | |
| <br><br> | |
| <b>Default: false</b> | |
| </td> | |
| <td> | |
| ```yaml | |
| include-transitive-objc-interfaces: true | |
| include-transitive-objc-protocols: true | |
| ``` | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| include-transitive-objc-categories | |
| </td> | |
| <td> | |
| By default, if an Objective-C interface is included in the bindings, all | |
| the categories that extend it are also included. To filter them, set this | |
| flag to false, then use objc-categories to include/exclude particular | |
| categories. | |
| <br><br> | |
| Transitive categories are generated by default because it's not always | |
| obvious from the Apple documentation which interface methods are declared | |
| directly in the interface, and which are declared in categories. So it may | |
| appear that the interface is missing methods, when in fact those methods | |
| are part of a category. This would be a difficult problem to diagnose if | |
| transitive categories were not generated by default. | |
| <br><br> | |
| <b>Default: true</b> | |
| </td> | |
| <td> | |
| ```yaml | |
| include-transitive-objc-categories: false | |
| ``` | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> |