Skip to content
This repository has been archived by the owner on Jan 28, 2024. It is now read-only.

Fix generated asset/assetId property for ffi-native #634

Merged
merged 7 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
generate a typedef for the `Function`.
- Use Dart wrapper types in args and returns of ObjCBlocks.
- Bump min SDK version to 3.2.0-114.0.dev.
- Renamed `asset` to `assetId` for `ffi-native`
nmfisher marked this conversation as resolved.
Show resolved Hide resolved

# 9.0.1

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ type-map:

```yaml
ffi-native:
asset: 'myasset' # Optional.
assetId: 'myasset' # Optional.
```
</td>
</tr>
Expand Down
2 changes: 1 addition & 1 deletion example/ffinative/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

name: NativeLibrary
ffi-native:
# asset: 'assetname' # (optional)
assetId: 'assetname' # (optional)
nmfisher marked this conversation as resolved.
Show resolved Hide resolved
description: Bindings to `headers/example.h`.
output: 'generated_bindings.dart'
headers:
Expand Down
14 changes: 9 additions & 5 deletions example/ffinative/generated_bindings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,40 @@
import 'dart:ffi' as ffi;

/// Adds 2 integers.
@ffi.Native<ffi.Int Function(ffi.Int, ffi.Int)>(symbol: 'sum')
@ffi.Native<ffi.Int Function(ffi.Int, ffi.Int)>(
symbol: 'sum', assetId: 'assetname')
external int sum(
int a,
int b,
);

/// Subtracts 2 integers.
@ffi.Native<ffi.Int Function(ffi.Int, ffi.Int)>(symbol: 'subtract')
@ffi.Native<ffi.Int Function(ffi.Int, ffi.Int)>(
symbol: 'subtract', assetId: 'assetname')
external int subtract(
int a,
int b,
);

/// Multiplies 2 integers, returns pointer to an integer,.
@ffi.Native<ffi.Pointer<ffi.Int> Function(ffi.Int, ffi.Int)>(symbol: 'multiply')
@ffi.Native<ffi.Pointer<ffi.Int> Function(ffi.Int, ffi.Int)>(
symbol: 'multiply', assetId: 'assetname')
external ffi.Pointer<ffi.Int> multiply(
int a,
int b,
);

/// Divides 2 integers, returns pointer to a float.
@ffi.Native<ffi.Pointer<ffi.Float> Function(ffi.Int, ffi.Int)>(symbol: 'divide')
@ffi.Native<ffi.Pointer<ffi.Float> Function(ffi.Int, ffi.Int)>(
symbol: 'divide', assetId: 'assetname')
external ffi.Pointer<ffi.Float> divide(
int a,
int b,
);

