Skip to content
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

RDART-983: Refactor how we open dynamic library to give better error message #1614

Merged
merged 3 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

### Enhancements
* Improve file compaction performance on platforms with page sizes greater than 4k (for example arm64 Apple platforms) for files less than 256 pages in size (Core 14.4.0).
* Add better hint to error message, if opening native library fails. (Issue [#1595](https://github.com/realm/realm-dart/issues/1595))

### Fixed
* Using prefix expressions such as negation of numbers as an initializer would fail. (Issue [#1606](https://github.com/realm/realm-dart/issues/1606))
* Using valid const, but non-literal expressions, such as negation of numbers, as an initializer would fail. (Issue [#1606](https://github.com/realm/realm-dart/issues/1606))

### Compatibility
* Realm Studio: 13.0.0 or later.
Expand Down
62 changes: 37 additions & 25 deletions packages/realm_dart/lib/src/init.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,17 @@ import 'dart:ffi';
import 'dart:io';

import 'package:path/path.dart' as p;
import 'package:realm_common/realm_common.dart';
elle-j marked this conversation as resolved.
Show resolved Hide resolved

import '../realm.dart' as realm show isFlutterPlatform;
import '../realm.dart' show realmBinaryName;
import 'cli/common/target_os_type.dart';
import 'cli/metrics/metrics_command.dart';
import 'cli/metrics/options.dart';
import 'realm_class.dart';

DynamicLibrary? _library;

void _debugWrite(String message) {
assert(() {
print(message);
return true;
}());
}

String _getBinaryPath(String libName) {
String _getPluginPath(String libName) {
if (Platform.isAndroid) {
return libName;
}
Expand Down Expand Up @@ -65,26 +58,45 @@ String get _exeDirName => p.dirname(Platform.resolvedExecutable);

DynamicLibrary _openRealmLib() {
final libName = _getLibName(realmBinaryName);
final root = _getNearestProjectRoot(Platform.script.path) ?? _getNearestProjectRoot(p.current);

// Try to open lib from various candidate paths
List<String> errMessages = [];
for (final open in [
() => _open(libName), // just ask OS..
() => _open(p.join(_exeDirName, libName)), // try finding it next to the executable
if (root != null) () => _open(p.join(root, 'binary', Platform.operatingSystem, libName)), // try finding it relative to project
() => _open(_getBinaryPath(libName)), // find it where it is installed by plugin
]) {

DynamicLibrary? tryOpen(String path) {
elle-j marked this conversation as resolved.
Show resolved Hide resolved
try {
return open();
} on Error catch (e) {
errMessages.add(e.toString());
return DynamicLibrary.open(path);
} on Error catch (_) {
return null;
}
}
throw RealmError(errMessages.join('\n'));
}

DynamicLibrary _open(String lib) => DynamicLibrary.open(lib);
Never throwError(Iterable<String> candidatePaths) {
throw RealmError(
[
'Could not open $libName. Tried:',
candidatePaths.map((p) => '- "$p"').join('\n'),
isFlutterPlatform //
? 'Hint: Did you forget to add a dependency on the realm package?'
: 'Hint: Did you forget to run `dart run realm_dart install`?'
].join('\n'),
);
}

if (isFlutterPlatform) {
final path = _getPluginPath(libName);
return tryOpen(path) ?? throwError([path]);
} else {
final root = _getNearestProjectRoot(Platform.script.path) ?? _getNearestProjectRoot(p.current);
final candidatePaths = [
libName, // just ask OS..
p.join(_exeDirName, libName), // try finding it next to the executable
if (root != null) p.join(root, 'binary', Platform.operatingSystem, libName), // try finding it relative to project
];
DynamicLibrary? lib;
for (final path in candidatePaths) {
lib = tryOpen(path);
if (lib != null) return lib;
}
elle-j marked this conversation as resolved.
Show resolved Hide resolved
throwError(candidatePaths);
}
}

/// @nodoc
// Initializes Realm library
Expand Down
Loading