[jnigen] fix: pr_checks now works on macOS (https://github.com/dart-lang/jnigen/issues/108)
diff --git a/.github/workflows/test-package.yml b/.github/workflows/test-package.yml index 6e252d8..a57feba 100644 --- a/.github/workflows/test-package.yml +++ b/.github/workflows/test-package.yml
@@ -247,6 +247,55 @@ - run: dart run jnigen:setup - run: dart test + test_jni_macos_minimal: + needs: [analyze_jni] + runs-on: macos-latest + defaults: + run: + working-directory: ./pkgs/jni + steps: + - uses: actions/checkout@v3 + - uses: subosito/flutter-action@v2 + with: + channel: 'stable' + cache: true + cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:' + - uses: actions/setup-java@v2 + with: + distribution: 'temurin' + java-version: '11' + - run: dart pub get + - run: dart run jni:setup + ## TODO(#51): -j 1 is required to avoid a rare race condition which is caused by + ## all tests which spawn JVM being run in same process. + - run: dart test -j 1 + + test_jnigen_macos_minimal: + needs: [analyze_jnigen] + runs-on: macos-latest + defaults: + run: + working-directory: ./pkgs/jnigen + steps: + - uses: actions/checkout@v3 + - name: Setup clang format + uses: ConorMacBride/install-package@v1 + with: + brew: clang-format + - uses: subosito/flutter-action@v2 + with: + channel: 'stable' + cache: true + cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:' + - uses: actions/setup-java@v2 + with: + distribution: 'temurin' + java-version: '11' + - run: git config --global core.autocrlf true + - run: dart pub get + - run: dart run jnigen:setup + - run: dart test + build_jni_example_linux: runs-on: ubuntu-latest defaults:
diff --git a/pkgs/jni/bin/setup.dart b/pkgs/jni/bin/setup.dart index 23226c3..eb4f9c9 100644 --- a/pkgs/jni/bin/setup.dart +++ b/pkgs/jni/bin/setup.dart
@@ -236,7 +236,12 @@ Platform.isWindows ? tempDir.uri.resolve("Debug") : tempDir.uri; final dllDir = Directory.fromUri(dllDirUri); for (var entry in dllDir.listSync()) { - final dllSuffix = Platform.isWindows ? "dll" : "so"; + verboseLog(entry.toString()); + final dllSuffix = Platform.isWindows + ? "dll" + : Platform.isMacOS + ? "dylib" + : "so"; if (entry.path.endsWith(dllSuffix)) { final dllName = entry.uri.pathSegments.last; final target = buildDir.uri.resolve(dllName);
diff --git a/pkgs/jni/example/macos/Flutter/Flutter-Debug.xcconfig b/pkgs/jni/example/macos/Flutter/Flutter-Debug.xcconfig index c2efd0b..4b81f9b 100644 --- a/pkgs/jni/example/macos/Flutter/Flutter-Debug.xcconfig +++ b/pkgs/jni/example/macos/Flutter/Flutter-Debug.xcconfig
@@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig"
diff --git a/pkgs/jni/example/macos/Flutter/Flutter-Release.xcconfig b/pkgs/jni/example/macos/Flutter/Flutter-Release.xcconfig index c2efd0b..5caa9d1 100644 --- a/pkgs/jni/example/macos/Flutter/Flutter-Release.xcconfig +++ b/pkgs/jni/example/macos/Flutter/Flutter-Release.xcconfig
@@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig"
diff --git a/pkgs/jni/example/macos/Podfile b/pkgs/jni/example/macos/Podfile new file mode 100644 index 0000000..dade8df --- /dev/null +++ b/pkgs/jni/example/macos/Podfile
@@ -0,0 +1,40 @@ +platform :osx, '10.11' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end
diff --git a/pkgs/jni/example/pubspec.lock b/pkgs/jni/example/pubspec.lock index 129041a..03efa2c 100644 --- a/pkgs/jni/example/pubspec.lock +++ b/pkgs/jni/example/pubspec.lock
@@ -7,7 +7,7 @@ name: archive url: "https://pub.dartlang.org" source: hosted - version: "3.1.11" + version: "3.3.0" args: dependency: transitive description: @@ -21,7 +21,7 @@ name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" boolean_selector: dependency: transitive description: @@ -35,21 +35,14 @@ name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" + version: "1.2.1" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" collection: dependency: transitive description: @@ -63,7 +56,7 @@ name: crypto url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "3.0.2" cupertino_icons: dependency: "direct main" description: @@ -77,7 +70,7 @@ name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" ffi: dependency: "direct main" description: @@ -144,21 +137,21 @@ name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.11" + version: "0.12.12" material_color_utilities: dependency: transitive description: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" package_config: dependency: transitive description: @@ -172,7 +165,7 @@ name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" platform: dependency: transitive description: @@ -205,7 +198,7 @@ name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.9.0" stack_trace: dependency: transitive description: @@ -226,35 +219,35 @@ name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" sync_http: dependency: transitive description: name: sync_http url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.3.1" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.12" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" vector_math: dependency: transitive description: @@ -268,7 +261,7 @@ name: vm_service url: "https://pub.dartlang.org" source: hosted - version: "8.2.2" + version: "9.0.0" webdriver: dependency: transitive description:
diff --git a/pkgs/jni/ffigen.yaml b/pkgs/jni/ffigen.yaml index 3833215..b022309 100644 --- a/pkgs/jni/ffigen.yaml +++ b/pkgs/jni/ffigen.yaml
@@ -49,6 +49,7 @@ typedefs: exclude: - 'va_list' + - '__builtin_va_list' rename: 'JNI(.*)': 'Jni$1' 'jint': 'JInt'
diff --git a/pkgs/jni/lib/src/jni.dart b/pkgs/jni/lib/src/jni.dart index 36c5220..96ba918 100644 --- a/pkgs/jni/lib/src/jni.dart +++ b/pkgs/jni/lib/src/jni.dart
@@ -20,7 +20,7 @@ } else if (Platform.isWindows) { return "$base.dll"; } else if (Platform.isMacOS) { - return "$base.framework/$base"; + return "lib$base.dylib"; } else { throw UnsupportedError("cannot derive library name: unsupported platform"); }
diff --git a/pkgs/jnigen/.gitignore b/pkgs/jnigen/.gitignore index c66a8b6..a63fd72 100644 --- a/pkgs/jnigen/.gitignore +++ b/pkgs/jnigen/.gitignore
@@ -5,6 +5,8 @@ .packages build/ pubspec.lock +.flutter-plugins +.flutter-plugins-dependencies # created by maven /target/
diff --git a/pkgs/jnigen/tool/pre_commit_checks.dart b/pkgs/jnigen/tool/pr_checks.dart similarity index 72% rename from pkgs/jnigen/tool/pre_commit_checks.dart rename to pkgs/jnigen/tool/pr_checks.dart index 07eb0b6..0b8ad52 100644 --- a/pkgs/jnigen/tool/pre_commit_checks.dart +++ b/pkgs/jnigen/tool/pr_checks.dart
@@ -16,26 +16,46 @@ import 'dart:async'; import 'dart:io'; +import 'package:args/args.dart'; + import 'command_runner.dart'; -void main() async { +// Flags +const _clone = 'clone'; + +void main(List<String> arguments) async { + final parser = ArgParser() + ..addFlag( + _clone, + help: 'Run checks in a cloned copy of the project.', + defaultsTo: true, + negatable: true, + ); + final argResults = parser.parse(arguments); + final shouldClone = argResults[_clone] as bool; final gitRoot = getRepositoryRoot(); // change to project root Directory.current = gitRoot.toFilePath(); - final tempDir = Directory.current.createTempSync('jnigen_checks_clone_'); - final tempJniPath = tempDir.uri.resolve("jni/"); - final tempJnigenPath = tempDir.uri.resolve("jnigen/"); - final gitClone = Runner("Clone jni", Directory.current.uri) - ..chainCommand('git', ['clone', '.', tempDir.path]) - ..chainCommand("flutter", ["pub", "get", "--offline"], - workingDirectory: tempJniPath) - ..chainCommand("dart", ["pub", "get", "--offline"], - workingDirectory: tempJnigenPath); - await gitClone.run(); + var tempDir = Directory.current; + if (shouldClone) { + tempDir = Directory.current.createTempSync('jnigen_checks_clone_'); + final gitClone = Runner("Clone jni", Directory.current.uri) + ..chainCommand('git', ['clone', '.', tempDir.path]); + await gitClone.run(); + } - final jniAnalyze = Runner("Analyze JNI", tempJniPath); + final jniPath = tempDir.uri.resolve("jni/"); + final jnigenPath = tempDir.uri.resolve("jnigen/"); + final pubGet = Runner("Pub get", tempDir.uri) + ..chainCommand("flutter", ["pub", "get", "--offline"], + workingDirectory: jniPath) + ..chainCommand("dart", ["pub", "get", "--offline"], + workingDirectory: jnigenPath); + await pubGet.run(); + + final jniAnalyze = Runner("Analyze JNI", jniPath); jniAnalyze ..chainCommand("dart", ["analyze", "--fatal-infos"]) ..chainCommand( @@ -50,8 +70,8 @@ "third_party/global_jni_env.c", "third_party/global_jni_env.h", ], - workingDirectory: tempJniPath.resolve("src/")); - final jniTest = Runner("Test JNI", tempJniPath) + workingDirectory: jniPath.resolve("src/")); + final jniTest = Runner("Test JNI", jniPath) ..chainCommand("dart", ["run", "jni:setup"]) ..chainCommand("dart", ["test", "-j", "1"]); unawaited(jniAnalyze.run().then((f) => jniTest.run())); @@ -60,19 +80,18 @@ .resolve("jni/lib/src/third_party/jni_bindings_generated.dart"); final ffigenBindings = File.fromUri(ffigenBindingsPath); final oldBindingsText = ffigenBindings.readAsStringSync(); - final ffigenCompare = - Runner("Generate & Compare FFIGEN bindings", tempJniPath) - ..chainCommand("dart", ["run", "ffigen", "--config", "ffigen.yaml"]) - ..chainCallback("compare bindings", () async { - final newBindingsText = await ffigenBindings.readAsString(); - if (newBindingsText != oldBindingsText) { - await ffigenBindings.writeAsString(oldBindingsText); - throw "new JNI.h bindings differ from old bindings"; - } - }); + final ffigenCompare = Runner("Generate & Compare FFIGEN bindings", jniPath) + ..chainCommand("dart", ["run", "ffigen", "--config", "ffigen.yaml"]) + ..chainCallback("compare bindings", () async { + final newBindingsText = await ffigenBindings.readAsString(); + if (newBindingsText != oldBindingsText) { + await ffigenBindings.writeAsString(oldBindingsText); + throw "new JNI.h bindings differ from old bindings"; + } + }); unawaited(ffigenCompare.run()); - final jnigenAnalyze = Runner("Analyze jnigen", tempJnigenPath) + final jnigenAnalyze = Runner("Analyze jnigen", jnigenPath) ..chainCommand("dart", ["analyze", "--fatal-infos"]) ..chainCommand( "dart", ["format", "--output=none", "--set-exit-if-changed", "."]) @@ -136,6 +155,8 @@ final notificationPlugin = compareNotificationPluginBindings.run(); return Future.wait([test, inAppJava, pdfBox, notificationPlugin]); }).then((_) { - tempDir.deleteSync(recursive: true); + if (shouldClone) { + tempDir.deleteSync(recursive: true); + } })); }