Skip to content

Commit 8e26588

Browse files
committed
move docs around
1 parent a69abba commit 8e26588

7 files changed

Lines changed: 354 additions & 347 deletions

File tree

pkgs/ffigen/README.md

Lines changed: 0 additions & 302 deletions
Original file line numberDiff line numberDiff line change
@@ -957,305 +957,3 @@ include-transitive-objc-categories: false
957957
</tr>
958958
</tbody>
959959
</table>
960-
961-
## FAQ
962-
963-
### Can FFIgen be used for removing underscores or renaming declarations?
964-
965-
FFIgen supports **regexp-based renaming**. The regexp must be a full match.
966-
For renaming you can use regexp groups (`$1` means group 1).
967-
968-
To renaming `clang_dispose_string` to `string_dispose` we can match it using
969-
`clang_(.*)_(.*)` and rename with `$2_$1`.
970-
971-
Here's an example of how to remove prefix underscores from any struct and its
972-
members.
973-
974-
```yaml
975-
structs:
976-
...
977-
rename:
978-
'_(.*)': '$1' # Removes prefix underscores from all structures.
979-
member-rename:
980-
'.*': # Matches any struct.
981-
'_(.*)': '$1' # Removes prefix underscores from members.
982-
```
983-
### How to generate declarations only from particular headers?
984-
985-
The default behavior is to include everything directly/transitively under
986-
each of the `entry-points` specified.
987-
988-
If you only want to have declarations directly particular header you can do so
989-
using `include-directives`. You can use **glob matching** to match header paths.
990-
991-
```yaml
992-
headers:
993-
entry-points:
994-
- 'path/to/my_header.h'
995-
include-directives:
996-
- '**my_header.h' # This glob pattern matches the header path.
997-
```
998-
### Can FFIgen filter declarations by name?
999-
1000-
FFIgen supports including/excluding declarations using full regexp matching.
1001-
1002-
Here's an example to filter functions using names:
1003-
1004-
```yaml
1005-
functions:
1006-
include:
1007-
- 'clang.*' # Include all functions starting with clang.
1008-
exclude:
1009-
- '.*dispose': # Exclude all functions ending with dispose.
1010-
```
1011-
1012-
This will include `clang_help`. But will exclude `clang_dispose`.
1013-
1014-
Note: exclude overrides include.
1015-
1016-
### How does FFIgen handle C Strings?
1017-
1018-
FFIgen treats `char*` just as any other pointer (`Pointer<Int8>`).
1019-
To convert these to/from `String`, you can use [package:ffi](https://pub.dev/packages/ffi).
1020-
Use `ptr.cast<Utf8>().toDartString()` to convert `char*` to dart `string` and
1021-
`"str".toNativeUtf8()` to convert `string` to `char*`.
1022-
1023-
### How are unnamed enums handled?
1024-
1025-
Unnamed enums are handled separately, under the key `unnamed-enums`, and are
1026-
generated as top level constants.
1027-
1028-
Here's an example that shows how to include/exclude/rename unnamed enums:
1029-
1030-
```yaml
1031-
unnamed-enums:
1032-
include:
1033-
- 'CX_.*'
1034-
exclude:
1035-
- '.*Flag'
1036-
rename:
1037-
'CXType_(.*)': '$1'
1038-
```
1039-
1040-
### How can I handle unexpected enum values?
1041-
1042-
Native enums are, by default, generated into Dart enums with `int get value` and
1043-
`fromValue(int)`. This works well in the case that your enums values are known
1044-
in advance and not going to change, and in return, you get the full benefits of
1045-
Dart enums like exhaustiveness checking.
1046-
1047-
However, if a native library adds another possible enum value after you generate
1048-
your bindings, and this new value is passed to your Dart code, this will result
1049-
in an `ArgumentError` at runtime. To fix this, you can regenerate the bindings
1050-
on the new header file, but if you wish to avoid this issue entirely, you can
1051-
tell FFIgen to generate plain Dart integers for your enum instead. To do this,
1052-
simply list your enum's name in the `as-int` section of your FFIgen config:
1053-
1054-
```yaml
1055-
enums:
1056-
as-int:
1057-
include:
1058-
- MyIntegerEnum
1059-
- '*IntegerEnum'
1060-
exclude:
1061-
- FakeIntegerEnum
1062-
```
1063-
1064-
Functions that accept or return these enums will now accept or return integers
1065-
instead, and it will be up to your code to map integer values to behavior and
1066-
handle invalid values. But your code will be future-proof against new additions
1067-
to the enums.
1068-
1069-
### Why are some struct/union declarations generated even after excluded them in config?
1070-
1071-
This happens when an excluded struct/union is a dependency to some included
1072-
declaration. (A dependency means a struct is being passed/returned by a function
1073-
or is member of another struct in some way.)
1074-
1075-
Note: If you supply `structs.dependency-only` as `opaque` FFIgen will generate
1076-
these struct dependencies as `Opaque` if they were only passed by reference
1077-
(pointer).
1078-
1079-
```yaml
1080-
structs:
1081-
dependency-only: opaque
1082-
unions:
1083-
dependency-only: opaque
1084-
```
1085-
1086-
### How to expose the native pointers?
1087-
1088-
By default, the native pointers are private, but you can use the
1089-
`symbol-address` subkey for functions/globals and make them public by matching
1090-
with its name. The pointers are then accessible via `nativeLibrary.addresses`.
1091-
1092-
Example:
1093-
1094-
```yaml
1095-
functions:
1096-
symbol-address:
1097-
include:
1098-
- 'myFunc' # Match function name.
1099-
- '.*' # Do this to expose all function pointers.
1100-
exclude: # If you only use exclude, then everything not excluded is generated.
1101-
- 'dispose'
1102-
```
1103-
1104-
### How to get typedefs to Native and Dart type of a function?
1105-
1106-
By default, these types are inline. But you can use the `expose-typedef` subkey
1107-
for functions to generate them. This will expose the Native and Dart type.
1108-
E.g. for a function named `hello` the generated typedefs are named as
1109-
`NativeHello` and `DartHello`.
1110-
1111-
Example:
1112-
1113-
```yaml
1114-
functions:
1115-
expose-typedefs:
1116-
include:
1117-
- 'myFunc' # Match function name.
1118-
- '.*' # Do this to expose types for all functions.
1119-
exclude: # If you only use exclude, then everything not excluded is generated.
1120-
- 'dispose'
1121-
```
1122-
1123-
### How are Structs/Unions/Enums that are referred to via typedefs handled?
1124-
1125-
Named declarations use their own names even when inside another typedef.
1126-
However, unnamed declarations inside typedefs take the name of the _first_
1127-
typedef that refers to them.
1128-
1129-
### Why are some typedefs not generated?
1130-
1131-
The following typedefs are not generated:
1132-
- They are not referred to anywhere in the included declarations.
1133-
- They refer to a struct/union having the same name as itself.
1134-
- They refer to a boolean, enum, inline array, Handle or any unsupported type.
1135-
1136-
### How are macros handled?
1137-
1138-
FFIgen uses `clang`'s own compiler frontend to parse and traverse the `C`
1139-
header files. FFIgen expands the macros using `clang`'s macro expansion and
1140-
then traverses the expanded code. To do this, FFIgen generates temporary files
1141-
in a system tmp directory.
1142-
1143-
A custom temporary directory can be specified by setting the `TEST_TMPDIR`
1144-
environment variable.
1145-
1146-
### What are these logs generated by FFIgen and how to fix them?
1147-
1148-
FFIgen can sometimes generate a lot of logs, especially when it's parsing a lot
1149-
of code.
1150-
- `SEVERE` logs are something you *definitely need to address*. They can be
1151-
caused due to syntax errors, or more generally missing header files
1152-
(which need to be specified using `compiler-opts` in config).
1153-
- `WARNING` logs are something *you can ignore*, but should probably look into.
1154-
These are mostly indications of declarations FFIgen couldn't generate due
1155-
to limitations of `dart:ffi`, private declarations (which can be resolved
1156-
by renaming them via FFIgen's config) or other minor issues in the config
1157-
file itself.
1158-
- Everything else can be safely ignored. Its purpose is to simply let you know
1159-
what FFIgen is doing.
1160-
- The verbosity of the logs can be changed by adding a flag with
1161-
the log level, e.g. `dart run ffigen --verbose <level>`.
1162-
Level options are `[all, fine, info (default), warning, severe]`.
1163-
The `all` and `fine` will print a ton of logs are meant for debugging
1164-
purposes only.
1165-
1166-
### How can type definitions be shared?
1167-
1168-
FFIgen can share type definitions using symbol files.
1169-
- A package can generate a symbol file using the `output.symbol-file` config.
1170-
- And another package can then import this, using `import.symbol-files` config.
1171-
- Doing so will reuse all the types such as Struct/Unions, and will automatically
1172-
exclude generating other types (E.g. functions, enums, macros).
1173-
1174-
Checkout `examples/shared_bindings` for details.
1175-
1176-
For manually reusing definitions from another package, the `library-imports`
1177-
and `type-map` config can be used.
1178-
1179-
### How does ObjC method filtering work?
1180-
1181-
Methods and properties on ObjC interfaces and protocols can be filtered using
1182-
the `member-filter` option under `objc-interfaces` and `objc-protocols`. For
1183-
simplicity we'll focus on interface methods, but the same rules apply to
1184-
properties and protocols. There are two parts to the filtering process: matching
1185-
the interface, and then filtering the method.
1186-
1187-
The syntax of `member-filter` is a YAML map from a pattern to some
1188-
`include`/`exclude` rules, and `include` and `exclude` are each a list of
1189-
patterns.
1190-
1191-
```yaml
1192-
objc-interfaces:
1193-
member-filter:
1194-
MyInterface: # Matches an interface.
1195-
include:
1196-
- "someMethod:withArg:" # Matches a method.
1197-
exclude:
1198-
- someOtherMethod # Matches a method.
1199-
```
1200-
1201-
The interface matching logic is the same as the matching logic for the
1202-
`member-rename` option:
1203-
1204-
- The pattern is compared against the original name of the interface (before any
1205-
renaming is applied).
1206-
- The pattern may be a string or a regexp, but in either case they must match
1207-
the entire interface name.
1208-
- If the pattern contains only alphanumeric characters, or `_`, it is treated as
1209-
a string rather than a regex.
1210-
- String patterns take precedence over regexps. That is, if an interface matches
1211-
both a regexp pattern, and a string pattern, it uses the string pattern's
1212-
`include`/`exclude` rules.
1213-
1214-
The method filtering logic uses the same `include`/`exclude` rules as the rest
1215-
of the config:
1216-
1217-
- `include` and `exclude` are a list of patterns.
1218-
- The patterns are compared against the original name of the method, before
1219-
renaming.
1220-
- The patterns can be strings or regexps, but must match the entire method name.
1221-
- The method name is in ObjC selector syntax, which means that the method name
1222-
and all the external parameter names are concatenated together with `:`
1223-
characters. This is the same name you'll see in ObjC's API documentation.
1224-
- **NOTE:** Since the pattern must match the entire method name, and most ObjC
1225-
method names end with a `:`, it's a good idea to surround the pattern with
1226-
quotes, `"`. Otherwise, YAML will think you're defining a map key.
1227-
- If no `include` or `exclude` rules are defined, all methods are included,
1228-
regardless of the top level `exclude-all-by-default` rule.
1229-
- If only `include` rules are `defined`, all non-matching methods are excluded.
1230-
- If only `exclude` rules are `defined`, all non-matching methods are included.
1231-
- If both `include` and `exclude` rules are defined, the `exclude` rules take
1232-
precedence. That is, if a method name matches both an `include` rule and an
1233-
`exclude` rule, the method is excluded. All non-matching methods are also
1234-
excluded.
1235-
1236-
The property filtering rules live in the same `objc-interfaces.member-filter`
1237-
option as the methods. There is no distinction between methods and properties in
1238-
the filters. The protocol filtering rules live in
1239-
`objc-protocols.member-filter`.
1240-
1241-
### How do I generate bindings for Apple APIs?
1242-
1243-
It can be tricky to locate header files containing Apple's ObjC frameworks, and
1244-
the paths can vary between computers depending on which version of Xcode you are
1245-
using and where it is installed. So FFIgen provides the following variable
1246-
substitutions that can be used in the `headers.entry-points` list:
1247-
1248-
- `$XCODE`: Replaced with the result of `xcode-select -p`, which is the
1249-
directory where Xcode's APIs are installed.
1250-
- `$IOS_SDK`: Replaced with `xcrun --show-sdk-path --sdk iphoneos`, which is the
1251-
directory within `$XCODE` where the iOS SDK is installed.
1252-
- `$MACOS_SDK`: Replaced with `xcrun --show-sdk-path --sdk macosx`, which is the
1253-
directory within `$XCODE` where the macOS SDK is installed.
1254-
1255-
For example:
1256-
1257-
```Yaml
1258-
headers:
1259-
entry-points:
1260-
- '$MACOS_SDK/System/Library/Frameworks/Foundation.framework/Headers/NSDate.h'
1261-
```

pkgs/ffigen/doc/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
## General documentation
44

5+
- [FAQ](faq.md)
56
- [Common errors](errors.md) in FFIgen and how to deal with them.
67

78
## Objective-C specific documentation
89

9-
- [Dealing with Objective-C API versioning](objc_api_versioning.md)
1010
- [Objective-C memory management considerations](objc_gc.md)
11-
- [Dealing with iOS/macOS API differences](objc_ios_mac_differences.md)
11+
- [Dealing with OS differences](objc_os_differences.md)
1212
- [Runtime type checks in Objective-C](objc_runtime_types.md)
1313
- [Objective-C threading considerations](objc_threading.md)
14+
- [Objective-C method filtering](objc_method_filtering.md)
15+
- [Generating bindings for Apple APIs](apple_apis.md)

pkgs/ffigen/doc/apple_apis.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## Generating bindings for Apple APIs
2+
3+
It can be tricky to locate header files containing Apple's ObjC frameworks, and
4+
the paths can vary between computers depending on which version of Xcode you are
5+
using and where it is installed. So FFIgen provides the following variable
6+
substitutions that can be used in the `headers.entry-points` list:
7+
8+
- `$XCODE`: Replaced with the result of `xcode-select -p`, which is the
9+
directory where Xcode's APIs are installed.
10+
- `$IOS_SDK`: Replaced with `xcrun --show-sdk-path --sdk iphoneos`, which is the
11+
directory within `$XCODE` where the iOS SDK is installed.
12+
- `$MACOS_SDK`: Replaced with `xcrun --show-sdk-path --sdk macosx`, which is the
13+
directory within `$XCODE` where the macOS SDK is installed.
14+
15+
For example:
16+
17+
```Yaml
18+
headers:
19+
entry-points:
20+
- '$MACOS_SDK/System/Library/Frameworks/Foundation.framework/Headers/NSDate.h'
21+
```

0 commit comments

Comments
 (0)