fzyzcjy / flutter_rust_bridge

Flutter/Dart <-> Rust binding generator, feature-rich, but seamless and simple.
https://fzyzcjy.github.io/flutter_rust_bridge/
MIT License
4.03k stars 275 forks source link

Project fails to build with dependency on defmt #2199

Closed darkwater closed 1 week ago

darkwater commented 1 month ago

Describe the bug

Defmt (deferred formatting) is a logging framework popular in the embedded Rust ecosystem.

In summary, it works by exporting the to-be-logged strings as static symbols, and at runtime sending their addresses (a few bytes) instead of the whole string (many bytes, including work to format parameters).

The resulting binary will contain symbols such as:

{"package":"foo","tag":"defmt_str","data":"Hello, world!", "disambiguator":"10919131587984043797","crate_name":"foo"}

I noticed that as soon as I depend on (a crate that depends on) defmt in my Flutter/Rust project, running fails with:

SEVERE: error: linking with `cc` failed: exit status: 1
SEVERE:   = note: rust-lld: error: /tmp/rustcf9ZPV3/list:37: ; expected, but got "package"
SEVERE:           collect2: error: ld returned 1 exit status

Looking at the mentioned list file:

{
  global:
    dart_fn_deliver_output;
    frb_get_rust_content_hash;
    frb_pde_ffi_dispatcher_primary;
    frb_pde_ffi_dispatcher_sync;
...
    _embassy_time_now;
    _embassy_time_set_alarm;
    _embassy_time_set_alarm_callback;
    {"package":"embassy-time","tag":"defmt_derived","data":"Duration {{ ticks: {=?:?} }}","disambiguator":"9988651866586741216","crate_name":"embassy_time"};
    {"package":"embassy-time","tag":"defmt_derived","data":"Instant {{ ticks: {=?:?} }}","disambiguator":"11137344269819762075","crate_name":"embassy_time"};
    {"package":"embassy-time","tag":"defmt_derived","data":"TimeoutError","disambiguator":"9003289308489355431","crate_name":"embassy_time"};
...

This is probably not exclusive to defmt, but will happen to any project that exports "weird" symbol names.

Steps to reproduce

Add a dependency on defmt, then call:

defmt::intern!("Hello, world!");

This should cause a symbol with a JSON name to be exported:

$ objdump target/debug/foo -x | rg Hello
 17 .defmt.{"package":"foo","tag":"defmt_str","data":"Hello, world!","disambiguator":"10919131587984043797","crate_name":"foo"}

Logs

Launching lib/main.dart on Linux in debug mode...
SEVERE: error: linking with `cc` failed: exit status: 1
SEVERE:   = note: rust-lld: error: /tmp/rustcf9ZPV3/list:37: ; expected, but got "package"
SEVERE:           collect2: error: ld returned 1 exit status
SEVERE: error: could not compile `rust_lib_sicshark` (lib) due to 1 previous error
Building Linux application...                                           
Error: Build process failed

Expected behavior

The symbol names should be sanitized in such a way that special symbols don't break the build.

Generated binding code

No response

OS

Arch Linux

Version of flutter_rust_bridge_codegen

2.0.0-dev.35

Flutter info

[✓] Flutter (Channel stable, 3.22.2, on Arch Linux 6.9.8-arch1-1, locale C.UTF-8)
    • Flutter version 3.22.2 on channel stable at /opt/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 761747bfc5 (5 weeks ago), 2024-06-05 22:15:13 +0200
    • Engine revision edd8546116
    • Dart version 3.4.3
    • DevTools version 2.34.3

[✓] Linux toolchain - develop for Linux desktop
    • clang version 18.1.8
    • cmake version 3.30.0
    • ninja version 1.12.1
    • pkg-config version 2.1.1

[✓] Connected device (1 available)
    • Linux (desktop) • linux • linux-x64 • Arch Linux 6.9.8-arch1-1

[✓] Network resources
    • All expected network resources are available.

(other targets omitted)

Version of clang++

18.1.8

Additional context

No response

welcome[bot] commented 1 month ago

Hi! Thanks for opening your first issue here! :smile:

fzyzcjy commented 1 month ago

Hmm, I guess the rust-lld: error: /tmp/rustcf9ZPV3/list:37 may not be related to frb, since imho frb does not change the linking process.

Is it possible that, it is because frb expose extern c methods? If so, maybe ask/search in rust/defmt how they solve this.

fzyzcjy commented 1 week ago

Close since this seems to not be related to frb, but feel free to reopen if needed!