-
Notifications
You must be signed in to change notification settings - Fork 284
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
Discussions about how to compile Flutter with Rust on Nix and NixOS #1898
Comments
Hi! Thanks for opening your first issue here! 😄 |
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 Then, if it is compiled, could you please check what is the proper way of loading a |
I forgot to mention that, sorry. Cargokit is able to create the flutter run --verbose
|
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 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. |
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
|
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 |
If you want to see the logs of a clean build on the actual project, here it is. flutter run --verbose (on the actual project)
|
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 I think this was caused by a botched upgrade by me. For some reason, instead of using To fix the Nix issue, I simply patched the 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 |
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.
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 |
I switched to nix as well ... and ran into troubles. 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 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.
Maybe @acul009 we should wait for others to "+1" this discussion. |
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. |
Not yet, though I'd like to in the future
|
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! {
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions";
flake-utils.follows = "nix-vscode-extensions/flake-utils";
nixpkgs.follows = "nix-vscode-extensions/nixpkgs";
# Rust
rust-overlay.url = "github:oxalica/rust-overlay";
};
outputs =
inputs:
inputs.flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import inputs.nixpkgs {
inherit system;
overlays = [ inputs.rust-overlay.overlays.default ];
};
extensions = inputs.nix-vscode-extensions.extensions.${system};
inherit (pkgs) vscode-with-extensions vscodium;
packages.default = vscode-with-extensions.override {
vscode = vscodium;
vscodeExtensions = [
extensions.vscode-marketplace.bbenoist.nix
extensions.vscode-marketplace.ms-vscode-remote.remote-ssh
extensions.vscode-marketplace.jnoortheen.nix-ide
extensions.vscode-marketplace.ms-vscode-remote.remote-containers
extensions.vscode-marketplace.rust-lang.rust-analyzer
extensions.open-vsx.eamodio.gitlens
extensions.open-vsx.dart-code.flutter
extensions.open-vsx.dart-code.dart-code
];
};
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
pkg-config
cmake
packages.default
flutter
ninja
corrosion
(pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default))
gtk3
clang
llvmPackages.libclang
];
shellHook = ''
printf "VSCodium with extensions:\n"
codium --list-extensions
export LIBCLANG_PATH="${pkgs.llvmPackages.libclang.lib}";
export CPATH="${pkgs.clang.libc_dev}/include:${pkgs.clang.libc}/lib:${pkgs.libclang.lib}/lib/clang/17/include";
export CC=clang;
export LD_LIBRARY_PATH="$(pwd)/build/linux/x64/debug/bundle/lib:$(pwd)/build/linux/x64/release/bundle/lib:$LD_LIBRARY_PATH"
nix-shell -p clang pkg-config corrosion cmake
'';
};
in
{
inherit packages devShells;
}
);
} |
Thanks @rob-mur! |
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. {
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions";
flake-utils.follows = "nix-vscode-extensions/flake-utils";
nixpkgs.follows = "nix-vscode-extensions/nixpkgs";
# Rust
rust-overlay.url = "github:oxalica/rust-overlay";
};
outputs =
inputs:
inputs.flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import inputs.nixpkgs {
inherit system;
config = {
android_sdk.accept_license = true;
allowUnfree = true;
};
overlays = [ inputs.rust-overlay.overlays.default ];
};
extensions = inputs.nix-vscode-extensions.extensions.${system};
inherit (pkgs) vscode-with-extensions vscodium;
packages.default = vscode-with-extensions.override {
vscode = vscodium;
vscodeExtensions = [
extensions.vscode-marketplace.bbenoist.nix
extensions.vscode-marketplace.ms-vscode-remote.remote-ssh
extensions.vscode-marketplace.jnoortheen.nix-ide
extensions.vscode-marketplace.ms-vscode-remote.remote-containers
extensions.vscode-marketplace.rust-lang.rust-analyzer
extensions.open-vsx.eamodio.gitlens
extensions.open-vsx.dart-code.flutter
extensions.open-vsx.dart-code.dart-code
];
};
config.android_sdk.accept_license = true;
androidComposition = pkgs.androidenv.composeAndroidPackages {
buildToolsVersions = [
"30.0.3"
];
platformVersions = [ "33" "34" ];
abiVersions = [ "x86_64" ];
includeEmulator = true;
emulatorVersion = "35.1.4";
includeSystemImages = true;
systemImageTypes = [ "google_apis_playstore" ];
includeNDK = true;
ndkVersions = [ "26.3.11579264" ];
};
androidSdk = androidComposition.androidsdk;
devShells.default = pkgs.mkShell
{
buildInputs = with pkgs;
[
pkg-config
cmake
packages.default
flutter
ninja
corrosion
(pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default.override {
extensions = [ "rust-src" "rustfmt" "clippy" ];
targets = [ "wasm32-unknown-unknown" "aarch64-linux-android" "armv7-linux-androideabi" "x86_64-linux-android" "i686-linux-android" ];
}))
gtk3
clang
llvmPackages.libclang
awscli2
cargo-lambda
jdk17
androidSdk
glibc_multi
aapt
libxml2
];
shellHook = ''
export LIBCLANG_PATH="${pkgs.llvmPackages.libclang.lib}"
export CPATH="${pkgs.clang.libc_dev}/include:${pkgs.clang.libc}/lib:${pkgs.libclang.lib}/lib/clang/17/include"
export CC=clang
export LIBXML2=$(xml2-config --libs | cut -d ' ' -f 1 | cut -c 3-)
export LD_LIBRARY_PATH="$(pwd)/build/linux/x64/debug/bundle/lib:$(pwd)/build/linux/x64/release/bundle/lib:$LIBXML2:$LD_LIBRARY_PATH"
export PATH="$PATH":"$HOME/.pub-cache/bin":"$HOME/.cargo/bin"
export DYNAMO_PREFIX=global
export AWS_CONFIG_FILE=$(pwd)/aws-config
export ANDROID_SDK_ROOT="${androidSdk}/libexec/android-sdk"
export ANDROID_NDK_ROOT="$ANDROID_SDK_ROOT/ndk-bundle"
export GRADLE_OPTS="-Dorg.gradle.project.android.aapt2FromMavenOverride=${pkgs.aapt}/bin/aapt2"
export LIBCTEST="${pkgs.glibc_multi}"
dart pub global activate flutter_rust_bridge
cargo install wasm-pack cargo-ndk
nix-shell -p clang pkg-config corrosion cmake glibc_multi
'';
};
in
{
inherit packages devShells;
}
);
}
|
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 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! 🚀 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. flake.nix{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions";
flake-utils.follows = "nix-vscode-extensions/flake-utils";
nixpkgs.follows = "nix-vscode-extensions/nixpkgs";
# Rust
rust-overlay.url = "github:oxalica/rust-overlay";
};
outputs =
inputs:
inputs.flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import inputs.nixpkgs {
inherit system;
config = {
android_sdk.accept_license = true;
allowUnfree = true;
};
overlays = [ inputs.rust-overlay.overlays.default ];
};
extensions = inputs.nix-vscode-extensions.extensions.${system};
inherit (pkgs) vscode-with-extensions vscodium;
packages.default = vscode-with-extensions.override {
vscode = vscodium;
vscodeExtensions = [
extensions.vscode-marketplace.bbenoist.nix
extensions.vscode-marketplace.ms-vscode-remote.remote-ssh
extensions.vscode-marketplace.jnoortheen.nix-ide
extensions.vscode-marketplace.ms-vscode-remote.remote-containers
extensions.vscode-marketplace.rust-lang.rust-analyzer
extensions.open-vsx.eamodio.gitlens
extensions.open-vsx.dart-code.flutter
extensions.open-vsx.dart-code.dart-code
];
};
config.android_sdk.accept_license = true;
androidComposition = pkgs.androidenv.composeAndroidPackages {
buildToolsVersions = [
"30.0.3"
];
platformVersions = [ "33" "34" ];
abiVersions = [ "x86_64" ];
includeEmulator = true;
emulatorVersion = "35.1.4";
includeSystemImages = true;
systemImageTypes = [ "google_apis_playstore" ];
includeNDK = true;
ndkVersions = [ "25.1.8937393" ];
};
androidSdk = androidComposition.androidsdk;
devShells.default = pkgs.mkShell
{
buildInputs = with pkgs;
[
pkg-config
cmake
packages.default
flutter
ninja
corrosion
(pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default.override {
extensions = [ "rust-src" "rustfmt" "clippy" ];
targets = [ "wasm32-unknown-unknown" "aarch64-linux-android" "armv7-linux-androideabi" "x86_64-linux-android" "i686-linux-android" ];
}))
gtk3
clang
llvmPackages.libclang
awscli2
cargo-lambda
jdk17
androidSdk
gcc-unwrapped
aapt
];
shellHook = ''
export LIBCLANG_PATH="${pkgs.llvmPackages.libclang.lib}"
export LD_LIBRARY_PATH="$(pwd)/build/linux/x64/debug/bundle/lib:$(pwd)/build/linux/x64/release/bundle/lib:$LD_LIBRARY_PATH"
export PATH="$PATH":"$HOME/.pub-cache/bin":"$HOME/.cargo/bin"
export DYNAMO_PREFIX=global
export AWS_CONFIG_FILE=$(pwd)/aws-config
export ANDROID_SDK_ROOT="${androidSdk}/libexec/android-sdk"
export ANDROID_NDK_ROOT="$ANDROID_SDK_ROOT/ndk-bundle"
export GRADLE_OPTS="-Dorg.gradle.project.android.aapt2FromMavenOverride=${pkgs.aapt}/bin/aapt2"
export CPATH_ANDROID="${androidSdk}/libexec/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.6/include:${androidSdk}/libexec/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include"
export CPATH="${pkgs.clang.libc_dev}/include:${pkgs.clang.libc}/lib:${pkgs.libclang.lib}/lib/clang/17/include"
export LIBGCC_PATH="${pkgs.gcc-unwrapped}/lib/gcc/x86_64-unknown-linux-gnu/13.2.0/libgcc.a"
dart pub global activate flutter_rust_bridge
cargo install wasm-pack cargo-ndk
nix-shell -p clang pkg-config corrosion cmake glibc
'';
};
in
{
inherit packages devShells;
}
);
} build.gradledef cpathAndroid = System.getenv("CPATH_ANDROID")
def libgcc = System.getenv("LIBGCC_PATH")
environment "CPATH", cpathAndroid
environment "RUSTFLAGS", " -C link-arg=" + libgcc
if (profileMode != null) {
commandLine 'cargo', 'ndk',
// Uncomment to enable these ABIs as required.
'-t', 'x86',
'-t', 'x86_64',
'-t', 'armeabi-v7a',
'-t', 'arm64-v8a',
'-o', '../../android/app/src/main/jniLibs', 'build'
args profileMode
} else {
commandLine 'cargo', 'ndk',
// Uncomment to enable these ABIs as required.
'-t', 'x86_64',
'-o', '../../android/app/src/main/jniLibs', 'build'
}
|
I updated my example project and added my nix flake configuration. Note, that this is for MacOS.
This is a setup with some workarounds - but it works :) |
(title changed to reflect the current content) |
@rob-mur glad that you could solve it and thanks for posting about that here! I noticed that I use a different android package: Maybe that one works better for you as well? However, I am on an ARM Mac - that setup might be too different for the same issues/solutions. I think that in my case Xcode cares about a system-wide cc toolset, and all tools rely on that one. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new issue. |
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
The text was updated successfully, but these errors were encountered: