c++linuxfluttercmakenix

Flutter can't find libsecret using nix/nixos


I am trying to run a Flutter application with flutter_secure_storage as a dependency on linux. This dependency in turn needs libsecret and won't compile despite the path being present in LD_LIBRARY_PATH:

[  +23 ms] Building Linux application...
[   +8 ms] <- compile package:dashboard/main.dart
[   +7 ms] executing: [build/linux/x64/debug/] cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DFLUTTER_TARGET_PLATFORM=linux-x64 /home/daniel/code/uni/eink/dashboard/linux
[ +111 ms] -- Checking for module 'libsecret-1>=0.18.4'
[  +28 ms] --   No package 'libsecret-1' found
[        ] CMake Error at /nix/store/ih3wsahlr3d787jc4kzqizp6syq6hy29-cmake-3.29.3/share/cmake-3.29/Modules/FindPkgConfig.cmake:634 (message):
[   +1 ms]   The following required packages were not found:
[        ]    - libsecret-1>=0.18.4
[        ] Call Stack (most recent call first):
[        ]   /nix/store/ih3wsahlr3d787jc4kzqizp6syq6hy29-cmake-3.29.3/share/cmake-3.29/Modules/FindPkgConfig.cmake:862 (_pkg_check_modules_internal)
[        ]   flutter/ephemeral/.plugin_symlinks/flutter_secure_storage_linux/linux/CMakeLists.txt:13 (pkg_check_modules)
[        ] -- Configuring incomplete, errors occurred!

My flake.nix:

{
  description = "Flutter environment";

  inputs = {
    flake-utils.url = "github:numtide/flake-utils";
    nixpkgs.url = "github:NixOS/nixpkgs";
  };

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachSystem [ "x86_64-linux" ] (system:
      let
        pkgs = import nixpkgs {
          inherit system;
          config.allowUnfree = true;
        };
        androidEnv = pkgs.androidenv.override { licenseAccepted = true; };
        androidComposition = androidEnv.composeAndroidPackages {
          cmdLineToolsVersion = "8.0"; # emulator related: newer versions are not only compatible with avdmanager
          platformToolsVersion = "34.0.4";
          buildToolsVersions = [ "30.0.3" "33.0.2" "34.0.0" ];
          platformVersions = [ "28" "31" "32" "33" "34" ];
          abiVersions = [ "x86_64" ]; # emulator related: on an ARM machine, replace "x86_64" with
          # either "armeabi-v7a" or "arm64-v8a", depending on the architecture of your workstation.
          includeNDK = false;
          includeSystemImages = true; # emulator related: system images are needed for the emulator.
          systemImageTypes = [ "google_apis" "google_apis_playstore" ];
          includeEmulator = true; # emulator related: if it should be enabled or not
          useGoogleAPIs = true;
          extraLicenses = [
            "android-googletv-license"
            "android-sdk-arm-dbt-license"
            "android-sdk-license"
            "android-sdk-preview-license"
            "google-gdk-license"
            "intel-android-extra-license"
            "intel-android-sysimage-license"
            "mips-android-sysimage-license"            ];
        };
        androidSdk = androidComposition.androidsdk;
      in
      {
        devShell = with pkgs; mkShell rec {
          ANDROID_HOME = "${androidSdk}/libexec/android-sdk";
          ANDROID_SDK_ROOT = "${androidSdk}/libexec/android-sdk";
          CHROME_EXECUTABLE = "google-chrome-stable";
          JAVA_HOME = jdk21.home;
          FLUTTER_ROOT = flutter;
          DART_ROOT = "${flutter}/bin/cache/dart-sdk";
          GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${androidSdk}/libexec/android-sdk/build-tools/33.0.2/aapt2";
          QT_QPA_PLATFORM = "wayland;xcb"; # emulator related: try using wayland, otherwise fall back to X
          # NB: due to the emulator's bundled qt version, it currently does not start with QT_QPA_PLATFORM="wayland".
          # Maybe one day this will be supported.
          buildInputs = [
            androidSdk
            flutter
            gradle
            jdk21
            protobuf
            buf
            pandoc
            libsecret
          ];
          # emulator related: vulkan-loader and libGL shared libs are necessary for hardware decoding
          LD_LIBRARY_PATH = "${pkgs.lib.makeLibraryPath [vulkan-loader libGL libsecret]}";
          # Globally installed packages, which are installed through `dart pub global activate package_name`,
          # are located in the `$PUB_CACHE/bin` directory.
          shellHook = ''
            if [ -z "$PUB_CACHE" ]; then
              export PATH="$PATH:$HOME/.pub-cache/bin"
            else
              export PATH="$PATH:$PUB_CACHE/bin"
            fi

            dart pub global activate protoc_plugin
          '';
        };
      }
    );
}

