native icon indicating copy to clipboard operation
native copied to clipboard

Remove Maven support in favor of helpers

Open HosseinYousefi opened this issue 2 years ago • 5 comments
trafficstars

I think there is a case to be made to completely remove maven support from jnigen's main workflow. We might instead add some helper scripts like dart run jnigen:maven_init that create the intial pom.xml files in the directory.

_Originally posted by @HosseinYousefi in https://github.com/dart-lang/native/issues/742

HosseinYousefi avatar Aug 24 '23 16:08 HosseinYousefi

A package similar to native_toolchain_c, to "replace" writing gradle/maven. Users can add their dependencies to build.dart.

Pros:

  • No need to edit some build.gradle or pom.xml file
  • No need to do gymnastics to find the path of the dependencies to generate bindings for (https://github.com/dart-lang/native/issues/684, https://github.com/dart-lang/native/issues/628) Maybe a con:
  • Users have to add hook/build.dart.

@mosuem @dcharkes wdyt?

HosseinYousefi avatar Jul 16 '24 21:07 HosseinYousefi

I know next to nothing about gradle and maven - so no thoughts from my side. :wink:

mosuem avatar Jul 17 '24 07:07 mosuem

that create the initial pom.xml files in the directory.

What is the output of this user-written hook/build.dart? Currently there's no way to have a "side-effect" (some file existing in your project afterwards).

Such "side-effects" would also only happen during the first Dart compilation (which is inside the Gradle build of an Android app in Flutter), so if you're side-effect generating a file that the Android native build should have picked up, it's too late already. Also, such side effects would happen multiple times in Flutter builds (multiple target architectures), and even more times in flutter run (dry runs).

If you want some file to appear in the project, then it should be a post-pub-get hook instead of a build hook?

Or maybe I've misunderstood what you're trying to achieve. Could you provide more details?

dcharkes avatar Jul 17 '24 07:07 dcharkes

Or maybe I've misunderstood what you're trying to achieve. Could you provide more details?

Something similar to what we want to achieve for C. We could and can still add an externalNativeBuild to build.gradle to build and bundle some C code. In parallel to that, we could build and bundle some C code using build hooks. Both of these will be included.

So users can do something like:

addDependencies([
  'foo.bar',
  'baz.qux',
]);

And these libraries are also downloaded and bundled, alongside anything that already exists in build.gradle.

that create the initial pom.xml files in the directory.

The pom.xml file was the original idea behind this issue. Here, I'm suggesting a different way.

HosseinYousefi avatar Jul 17 '24 08:07 HosseinYousefi

Notes from a discussion with @dcharkes

Managing Android dependencies for codegen

Current workflow

  1. Add the dependency to your plugin's build.gradle
  2. Create an example flutter app that has a main.dart
  3. [Currently] add the same dependency to the build.gradle of the example because somehow the transitive resolution of dependencies is buggy
  4. Add the location of the example app to jnigen.yaml and set add_gradle_deps to true
  5. cd example/ && flutter build apk so gradle resolves and caches the dependencies
  6. cd .. && dart run jnigen --config jnigen.yaml to finally generate the bindings

What are we solving here? The fact that the user doesn't have to specify the dependency in build.gradle AND download a .jar file and/or specify the same dependency again in jnigen.yaml. This can be error-prone due to for example, a version mismatch.

But this approach is extremely hacky. It includes having to build an example project, passsing the path to the example project in the config, and editing the build.gradle file of the example project!

A nicer workflow

  1. Add the dependency to pubspec.yaml
  2. Run dart pub get (which happens when saving the pubspec file in VSCode).
  3. dart run tool/jnigen.dart to generate the bindings.

How to achieve?

Codegen is in the development phase, so we don't want to build to get the dependencies. We need something like a "post-pub-get-hook" that happens after dart pub get. This can download dependencies that are required for codegen from their specification in pubspec.yaml. As a PoC, at first this can be a separate command like dart run jnigen:get.

The same dependencies are then used in the build hook to be bundled in, so the user won't have to specify them twice.

This also solves the hacky ways of accessing the gradle cache.

Concrete steps

For building and bundling we need https://github.com/dart-lang/native/issues/1350. Once this and the general jnigen:get workflow work, we can consider designing a "post-pub-get-hook" to simplify development. This gives the ability to call our tool/jnigen.dart directly in hook/post_pub.dart(?) so changes to the dependencies cause an auto-regen.

HosseinYousefi avatar Jul 17 '24 12:07 HosseinYousefi