Issue running on on NixOS
Basic info:
- ObjectBox version: objectbox: ^1.7.2, objectbox_flutter_libs: any, objectbox_generator: any
- Flutter/Dart SDK: Flutter 3.10.0, Dart 3.0.0
- Reproducible: Always
- Build OS: NixOS 23.05 (Stoat)
- Deployment device or OS: NixOS 23.05 (Stoat)
Steps to reproduce
- Build a project that uses objectbox_flutter_libs (or libobjectbox.so)
- Try to run it
- :(
Expected behavior
App would run
Code
N/A
Logs, stack traces
$ flutter run --device-id linux
{...}
flutter: Failed to load ObjectBox library. For Flutter apps, check if objectbox_flutter_libs is added to dependencies. For unit tests and Dart apps, check if the ObjectBox library was downloaded (https://docs.objectbox.io/getting-started).
flutter: Failed to load ObjectBox library. For Flutter apps, check if objectbox_flutter_libs is added to dependencies. For unit tests and Dart apps, check if the ObjectBox library was downloaded (https://docs.objectbox.io/getting-started).
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): Failed to load dynamic library 'libobjectbox.so': libobjectbox.so: cannot open shared object file: No such file or directory
#0 _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:11:43)
#1 new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:22:12)
#2 _tryObjectBoxLibFile (package:objectbox/src/native/bindings/bindings.dart:84:29)
#3 loadObjectBoxLib (package:objectbox/src/native/bindings/bindings.dart:101:12)
#4 C (package:objectbox/src/native/bindings/bindings.dart:119:27)
#5 C (package:objectbox/src/native/bindings/bindings.dart)
#6 new Model (package:objectbox/src/native/model.dart:19:31)
#7 new Store (package:objectbox/src/native/store.dart:175:21)
#8 openStore (package:notes/objectbox.g.dart:90:5)
<asynchronous suspension>
#9 initStore (package:notes/store.dart:25:16)
<asynchronous suspension>
#10 main (package:notes/main.dart:10:3)
<asynchronous suspension>
$ ldd build/linux/arm64/debug/bundle/lib/libobjectbox.so
linux-vdso.so.1 (0x0000ffff86e80000)
libdl.so.2 => /nix/store/0ckxcm0bnsh64a4vi40d5wjs96i014nl-glibc-2.37-8/lib/libdl.so.2 (0x0000ffff86d00000)
libstdc++.so.6 => not found
libm.so.6 => /nix/store/0ckxcm0bnsh64a4vi40d5wjs96i014nl-glibc-2.37-8/lib/libm.so.6 (0x0000ffff86c50000)
libgcc_s.so.1 => /nix/store/x2f8wiip66lxf6zynscszpm4d990q098-xgcc-12.2.0-libgcc/lib/libgcc_s.so.1 (0x0000ffff86c10000)
libpthread.so.0 => /nix/store/0ckxcm0bnsh64a4vi40d5wjs96i014nl-glibc-2.37-8/lib/libpthread.so.0 (0x0000ffff86be0000)
libc.so.6 => /nix/store/0ckxcm0bnsh64a4vi40d5wjs96i014nl-glibc-2.37-8/lib/libc.so.6 (0x0000ffff86a30000)
/nix/store/0ckxcm0bnsh64a4vi40d5wjs96i014nl-glibc-2.37-8/lib/ld-linux-aarch64.so.1 (0x0000ffff86e43000)
$ LD_LIBRARY_PATH=/nix/store/px2m9rmdcp245j1sdgdrhamlk6ph182b-gcc-12.2.0-lib/lib/ ldd build/linux/arm64/debug/bundle/lib/libobjectbox.so
linux-vdso.so.1 (0x0000ffff9919b000)
libdl.so.2 => /nix/store/0ckxcm0bnsh64a4vi40d5wjs96i014nl-glibc-2.37-8/lib/libdl.so.2 (0x0000ffff99010000)
libstdc++.so.6 => /nix/store/px2m9rmdcp245j1sdgdrhamlk6ph182b-gcc-12.2.0-lib/lib/libstdc++.so.6 (0x0000ffff98de0000)
libm.so.6 => /nix/store/0ckxcm0bnsh64a4vi40d5wjs96i014nl-glibc-2.37-8/lib/libm.so.6 (0x0000ffff98d30000)
libgcc_s.so.1 => /nix/store/px2m9rmdcp245j1sdgdrhamlk6ph182b-gcc-12.2.0-lib/lib/libgcc_s.so.1 (0x0000ffff98cf0000)
libpthread.so.0 => /nix/store/0ckxcm0bnsh64a4vi40d5wjs96i014nl-glibc-2.37-8/lib/libpthread.so.0 (0x0000ffff98cc0000)
libc.so.6 => /nix/store/0ckxcm0bnsh64a4vi40d5wjs96i014nl-glibc-2.37-8/lib/libc.so.6 (0x0000ffff98b10000)
/nix/store/0ckxcm0bnsh64a4vi40d5wjs96i014nl-glibc-2.37-8/lib/ld-linux-aarch64.so.1 (0x0000ffff9915e000)
To fix the issue I tried..
$ LD_LIBRARY_PATH=/nix/store/px2m9rmdcp245j1sdgdrhamlk6ph182b-gcc-12.2.0-lib/lib/ flutter run
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): Failed to load dynamic library 'libobjectbox.so': libobjectbox.so: cannot open shared object file: No such file or directory
but it didn't work. I thought that the issue may be with flutter run overriding the LD_LIBRARY_PATH - so I've decided to test it another way:
$ flutter build linux
$ LD_LIBRARY_PATH=/nix/store/px2m9rmdcp245j1sdgdrhamlk6ph182b-gcc-12.2.0-lib/lib/ build/linux/arm64/debug/bundle/notes
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): Failed to load dynamic library 'libobjectbox.so': libobjectbox.so: cannot open shared object file: No such file or directory
But it still doesn't work
Thanks for reporting!
Failed to load dynamic library 'libobjectbox.so': libobjectbox.so: cannot open shared object file: No such file or directory
This sounds like the shared library isn't bundled at all. It should be in a lib folder next to the executable.
Can you
- double check your pubspec file has dependencies similar to what is shown on Getting Started and,
- upgrade to the latest version of objectbox (to get v2 you likely need to run
flutter pub upgrade objectbox --major-versions)?
Hey! The lib is at the right place - I've tested it on a just created flutter project. As can be seen in the ldd - the file is there.
My dependencies are exactly the same as in getting started (with latest versions from pub.dev).
This could be relevant:
libstdc++.so.6 => not found
We don't test on NixOS, so I'm sorry that we cannot really help here. This is extremely common lib with Linux, so my guess that this is a very NixOS-specific issue. Let us know if you find something out.
Okay! I'll investigate that further and let you know about the details!
I am not familiar with how flutter packaging works, but I packaged the objectbox-c pre-built shared object for nixos (see gist).
I am able to get apps running if I manually delete lib/libobjectstore.so and then symlink in the patched binary from the nix store. However, when I rebuild it seems to get overwritten as the cmake file always re-downloads the prebuilt binary. As I am not familiar with flutter packagingI am not sure best practice for updating the cmake file to allow me to "bring my own shared object."
@jordanisaacs I think that a flag for building objectbox as a part of flutter build is they way to go - but I'm unsure what's the objectbox team on that.
I don't follow; e.g. what's "the patched binary from the nix store"?
If you do not want the CMake setup, you can e.g. go with download.sh - there's a tab for that in the installation docs. And/or, copy and adjust the CMakeLists.txt for your needs?
the patched binary from the nix store is output of the nix expression posted by @jordanisaacs. (p.s. I couldn't get it to work with nix-build).
And I think that I'll speak for me and other nix users who use objectbox - we wouldn't really want to manually adjust the CMakeLists.txt in every project because we are already using objectbox_flutter_libs and it should provide the system system with binary it can run.
also I've just realized that objectbox is closed source.. truly a good job at obfuscating that fact.. And since using closed source code is a blocker for me I guess that I'll need to find some other database that doesn't hide the (quite important imo) fact about the project source being unavailable.
also since we are here already - could you change licensing on https://pub.dev/packages/objectbox? This is a bit misleading - mentioning that you also accept the objectbox binary license would be a cool thing. p.s. I'm unsubscribing from this issue, so ping me if you need something from me.
I don't follow; e.g. what's "the patched binary from the nix store"?
If you do not want the CMake setup, you can e.g. go with download.sh - there's a tab for that in the installation docs. And/or, copy and adjust the CMakeLists.txt for your needs?
The issue is NixOS doesn't have its shared libraries in the standard Linux location. Hence you see missing libraries with ldd. that Nix expression I wrote patches your pre-built shared object to point to the other shared objects correctly (using autopatchelf), but it also places it in the nix store /nix/store/*****. Furthermore nix builds software in a sandbox without network access.
I think all I need as a packager is for objectbox to provide an environment variable that skips downloading the shared object in the build phase. My goal is to package BlueBubbles for Nix which utilizes this library, and it would also make life easier packaging anything else that utilizes this library .
@jordanisaacs Thanks for providing some background!
Had a quick look... CMake offers providing some "patch command" (docs here, search for "PATCH_COMMAND"). If there would be a way to "inject" (e.g. env var?) a patch command from your side, would you be able to run autopatchelf and do the adjustments? This would also cover updating to a new version and stuff; might be a smoother (more automated) process?