Skip to content

RFC: feat: allow omission of dart-opaque feature #2662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 5, 2025
Merged
Show file tree
Hide file tree
Changes from 5 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
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ impl WireRustCodecCstGeneratorDecoderTrait for BoxedWireRustCodecCstGenerator<'_
body: "flutter_rust_bridge::for_generated::new_leak_box_ptr(value)".to_owned(),
target: Target::Io,
needs_ffigen: true,
cargo_feature: None,
}
.into(),
..Default::default()
Expand All @@ -110,6 +111,7 @@ impl WireRustCodecCstGeneratorDecoderTrait for BoxedWireRustCodecCstGenerator<'_
),
target: Target::Io,
needs_ffigen: true,
cargo_feature: None,
}
.into(),
..Default::default()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,6 @@ pub(crate) fn generate_list_generate_allocate_func(
),
target: Target::Io,
needs_ffigen: true,
cargo_feature: None,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ impl WireRustCodecCstGeneratorDecoderTrait for PrimitiveListWireRustCodecCstGene
),
target: Target::Io,
needs_ffigen: true,
cargo_feature: None,
}.into(),
..Default::default()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(crate) struct ExternFunc {
pub(crate) body: String,
pub(crate) target: Target,
pub(crate) needs_ffigen: bool,
pub(crate) cargo_feature: Option<String>,
}

#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
Expand All @@ -36,12 +37,17 @@ impl ExternFunc {
Target::Io => "#[unsafe(no_mangle)]",
Target::Web => "#[wasm_bindgen]",
};
let feature = match &self.cargo_feature {
Some(feature) => format!("#[cfg(feature = \"{}\")]", feature),
None => "".to_owned(),
};
let ExternFunc { body, .. } = self;

let func_name = self.func_name(c_symbol_prefix);

format!(
r#"
{feature}
{attribute}
pub {call_convention} fn {func_name}({}) {} {{
{body}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub(crate) fn generate_wire_func(
body: generate_redirect_body(func, &params.common),
target: target.try_into().unwrap(),
needs_ffigen: true,
cargo_feature: None,
}
.into(),
TargetOrCommon::Common => format!(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ impl WireRustGeneratorMiscTrait for RustOpaqueWireRustGenerator<'_> {
),
target,
needs_ffigen: false,
cargo_feature: None,
})
.collect_vec()
.into()
Expand Down
2 changes: 2 additions & 0 deletions frb_codegen/src/library/internal/frb_rust_source_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ fn generate_target_pde_dispatcher_mode(target: Target, mode: FfiDispatcherMode)
body,
target,
needs_ffigen: false,
cargo_feature: None,
}
}

Expand Down Expand Up @@ -122,5 +123,6 @@ fn generate_dart_fn_deliver_output(target: Target) -> ExternFunc {
),
target,
needs_ffigen: false,
cargo_feature: Some("dart-opaque".into()),
}
}
15 changes: 14 additions & 1 deletion frb_example/dart_minimal/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,20 @@ edition = "2021"
crate-type = ["cdylib"]

[dependencies]
flutter_rust_bridge = { path = "../../../frb_rust" }
flutter_rust_bridge = { path = "../../../frb_rust", default-features = false, features = [
"anyhow",
# "dart-opaque",
"log",
"portable-atomic",
"rust-async",
"thread-pool",
"user-utils",
"wasm-start",
] }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(frb_expand)'] }

[features]
default = ["dart-opaque"]
dart-opaque = ["flutter_rust_bridge/dart-opaque"]
Comment on lines +24 to +26
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: is it possible we make it as simple as possible, say, is it possible to remove the dart-opaque line, and directly specify as flutter_rust_bridge/dart-opaque? (just a quick nit, I forget whether rust supports so or not, if not then ignore)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know of another way to do this.

2 changes: 2 additions & 0 deletions frb_rust/src/internal_generated/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ macro_rules! frb_generated_io_extern_func {
pde_ffi_dispatcher_sync_impl(func_id, ptr_, rust_vec_len_, data_len_)
}

