Open TheBotlyNoob opened 3 weeks ago
Hi! Thanks for opening your first issue here! :smile:
Hmm, without more info, I guess it may be because Flutter/Dart have trouble finding the .so file when using nix, or cargokit fails to call rust compilation (maybe nix has some special properties).
Firstly, could you please show flutter run --verbose
, then the logs of cargokit will be shown and it can be checked whether the .so
is compiled or not.
Then, if it is compiled, could you please check what is the proper way of loading a .so
(DynamicLibrary) in Flutter on nix? (It may be the same question for calling C/C++/Rust/...) I guess one quick check is to use absolute path for .so file temporarily and see whether it works.
I forgot to mention that, sorry. Cargokit is able to create the .so
file, and it does get copied to the correct directory (build/linux/x64/debug/bundle/lib/liburust_lib_myapp.so
). Here is the output of flutter run --verbose
:
and it does get copied to the correct directory (build/linux/x64/debug/bundle/lib/liburust_lib_myapp.so
Then maybe try to point to the absolute path of .so as a first check.
Btw does nix have special property to forbid accessing some files?
okay, so if I manually patch LD_LIBRARY_PATH
to the lib directory (i.e. going to the bundle directory, setting LD_LIBRARY_PATH
to $(pwd)/lib
, and running ./myapp
), everything goes great. So that raises the question of why isn't dart finding the library by default?
Nix shouldn't have special properties- it (afaik) acts like a normal linux distro with some fancy config as a package manager. It is super useful for easy development environments, using devenv. The config is kinda hard to get down though.
So that raises the question of why isn't dart finding the library by default?
Given the information, I guess is it possible that, nix somehow provides different library search path than other linux distri? The loading logic is at https://github.com/fzyzcjy/flutter_rust_bridge/blob/8915d06a77122404650abcec9f0a5b03cfd1ada2/frb_dart/lib/src/loader/_io.dart#L77 (only a dozen lines of code), and the core is just:
DynamicLibrary.open('libsomething.so');
I think I'm getting hit with multiple issues at once. After switching to a machine running Arch, I realized that cargokit didn't copy the .so
file to the bundle
directory in the real app (both on the Arch and Nix machines). The core issue on Nix still exists, as that happened on the bare example app, but this is also weird. Cargokit does call cargo
because the processes appear in the task manager, but the files don't get copied for some reason. Give me a few days to figure these issues out and I'll report back... eventually. I don't want to waste your time. After I figure out the library not copying issue, I can figure out the Nix issue.
If you want to see the logs of a clean build on the actual project, here it is.
It's OK and take your time! If it turn out to be cargokit issue, I guess I may not be able to help much in this repo and it may be great to issue/PR in cargokit.
I found a fairly hacky fix, but it works for my setup and I don't really feel like debugging further unless someone else is having this issue.
I nuked the existing rust_builder/
, linux/
, windows/
, macos/
, etc. folders, the pubspec.yaml
-- pretty much everything BUT the lib
and rust
directories, and regenerated it using flutter_rust_bridge_codegen create <project_name>
and copied the generated folders back to the original directory.
I think this was caused by a botched upgrade by me. For some reason, instead of using flutter_rust_bridge_codegen
to upgrade the project, I simply found and replaced all instances of -dev.<OLD_VERSION>
(i.e. -dev.21
) with -dev.<NEW_VERSION>
(i.e. -dev.32
). I'm not sure if this was the real issue or not, but its what happened before things went haywire (the botched upgrade to flutter_rust_bridge
happened at about the same time as me switching to Nix, which is why I didn't notice it before immediately blaming it on Nix.
To fix the Nix issue, I simply patched the LD_LIBRARY_PATH
to "$(pwd)/client/build/linux/x64/debug/bundle/lib:$(pwd)/client/build/linux/x64/release/bundle/lib:$LD_LIBRARY_PATH"
(export LD_LIBRARY_PATH="$(pwd)/client/build/linux/x64/debug/bundle/lib:$(pwd)/client/build/linux/x64/release/bundle/lib:$LD_LIBRARY_PATH"
in the shell before running flutter run
)
if anyone else has similar issues, I'd be happy to help debug with you, and maybe provide another fix I find in the future. But for now this is good enough for me.
for the full diff, see https://github.com/TheBotlyNoob/bramlett/commit/d1da8cbffe833e80416a72c9eaf52651ec70f039
I simply found and replaced all instances of
Well I guess this may not work: The developer-facing API is guaranteed to not have breaking changes (for stable versions) and almost no breaking changes (for .dev versions); however, the generated code can change arbitrarily. In other words, it is possible that .dev.21's generated code will be quite different from that of .dev.32, and that will cause trouble because the runtime library version mismatch.
To fix the Nix issue, I simply patched
Looks pretty reasonable - I personally also often wrap commands with extra things
Found what was wrong with Nix: https://nix.dev/guides/faq.html#how-to-run-non-nix-executables. There's nothing you can really do about it, I don't think- just putting it here for info.
On the upgrading, I found-and-replaced the versions then regenerated. I didn't just change the version.
Anyhow, I think this issue is pretty much fixed, although the only fix is kind of a workaround. If you feel like thats enough, you can close it.
I see, this looks like speciality of nix.
Never used nix before, but by looking at the doc, I guess it may be possible to use things like programs.nix-ld.libraries
to fix it?
I switched to nix as well ... and ran into troubles. A tip I got was to use a FHS environment - which only works on Linux. As I am running on an apple silicon Mac, I wrote a nix.flake, which installs flutter & dart into the local project directory. Rust is installed globally - nix only installs rustup, which I used to install the rust toolchain.
I had a lot of lib issues (though these where apple libs (like core, UIKit, ...) not present, and could only solve these by not using libs c-compiler, but Xcode's one -> by using mkShellNoCC
instead of mkShell
.
If anyone has troubles as well: write to me :)
I have a flake with dev shell for my project which I could share if anyone is interested
Edit: Maybe we could work on adding a default flake for nix users?
@acul009 you don't compile to iOS, right? Because for that the flutter-nix package is broken.
Otherwise it might be a good idea - we could start by joining our nix flake files. @fzyzcjy what do you think? Pro:
Maybe @acul009 we should wait for others to "+1" this discussion.
@fzyzcjy what do you think?
I do not have Nix (thus not possible to play with it by myself), but PRs are welcome! After it is setup, we can also utilize the github actions (e.g. https://github.com/marketplace/actions/install-nix) to ensure it never breaks as time goes by.
@acul009 you don't compile to iOS, right? Because for that the flutter-nix package is broken.
Not yet, though I'd like to in the future
Otherwise it might be a good idea - we could start by joining our nix flake files. I'm pretty new to nix and nixos and it took me quite a while to get this working. If there's a nix flake that works out of the box, then others wouldn't need to scour these issues to get it working.
Hi!
I've been messing around with Nix trying to get my project to work too (which was previously on ubuntu). Note that it's still on 1.82.6 of this library as I've not found the time to work through the 2.0 upgrade.
What I'm noticing is the same bug that has been raised here, but the fix needed tweaking slightly to remove the 'client' part of the path (presumably that's from v2.0?).
Please see my full flake below as it was very painful to make so if it saves anyone time that's a win!
Note that I also had to specify llvm path explicitly in my build.rs using the LIBCLANG_PATH environment variable as otherwise it isn't found by ffigen.
Most of the advice I saw online was to use the nix-shell -p ... arguments to 'make the environment work as if it was normal linux' but I didn't have that that experience at all (YMMV), but these environment variables allow me to build!
Thanks @rob-mur! I assume you are still on a *nix based os, not MacOS?
No worries - yep NixOS.
I'll update my configuration once I've got web + android working (the flake up until this point was just to get it building on Linux)
Hi again
I've been tinkering on this for a couple days now - adding web support was relatively painless but android is super painful to get working. See my current flake below which still doesn't work (it seems the version of libc that is making it into my app is too old somehow and doesn't have the right 64 bit symbols).
Note that I've currently just been trying to get an x86_64 emulator working as cross compilation to arm and x86 causes even more issues.
If anyone has had any luck please let me know - I'm mostly just trying to link random libraries now as nothing obvious seems to work.
The basic issue I think is that my native library builds sqlite and is doing so with some version of libc that is newer than the one in even the latest ndk.
Will keep investigating but if generally the status of nix plus android for frb with a non-trivial project is very ropey at the moment
Ok, so essentially the issue is that the CPATH environment variable that is set to get the Linux build working is interfering with the Android build, because the Android one is using an older version of various C libraries. (the android ndk is a modified version of clang_14).
The problem though is that we need to set CPATH to the includes and lib directories of the clang we are using, otherwise ffigen fails silently and we run into this issue. (normally I think this doesn't matter because it assumes some /usr/lib path which doesn't exist on nix)
Therefore what I think we need to do is modify the CPATH to point to the relevant android-ndk. If we do this then we manage to not run into issues with ffigen or having symbols unknown to bionic at runtime and so can run on Android!
The downside of the above fix is it breaks the Linux build - we need to be changing this environment variable per target otherwise we have issues. The current fix I've landed on is to have CPATH set as the default linux value and then in gradle overwrite it with what we need for the android build.
Note also that in order to use sqlite we have to link in libgcc statically during the cargo ndk run using rustflags else __extenddftf2 cannot be found at runtime (see here). Before this was relying on a /usr/lib directory which we don't have on Nix so instead I pull in the file using an environment variable from gcc-unwrapped. Note that I then needed to set CC=clang
in order for sqlite to build.
All of the above to say that the below flake.nix and snippet of my build.gradle is sufficient to run FRB on NixOS for a non-trivial project for Linux, Web and Android! :rocket:
I won't be looking into iOS as I don't support that platform for my app anyway, but that would be the only platform that doesn't work.
I updated my example project and added my nix flake configuration.
Note, that this is for MacOS. FRB is done in a nix-y way but Flutter and Xcode are not:
.toolchain
).This is a setup with some workarounds - but it works :)
Describe the bug
When running any (at least, all the applications I've tried) flutter application using
flutter_rust_bridge
on Nixos, the error:appears, and the window is simply a white screen. The issue doesn't appear on flutter apps without
flutter_rust_bridge
.This appears to occur on any Nix installation- not only the NixOS version.
Steps to reproduce
git flutter libclang glibc cmake ninja rustup
.Logs
Expected behavior
Flutter being able to find the library.
Generated binding code
No response
OS
NixOS
Version of
flutter_rust_bridge_codegen
2.0.0-dev.32
Flutter info
Version of
clang++
17.0.6
Additional context
No response