/// Divides 2 floats, returns a pointer to double.
@ffi.Native<ffi.Pointer<ffi.Double> Function(ffi.Float, ffi.Float)>(
symbol: 'dividePrecision')
symbol: 'dividePrecision', assetId: 'assetname')
external ffi.Pointer<ffi.Double> dividePrecision(
double a,
double b,
Expand Down
4 changes: 2 additions & 2 deletions ffigen.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -418,12 +418,12 @@
"type": "object",
"additionalProperties": false,
"properties": {
"asset": {
"assetId": {
"type": "string"
}
},
"required": [
"asset"
"assetId"
]
}
]
Expand Down
4 changes: 2 additions & 2 deletions lib/src/code_generator/func.dart
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ class Func extends LookUpBinding {
functionType.getFfiDartType(w, writeArgumentNames: false);

if (ffiNativeConfig.enabled) {
final assetString = ffiNativeConfig.asset != null
? ", asset: '${ffiNativeConfig.asset}'"
final assetString = ffiNativeConfig.assetId != null
? ", assetId: '${ffiNativeConfig.assetId}'"
: '';
final isLeafString = isLeaf ? ', isLeaf: true' : '';
s.write(
Expand Down
4 changes: 2 additions & 2 deletions lib/src/config_provider/config_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -384,9 +384,9 @@ class ObjCModulePrefixer {

class FfiNativeConfig {
final bool enabled;
final String? asset;
final String? assetId;

const FfiNativeConfig({required this.enabled, this.asset});
const FfiNativeConfig({required this.enabled, this.assetId});
}

class SymbolFile {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/config_provider/spec_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,6 @@ FfiNativeConfig ffiNativeExtractor(dynamic yamlConfig) {
final yamlMap = yamlConfig as Map?;
return FfiNativeConfig(
enabled: true,
asset: yamlMap?[strings.ffiNativeAsset] as String?,
assetId: yamlMap?[strings.ffiNativeAsset] as String?,
);
}
2 changes: 1 addition & 1 deletion lib/src/strings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ const doubleNaN = 'double.nan';
const dartHandleUsr = 'c:@S@_Dart_Handle';

const ffiNative = 'ffi-native';
const ffiNativeAsset = 'asset';
const ffiNativeAsset = 'assetId';

Directory? _tmpDir;

Expand Down
3 changes: 3 additions & 0 deletions test/ffi_native_test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Ignore files generated by clang on windows.
native_test.exp
native_test.lib
122 changes: 122 additions & 0 deletions test/ffi_native_test/_expected_ffi_native_test_bindings.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// ignore_for_file: camel_case_types, non_constant_identifier_names

// AUTO GENERATED FILE, DO NOT EDIT.
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint
import 'dart:ffi' as ffi;

@ffi.Native<ffi.Bool Function(ffi.Bool)>(
symbol: 'Function1Bool', assetId: 'native_test')
external bool Function1Bool(
bool x,
);

@ffi.Native<ffi.Uint8 Function(ffi.Uint8)>(
symbol: 'Function1Uint8', assetId: 'native_test')
external int Function1Uint8(
int x,
);

@ffi.Native<ffi.Uint16 Function(ffi.Uint16)>(
symbol: 'Function1Uint16', assetId: 'native_test')
external int Function1Uint16(
int x,
);

@ffi.Native<ffi.Uint32 Function(ffi.Uint32)>(
symbol: 'Function1Uint32', assetId: 'native_test')
external int Function1Uint32(
int x,
);

@ffi.Native<ffi.Uint64 Function(ffi.Uint64)>(
symbol: 'Function1Uint64', assetId: 'native_test')
external int Function1Uint64(
int x,
);

@ffi.Native<ffi.Int8 Function(ffi.Int8)>(
symbol: 'Function1Int8', assetId: 'native_test')
external int Function1Int8(
int x,
);

@ffi.Native<ffi.Int16 Function(ffi.Int16)>(
symbol: 'Function1Int16', assetId: 'native_test')
external int Function1Int16(
int x,
);

@ffi.Native<ffi.Int32 Function(ffi.Int32)>(
symbol: 'Function1Int32', assetId: 'native_test')
external int Function1Int32(
int x,
);

@ffi.Native<ffi.Int64 Function(ffi.Int64)>(
symbol: 'Function1Int64', assetId: 'native_test')
external int Function1Int64(
int x,
);

@ffi.Native<ffi.IntPtr Function(ffi.IntPtr)>(
symbol: 'Function1IntPtr', assetId: 'native_test')
external int Function1IntPtr(
int x,
);

@ffi.Native<ffi.UintPtr Function(ffi.UintPtr)>(
symbol: 'Function1UintPtr', assetId: 'native_test')
external int Function1UintPtr(
int x,
);

@ffi.Native<ffi.Float Function(ffi.Float)>(
symbol: 'Function1Float', assetId: 'native_test')
external double Function1Float(
double x,
);

@ffi.Native<ffi.Double Function(ffi.Double)>(
symbol: 'Function1Double', assetId: 'native_test')
external double Function1Double(
double x,
);

@ffi.Native<ffi.Pointer<Struct1> Function()>(
symbol: 'getStruct1', assetId: 'native_test')
external ffi.Pointer<Struct1> getStruct1();

@ffi.Native<Struct3 Function(ffi.Int, ffi.Int, ffi.Int)>(
symbol: 'Function1StructReturnByValue', assetId: 'native_test')
external Struct3 Function1StructReturnByValue(
int a,
int b,
int c,
);

@ffi.Native<ffi.Int Function(Struct3)>(
symbol: 'Function1StructPassByValue', assetId: 'native_test')
external int Function1StructPassByValue(
Struct3 sum_a_b_c,
);

final class Struct1 extends ffi.Struct {
@ffi.Int8()
external int a;

@ffi.Array.multi([3, 1, 2])
external ffi.Array<ffi.Array<ffi.Array<ffi.Int32>>> data;
}

final class Struct3 extends ffi.Struct {
@ffi.Int()
external int a;

@ffi.Int()
external int b;

@ffi.Int()
external int c;
}
129 changes: 129 additions & 0 deletions test/ffi_native_test/build_test_dylib.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
nmfisher marked this conversation as resolved.
Show resolved Hide resolved
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// =======================================================================
/// ==== Script to generate dynamic library for native_function_tests =====
/// =======================================================================
/// This Script effectively calls the following (but user can provide
/// command line args which will replace the defaults shown below)-
///
/// Linux:
/// ```
/// clang -shared -fpic native_test.c -o native_test.so
/// ```
/// MacOS:
/// ```
/// clang -shared -fpic native_test.c -o native_test.dylib
/// ```
/// Windows:
/// ```
/// call clang -shared native_test.c -o native_test.dll -Wl,"/DEF:native_test.def"
/// del native_test.exp
/// del native_test.lib
/// ```
/// =======================================================================
/// =======================================================================
/// =======================================================================

import 'dart:io';

const macOS = 'macos';
const windows = 'windows';
const linux = 'linux';

Map<String, Options> platformOptions = {
linux: Options(
outputfilename: 'native_test.so',
sharedFlag: '-shared',
inputHeader: 'native_test.c',
fPIC: '-fpic',
),
windows: Options(
outputfilename: 'native_test.dll',
sharedFlag: '-shared',
inputHeader: 'native_test.c',
moduleDefPath: '-Wl,/DEF:native_test.def',
),
macOS: Options(
outputfilename: 'native_test.dylib',
sharedFlag: '-shared',
inputHeader: 'native_test.c',
fPIC: '-fpic',
),
};

void main(List<String> arguments) {
print('Building Dynamic Library for Native Tests... ');
final options = getPlatformOptions()!;

// Run clang compiler to generate the dynamic library.
final processResult = runClangProcess(options);
printSuccess(processResult, options);
}

/// Calls the clang compiler.
ProcessResult runClangProcess(Options options) {
final result = Process.runSync(
'clang',
[
options.sharedFlag,
options.fPIC,
options.inputHeader,
'-o',
options.outputfilename,
options.moduleDefPath,
'-Wno-nullability-completeness',
],
);
return result;
}

/// Prints success message (or process error if any).
void printSuccess(ProcessResult result, Options options) {
print(result.stdout);
if ((result.stderr as String).isEmpty) {
print('Generated file: ${options.outputfilename}');
} else {
print(result.stderr);
}
}

/// Get options based on current platform.
Options? getPlatformOptions() {
if (Platform.isMacOS) {
return platformOptions[macOS];
} else if (Platform.isWindows) {
return platformOptions[windows];
} else if (Platform.isLinux) {
return platformOptions[linux];
} else {
throw Exception('Unknown Platform.');
}
}

/// Hold options which would be passed to clang.
class Options {
/// Name of dynamic library to generate.
final String outputfilename;

/// Tells compiler to generate a shared library.
final String sharedFlag;

/// Flag for generating Position Independant Code (Not used on windows).
final String fPIC;

/// Input file.
final String inputHeader;

/// Path to `.def` file containing symbols to export, windows use only.
final String moduleDefPath;

Options({
required this.outputfilename,
required this.sharedFlag,
required this.inputHeader,
this.fPIC = '',
this.moduleDefPath = '',
});
}
Loading
Loading