#[cfg(feature = "dart-opaque")]
#[unsafe(no_mangle)]
pub extern "C" fn frb_dart_fn_deliver_output(
call_id: i32,
Expand Down Expand Up @@ -69,6 +70,7 @@ macro_rules! frb_generated_web_extern_func {
pde_ffi_dispatcher_sync_impl(func_id, ptr_, rust_vec_len_, data_len_)
}

#[cfg(feature = "dart-opaque")]
#[wasm_bindgen]
pub fn frb_dart_fn_deliver_output(
call_id: i32,
Expand Down
3 changes: 3 additions & 0 deletions frb_utils/lib/src/commands/test_web_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ class TestWebConfig {

@CliOption(help: 'Rust feature flags to set during build')
late List<String> rustFeatures;

@CliOption(help: 'Whether to enable Rust default features', defaultsTo: true)
late bool defaultFeatures;
}
8 changes: 7 additions & 1 deletion frb_utils/lib/src/commands/test_web_command.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions frb_utils/lib/src/dart_web_test_utils/run_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ Future<void> executeTestWeb(TestWebConfig config) async {
final webRoot = '$dartRoot/web';
print('executeTestWeb: Pick dartRoot=$dartRoot');

List<String> cargoArgs =
config.rustFeatures.expand((x) => ['--features', x]).toList();
List<String> cargoArgs = [
...config.rustFeatures.expand((x) => ['--features', x]),
if (!config.defaultFeatures) '--no-default-features',
];

print('executeTestWeb: compile');
await executeBuildWeb(BuildWebArgs(
Expand Down
3 changes: 1 addition & 2 deletions frb_utils/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ dependencies:

dev_dependencies:
build_runner: ^2.2.0
# Temporarily remove before https://github.com/kevmoo/build_cli/issues/168 is fixed
# build_cli: ^2.2.4
build_cli: ^2.2.5
flutter_lints: ^3.0.1
test: ^1.24.0
24 changes: 14 additions & 10 deletions tools/frb_internal/lib/src/makefile_dart/lint.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,22 +55,26 @@ Future<void> lintRustFormat(LintConfig config) async {

Future<void> lintRustClippy(LintConfig config) async {
for (final package in kRustPackages) {
final feature = getRustFeaturesOfPackage(package);
if (config.fix) {
final featureConfigurations = getRustFeaturesOfPackage(package);
for (final featureConfiguration in featureConfigurations) {
if (config.fix) {
await exec(
'cargo fix ${featureConfiguration.toCargoArgs} --allow-dirty --allow-staged',
relativePwd: package);
}
await exec(
'cargo fix ${feature != null ? "--features $feature" : ""} --allow-dirty --allow-staged',
'cargo clippy ${featureConfiguration.toCargoArgs} ${config.fix ? "--fix --allow-dirty --allow-staged" : ""} -- -D warnings',
relativePwd: package);
}
await exec(
'cargo clippy ${feature != null ? "--features $feature" : ""} ${config.fix ? "--fix --allow-dirty --allow-staged" : ""} -- -D warnings',
relativePwd: package);
}

for (final package in kRustPackagesAllowWeb) {
final feature = getRustFeaturesOfPackage(package);
await exec(
'cargo clippy ${feature != null ? "--features $feature" : ""} --target wasm32-unknown-unknown ${config.fix ? "--fix --allow-dirty --allow-staged" : ""} -- -D warnings',
relativePwd: package);
final featureConfigurations = getRustFeaturesOfPackage(package);
for (final featureConfiguration in featureConfigurations) {
await exec(
'cargo clippy ${featureConfiguration.toCargoArgs} --target wasm32-unknown-unknown ${config.fix ? "--fix --allow-dirty --allow-staged" : ""} -- -D warnings',
relativePwd: package);
}
}
}

Expand Down
26 changes: 23 additions & 3 deletions tools/frb_internal/lib/src/makefile_dart/misc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,33 @@ String convertConfigPackage(String raw) {
return ans;
}

String? getRustFeaturesOfPackage(String package) {
final class FeatureConfiguration {
final bool defaultFeatures;
final String? features;

const FeatureConfiguration({
required this.features,
this.defaultFeatures = true,
});

String get toCargoArgs =>
"${features != null ? "--features $features" : ""} ${defaultFeatures ? "" : "--no-default-features"}";
}

List<FeatureConfiguration> getRustFeaturesOfPackage(String package) {
if (package == "frb_example/pure_dart_pde/rust" ||
package == "frb_example/pure_dart/rust" ||
package == "frb_example/pure_dart" ||
package == "frb_example/pure_dart_pde") {
return "internal_feature_for_testing";
return const [
FeatureConfiguration(features: "internal_feature_for_testing")
];
} else if (package == "frb_example/dart_minimal/rust") {
return const [
FeatureConfiguration(features: null),
FeatureConfiguration(features: null, defaultFeatures: false),
];
} else {
return null;
return const [FeatureConfiguration(features: null)];
}
}
53 changes: 30 additions & 23 deletions tools/frb_internal/lib/src/makefile_dart/test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -307,25 +307,27 @@ Future<void> testRustPackage(TestRustPackageConfig config) async {
await runPubGetIfNotRunYet('frb_example/dart_minimal');
await runPubGetIfNotRunYet('frb_example/pure_dart');
print("testRustPackage ${config.package}");
final feature = getRustFeaturesOfPackage(config.package);
await exec('cargo build ${feature != null ? "--features $feature" : ""}',
relativePwd: config.package);

final effectiveEnableCoverage = config.coverage &&
const ['frb_codegen', 'frb_rust'].contains(config.package);
final featureConfigurations = getRustFeaturesOfPackage(config.package);
for (final featureConfiguration in featureConfigurations) {
await exec('cargo build ${featureConfiguration.toCargoArgs}',
relativePwd: config.package);

final outputCodecovPath =
'${getCoverageDir('test_rust_package_${config.package.replaceAll("/", "_")}')}/codecov.json';
await exec(
'cargo ${effectiveEnableCoverage ? "llvm-cov --codecov --output-path $outputCodecovPath" : "test"} ${feature != null ? "--features $feature" : ""}',
relativePwd: config.package,
extraEnv: {
'FRB_SKIP_GENERATE_FRB_EXAMPLE_TEST': '1',
if (config.updateGoldens) 'UPDATE_GOLDENS': '1',
...kEnvEnableRustBacktrace,
});
final effectiveEnableCoverage = config.coverage &&
const ['frb_codegen', 'frb_rust'].contains(config.package);

if (effectiveEnableCoverage) transformCodecovReport(outputCodecovPath);
final outputCodecovPath =
'${getCoverageDir('test_rust_package_${config.package.replaceAll("/", "_")}')}/codecov.json';
await exec(
'cargo ${effectiveEnableCoverage ? "llvm-cov --codecov --output-path $outputCodecovPath" : "test"} ${featureConfiguration.toCargoArgs}',
relativePwd: config.package,
extraEnv: {
'FRB_SKIP_GENERATE_FRB_EXAMPLE_TEST': '1',
if (config.updateGoldens) 'UPDATE_GOLDENS': '1',
...kEnvEnableRustBacktrace,
});

if (effectiveEnableCoverage) transformCodecovReport(outputCodecovPath);
}
}

Future<void> testDartNative(TestDartNativeConfig config) async {
Expand Down Expand Up @@ -449,12 +451,17 @@ Future<void> testDartWeb(TestDartConfig config) async {
// extraEnv: kEnvEnableRustBacktrace,
);
} else {
final features = getRustFeaturesOfPackage(config.package);
await exec(
'dart run flutter_rust_bridge_utils test-web --entrypoint ../$package/test/dart_web_test_entrypoint.dart ${features != null ? "--rust-features $features" : ""}',
relativePwd: 'frb_utils',
// extraEnv: kEnvEnableRustBacktrace,
);
final featureConfigurations = getRustFeaturesOfPackage(package);
for (final featureConfiguration in featureConfigurations) {
final features = featureConfiguration.features;
final defaultFeatures = featureConfiguration.defaultFeatures;

await exec(
'dart run flutter_rust_bridge_utils test-web --entrypoint ../$package/test/dart_web_test_entrypoint.dart ${defaultFeatures ? "" : "--no-default-features"} ${features != null ? "--rust-features $features" : ""}',
relativePwd: 'frb_utils',
// extraEnv: kEnvEnableRustBacktrace,
);
}
}
}

Expand Down
Loading