Fixed wrapper not found error when running pub run ffigen (#42)
Possibly fixes #41 (Needs to be tested after publishing).
- Using `dart:cli` to resolve package uri and get wrapper.c for running `pub run ffigen:setup`.
- If `dart:cli` is unavailable, fallback tries to work up the current directory to find `.dart_tool/package_config.json` and get rootUri of `package:ffigen` and find wrapper.c from there.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2d65c34..83afb0b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# 0.1.2
+- Fixed wrapper not found error when running `pub run ffigen`.
+
# 0.1.1
- Address pub score: follow dart File conventions, provide documentation, and pass static analysis.
diff --git a/bin/setup.dart b/bin/setup.dart
index e933691..ef618fc 100644
--- a/bin/setup.dart
+++ b/bin/setup.dart
@@ -27,7 +27,7 @@
import 'dart:io';
import 'package:args/args.dart';
import 'package:meta/meta.dart';
-import 'package:ffigen/src/find_dot_dart_tool.dart';
+import 'package:ffigen/src/find_resource.dart';
import 'package:ffigen/src/strings.dart' as strings;
import 'package:path/path.dart' as path;
@@ -140,14 +140,7 @@
///
/// Throws error if not found.
String _getWrapperPath(String wrapperName) {
- final file = File(path.join(
- Platform.script
- .resolve(path.posix.join('..', 'lib', 'src', 'clang_library'))
- // This needs to be in posix style or illegal character exception is
- // thrown on windows.
- .toFilePath(),
- wrapperName,
- ));
+ final file = File.fromUri(findWrapper(wrapperName));
if (file.existsSync()) {
return file.absolute.path;
} else {
diff --git a/lib/src/code_generator.dart b/lib/src/code_generator.dart
index 9eb01b6..efbb1a2 100644
--- a/lib/src/code_generator.dart
+++ b/lib/src/code_generator.dart
@@ -14,4 +14,3 @@
export 'code_generator/struc.dart';
export 'code_generator/type.dart';
export 'code_generator/typedef.dart';
-
diff --git a/lib/src/find_dot_dart_tool.dart b/lib/src/find_dot_dart_tool.dart
deleted file mode 100644
index 07c4a98..0000000
--- a/lib/src/find_dot_dart_tool.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library finddotdarttool;
-
-export 'find_dot_dart_tool/finddotdarttool_fallback.dart'
- if (dart.library.cli) 'find_dot_dart_tool/finddotdarttool_cli.dart';
diff --git a/lib/src/find_dot_dart_tool/finddotdarttool_fallback.dart b/lib/src/find_dot_dart_tool/finddotdarttool_fallback.dart
deleted file mode 100644
index 50e2c4c..0000000
--- a/lib/src/find_dot_dart_tool/finddotdarttool_fallback.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io' show Platform, File;
-
-/// Find the `.dart_tool/` folder, returns `null` if unable to find it.
-Uri findDotDartTool() {
- // HACK: Because 'dart:isolate' is unavailable in Flutter we have no means
- // by which we can find the location of the package_config.json file.
- // Which we need, because the binary library created by:
- // flutter pub run ffigen:setup
- // is located relative to this path. As a workaround we use
- // `Platform.script` and traverse level-up until we find a
- // `.dart_tool/package_config.json` file.
- // Find script directory
- var root = Platform.script.resolve('./');
- // Traverse up until we see a `.dart_tool/package_config.json` file.
- do {
- if (File.fromUri(root.resolve('.dart_tool/package_config.json'))
- .existsSync()) {
- return root.resolve('.dart_tool/');
- }
- } while (root != (root = root.resolve('..')));
- return null;
-}
diff --git a/lib/src/find_resource.dart b/lib/src/find_resource.dart
new file mode 100644
index 0000000..e9a9dae
--- /dev/null
+++ b/lib/src/find_resource.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library find_resource;
+
+export 'find_resource/find_resource_fallback.dart'
+ if (dart.library.cli) 'find_resource/find_resource_cli.dart';
diff --git a/lib/src/find_dot_dart_tool/finddotdarttool_cli.dart b/lib/src/find_resource/find_resource_cli.dart
similarity index 73%
rename from lib/src/find_dot_dart_tool/finddotdarttool_cli.dart
rename to lib/src/find_resource/find_resource_cli.dart
index 0773410..d3885b5 100644
--- a/lib/src/find_dot_dart_tool/finddotdarttool_cli.dart
+++ b/lib/src/find_resource/find_resource_cli.dart
@@ -5,7 +5,7 @@
import 'dart:cli' as cli;
import 'dart:io' show File;
import 'dart:isolate' show Isolate;
-import 'finddotdarttool_fallback.dart' as fallback;
+import 'find_resource_fallback.dart' as fallback;
/// Find the `.dart_tool/` folder, returns `null` if unable to find it.
Uri findDotDartTool() {
@@ -27,3 +27,11 @@
// current script location and traverse up from there.
return fallback.findDotDartTool();
}
+
+Uri findWrapper(String wrapperName) {
+ final wrapperUri = cli.waitFor(Isolate.resolvePackageUri(
+ Uri.parse('package:ffigen/src/clang_library/$wrapperName')));
+ // If [Isolate.packageConfig] isn't helpful we fallback to looking at the
+ // current script location and traverse up from there.
+ return wrapperUri ?? fallback.findWrapper(wrapperName);
+}
diff --git a/lib/src/find_resource/find_resource_fallback.dart b/lib/src/find_resource/find_resource_fallback.dart
new file mode 100644
index 0000000..0db61ee
--- /dev/null
+++ b/lib/src/find_resource/find_resource_fallback.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert' show jsonDecode;
+import 'dart:io' show File, Directory;
+
+/// Find the `.dart_tool/` folder, returns `null` if unable to find it.
+Uri findDotDartTool() {
+ // HACK: Because 'dart:isolate' is unavailable in Flutter we have no means
+ // by which we can find the location of the package_config.json file.
+ // Which we need, because the binary library created by:
+ // flutter pub run ffigen:setup
+ // is located relative to this path. As a workaround we use
+ // `Platform.script` and traverse level-up until we find a
+ // `.dart_tool/package_config.json` file.
+ // Find script directory
+ var root = Directory.current.uri;
+ // Traverse up until we see a `.dart_tool/package_config.json` file.
+ do {
+ if (File.fromUri(root.resolve('.dart_tool/package_config.json'))
+ .existsSync()) {
+ return root.resolve('.dart_tool/');
+ }
+ } while (root != (root = root.resolve('..')));
+ return null;
+}
+
+Uri findWrapper(String wrapperName) {
+ var root = Directory.current.uri;
+ // Traverse up until we see a `.dart_tool/package_config.json` file.
+ do {
+ final file = File.fromUri(root.resolve('.dart_tool/package_config.json'));
+ if (file.existsSync()) {
+ /// Read the package_config.json file to extract path of wrapper.
+ try {
+ final packageMap =
+ jsonDecode(file.readAsStringSync()) as Map<String, dynamic>;
+ if (packageMap['configVersion'] == 2) {
+ var ffigenRootUriString = ((packageMap['packages'] as List<dynamic>)
+ .cast<Map<String, dynamic>>()
+ .firstWhere(
+ (element) => element['name'] == 'ffigen')['rootUri']
+ as String);
+ ffigenRootUriString = ffigenRootUriString.endsWith('/')
+ ? ffigenRootUriString
+ : ffigenRootUriString + '/';
+
+ /// [ffigenRootUri] can be relative to .dart_tool if its from
+ /// filesystem so we need to resolve it from .dart_tool first.
+ return file.parent.uri
+ .resolve(ffigenRootUriString)
+ .resolve('lib/src/clang_library/$wrapperName');
+ }
+ } catch (e, s) {
+ print(s);
+ throw Exception('Cannot resolve package:ffigen\'s rootUri.');
+ }
+ }
+ } while (root != (root = root.resolve('..')));
+ return null;
+}
diff --git a/lib/src/header_parser/parser.dart b/lib/src/header_parser/parser.dart
index a2b1593..832127a 100644
--- a/lib/src/header_parser/parser.dart
+++ b/lib/src/header_parser/parser.dart
@@ -7,7 +7,7 @@
import 'package:ffi/ffi.dart';
import 'package:ffigen/src/code_generator.dart';
import 'package:ffigen/src/config_provider.dart';
-import 'package:ffigen/src/find_dot_dart_tool.dart';
+import 'package:ffigen/src/find_resource.dart';
import 'package:ffigen/src/header_parser/translation_unit_parser.dart';
import 'package:ffigen/src/strings.dart' as strings;
import 'package:logging/logging.dart';
diff --git a/pubspec.yaml b/pubspec.yaml
index 201cf67..8da3a6a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
name: ffigen
-version: 0.1.1
+version: 0.1.2
homepage: https://github.com/dart-lang/ffigen
description: Experimental generator for FFI bindings, using LibClang to parse C/C++ header files.