Content of $LD_LIBRARY_PATH: /nix/store/8qdl40qaqck04bha609c1jhkqsihm4l2-vulkan-loader-1.3.283.0/lib:/nix/store/a5vcvrkh1c2ng5kr584g3zw3991vnhks-libGL-1.7.0/lib:/nix/store/ggzid0gk0j02d0549kscb3rr6yp0ma5a-libsecret-0.21.4/lib

How can I fix this and make flutter/cmake detect libsecret?


Solution

  • The fix was as per @Tsyvarev comment to rather use the CMAKE_PREFIX_PATH variable. Also, I added the pkg-config, libsecret.dev and gtk3.dev dependency. The CMAKE_PREFIX_PATH is set for the libsecret and gtk3 lib paths.

    In addition as per https://github.com/NixOS/nixpkgs/issues/24215#issuecomment-1065924731 I removed said if statement and now it works :)

    Fixed flake.nix:

    {
      description = "Flutter environment";
    
      inputs = {
        flake-utils.url = "github:numtide/flake-utils";
        nixpkgs.url = "github:NixOS/nixpkgs";
      };
    
      outputs = { self, nixpkgs, flake-utils }:
        flake-utils.lib.eachSystem [ "x86_64-linux" ] (system:
          let
            pkgs = import nixpkgs {
              inherit system;
              config.allowUnfree = true;
            };
            androidEnv = pkgs.androidenv.override { licenseAccepted = true; };
            androidComposition = androidEnv.composeAndroidPackages {
              cmdLineToolsVersion = "8.0"; # emulator related: newer versions are not only compatible with avdmanager
              platformToolsVersion = "34.0.4";
              buildToolsVersions = [ "30.0.3" "33.0.2" "34.0.0" ];
              platformVersions = [ "28" "31" "32" "33" "34" ];
              abiVersions = [ "x86_64" ]; # emulator related: on an ARM machine, replace "x86_64" with
              # either "armeabi-v7a" or "arm64-v8a", depending on the architecture of your workstation.
              includeNDK = false;
              includeSystemImages = true; # emulator related: system images are needed for the emulator.
              systemImageTypes = [ "google_apis" "google_apis_playstore" ];
              includeEmulator = true; # emulator related: if it should be enabled or not
              useGoogleAPIs = true;
              extraLicenses = [
                "android-googletv-license"
                "android-sdk-arm-dbt-license"
                "android-sdk-license"
                "android-sdk-preview-license"
                "google-gdk-license"
                "intel-android-extra-license"
                "intel-android-sysimage-license"
                "mips-android-sysimage-license"            ];
            };
            androidSdk = androidComposition.androidsdk;
          in
          {
            devShell = with pkgs; mkShell rec {
              ANDROID_HOME = "${androidSdk}/libexec/android-sdk";
              ANDROID_SDK_ROOT = "${androidSdk}/libexec/android-sdk";
              CHROME_EXECUTABLE = "google-chrome-stable";
              JAVA_HOME = jdk21.home;
              FLUTTER_ROOT = flutter;
              DART_ROOT = "${flutter}/bin/cache/dart-sdk";
              GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${androidSdk}/libexec/android-sdk/build-tools/33.0.2/aapt2";
              QT_QPA_PLATFORM = "wayland;xcb"; # emulator related: try using wayland, otherwise fall back to X
              # NB: due to the emulator's bundled qt version, it currently does not start with QT_QPA_PLATFORM="wayland".
              # Maybe one day this will be supported.
              buildInputs = [
                androidSdk
                flutter
                gradle
                jdk21
                protobuf
                buf
                pandoc
                libsecret.dev
                gtk3.dev
                grpcurl
                google-chrome
                chromedriver
                pkg-config
              ];
              # emulator related: vulkan-loader and libGL shared libs are necessary for hardware decoding
              LD_LIBRARY_PATH = "${pkgs.lib.makeLibraryPath [vulkan-loader libGL]}";
              CMAKE_PREFIX_PATH = "${pkgs.lib.makeLibraryPath [libsecret.dev gtk3.dev]}";
              # Globally installed packages, which are installed through `dart pub global activate package_name`,
              # are located in the `$PUB_CACHE/bin` directory.
              shellHook = ''
                if [ -z "$PUB_CACHE" ]; then
                  export PATH="$PATH:$HOME/.pub-cache/bin"
                else
                  export PATH="$PATH:$PUB_CACHE/bin"
                fi
    
                dart pub global activate protoc_plugin
              '';
            };
          }
        );
    }