dart-lang / native

Dart packages related to FFI and native assets bundling.
BSD 3-Clause "New" or "Revised" License
105 stars 36 forks source link

Improve detection of Android SDK and Dependencies. #793

Open mahesh-hegde opened 1 year ago

mahesh-hegde commented 1 year ago
  1. Finding Android SDK is done through ANDROID_SDK_ROOT environment variable but there's no guarantee it's set on all systems. Best method will be somehow obtain the config of Flutter SDK, but not sure it can be programmatically obtained, other than grepping the output of flutter doctor.

  2. Android's core library stubs are in android.jar and easy to find once we have SDK root. But other libraries including androidx are fetched by gradle and included in compile classpath. It would be nice to have a way to obtain compile classpath for android part of the flutter project. (The use case is writing some platform specific java code in android/ part of the flutter project and integrating it via jnigen.).

Alternatively it might be possible to copy dependency jars into temporary folder like we are doing with maven. I am still investigating it. It's important to not to tamper with any existing gradle config or leave trace of stub files created..

A point of friction is that Android gradle plugin does so many things differently and answers / guides related to standard java - gradle combination don't work anymore. :(

mahesh-hegde commented 1 year ago

I was able to get compile time gradle classpath using a hack.

Here's how it works:

Besides modifying sources, it requires us to have built the android project at least once. Or else gradle fails to resolve classpaths. Also it lists some preprocessed JARs which are not strictly required. The resulting classpath will be very large. I couldn't find a way to get only around these issues.

Without this gradle hack, we won't be able to use androidx etc.. libraries (anything apart from core android. namespace) in the custom java code we write, which is a huge drawback. So I am implementing this opt-in and leaving a choice to just use android SDK (by explicitly SDK version order).

But in long term, we should find a way to handle this gradle issue and deprecate manually looking for SDKs.

dcharkes commented 1 year ago
  1. Finding Android SDK is done through ANDROID_SDK_ROOT environment variable but there's no guarantee it's set on all systems. Best method will be somehow obtain the config of Flutter SDK, but not sure it can be programmatically obtained, other than grepping the output of flutter doctor.

In package:ffigen we have a best effort to find a libclang somewhere on the system with (1) some default install paths, and (2) different command-line utilities. I think it is fine to try multiple methods, and give an error if none worked.

mahesh-hegde commented 1 year ago

The best method is when gradle can be used. If that's possible no other trick will be required.

In theory, gradle has all the config we need somewhere. But I can't just figure out how to access the exact list of JAR files before preprocessing. Doesn't help that gradle is much more complex than maven.

The problem is more about gradle than it's about finding Android SDK root through environment variable. If it's possible to plug into android gradle subproject through a hook and get the required properties, that would get classpath for all dependencies of the android project, and no need to specify anything like SDK version by hand.

    Mahesh

On Wed, 31 Aug, 2022, 1:39 pm Daco Harkes, @.***> wrote:

  1. Finding Android SDK is done through ANDROID_SDK_ROOT environment variable but there's no guarantee it's set on all systems. Best method will be somehow obtain the config of Flutter SDK, but not sure it can be programmatically obtained, other than grepping the output of flutter doctor.

In package:ffigen we have a best effort to find a libclang somewhere on the system with (1) some default install paths, and (2) different command-line utilities. I think it is fine to try multiple methods, and give an error if none worked.

— Reply to this email directly, view it on GitHub https://github.com/dart-lang/jni_gen/issues/33#issuecomment-1232607775, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALAKLFVC2ZGGDNXAV5U2XCTV34HKPANCNFSM57YYTY2Q . You are receiving this because you authored the thread.Message ID: @.***>

mahesh-hegde commented 1 year ago

Update: this mostly solved problem for in-app glue code. But we need a general mechanism to get source for gradle libraries.

cc: @HosseinYousefi @dcharkes

mahesh-hegde commented 1 year ago

Self-assigning this for the time being.

A breakdown of what needs to be figured out.

Note 1: There are many answers on SO for Gradle with Java SE which do not work for AGP.

Optionally:

mahesh-hegde commented 1 year ago

To my pleasant surprise, this works with AGP

https://stackoverflow.com/questions/39975780/how-can-i-use-gradle-to-download-dependencies-and-their-source-files-and-place-t/39981143#39981143

AlexV525 commented 2 months ago

The cronet_http still applies a gradle dependency to the example explicitly to make jnigen work, which covers up other issues like https://github.com/dart-lang/http/issues/1179 which cannot be reproduced by the example because the dependency is there.

https://github.com/dart-lang/http/blob/5c01453ab467408194143d4106092201f03ed98e/pkgs/cronet_http/example/android/app/build.gradle#L74-L76

HosseinYousefi commented 1 month ago

Thanks for reporting this, @AlexV525. I plan to tackle these issues for 0.11.0.