rainyl / opencv_dart

OpenCV bindings for Dart language and Flutter. Support Asynchronous Now!
https://pub.dev/packages/opencv_dart
Apache License 2.0
136 stars 18 forks source link

Android Plugin custom arch support #211

Closed einsitang closed 3 months ago

einsitang commented 3 months ago

I'm use opencv_dart on my project , but release apk files that are getting to big,I try to optimize file sizes,so I found the apk with some binary file is no need.

so I find a way to exclude so file on useless arch.

this PR just for Android Plugin work , just work well on me , I did't compile and test complete opencv_dart , can't change code with C/C++/MAKEFILE chain tool thing because I not work on these and no executable environment.

you may need complete build/testing pipeline to verify merge code.

I added OPENCV_DART_ANDROID_SUPPORT_ARCHS flag on file android/build.gradle.

can let user set environment before build apk (Android only) , android gradle prebuild task will only copy support arch .so file with only need.

here is use case:

flutter build release without OPENCV_DART_ANDROID_SUPPORT_ARCHS define

unset OPENCV_DART_ANDROID_SUPPORT_ARCHS
flutter build apk --release
✓ Built build/app/outputs/flutter-apk/app-release.apk (200.1MB)

flutter build release with OPENCV_DART_ANDROID_SUPPORT_ARCHS define arm64-v8a,armeabi-v7a

export OPENCV_DART_ANDROID_SUPPORT_ARCHS=arm64-v8a,armeabi-v7a
flutter build apk --release 
✓ Built build/app/outputs/flutter-apk/app-release.apk (141.8MB)

flutter build release with OPENCV_DART_ANDROID_SUPPORT_ARCHS define arm64-v8a,armeabi-v7a

and specified --target-platform=android-arm,android-arm64 (not include libflutter.so on x86/x86_64)

export OPENCV_DART_ANDROID_SUPPORT_ARCHS=arm64-v8a,armeabi-v7a
flutter build apk --release --target-platform=android-arm,android-arm64
✓ Built build/app/outputs/flutter-apk/app-release.apk (123.9MB)

OPENCV_DART_ANDROID_SUPPORT_ARCHS FLAG an only receive 'x86_64', 'arm64-v8a', 'armeabi-v7a' for now

subject to ARCHS on android/build.gradle

def ARCHS = ['x86_64', 'arm64-v8a', 'armeabi-v7a']

which mean if you type in an arch that doesn't exist / support , will skip it

[opencv_dart] OPENCV_DART_ANDROID_SUPPORT_ARCHS is defined : x86_64,arm64-v8a,x86
[opencv_dart] Support arch: x86_64
[opencv_dart] Support arch: arm64-v8a
[opencv_dart] Unsupport arch: x86
[opencv_dart] OPENCV_DART for Android support arch : [x86_64, arm64-v8a]

issues :

in addition, I found that the ios makefile script only supports os64 arch, no arm64 and os64, which means opencv_dart can’t run on ios emulator ? I did’t test yet.

remind :

I saw your license not add name of copyright owner

rainyl commented 3 months ago

@einsitang first of all, thanks for your contribution!

however, i personally think it's not necessary, flutter support splitting for different abi, check at here: https://docs.flutter.dev/deployment/android#build-an-apk

einsitang commented 3 months ago

https://docs.flutter.dev/deployment/android#build-an-apk

I know it . but split abi mean multiple Archs cannot be supported at the same time . we did't know which chip of arm on device

rainyl commented 3 months ago

oh, all right, that's reasonable. will review it later.

in addition, I found that the ios makefile script only supports os64 arch, no arm64 and os64, which means opencv_dart can’t run on ios emulator ? I did’t test yet.

os64 is an universal xcframework for both x86_64 and arm64, so it works on simulator.

I saw your license not add name of copyright owner

thanks~ will add later.

einsitang commented 3 months ago

This FLAG scenario will only occur in private/enterprise internal distribution, non-professional test platform distribution, network distribution.

if download from app store , the package containing the appropriate abi is automatically selected for distribution , so not need it.

may need to update instructions for these.

os64 is an universal xcframework for both x86_64 and arm64, so it works on simulator.

👍🏻

rainyl commented 3 months ago

Almost fine, I have renamed some variables' names to make it clearer, hope you wont mind it.

einsitang commented 3 months ago

yes , make it easier to read

but you remove task "cleanupExtractLibs" , that mean if not clean pub cache , exist abi file will pack in apk with next build

rainyl commented 3 months ago

we shouldnt make it clean and extract libs again and again every time the app is built, comparing to this, i prefer to let users clean the cache manually, we can provide a new setup option to simplify this, then users can run dart run opencv_dart:setup --clean-cache to remove the cached libs. What do you think?

einsitang commented 3 months ago

At the beginning, the way I conceived was to hope that flutter's explicit commands and parameters could be read when prebuild, but after some searching, I did not find a way to meet the scheme, so I could only use the hack method of environment variables to achieve it.

If you skip the cleaning step, executing the command every time the user wants to package the abi on demand will look like this:

dart run opencv_dart:setup --clean-cache
export FLAG=arm64-v8a,armeabi-v7a
flutter build apk --target-platform=android-arm,android-arm64

It seems too complicated and mentally taxing

Or you could change it to:

dart run opencv_dart:setup --arch=arm,arm64 // default all and run once
flutter build apk --target-platform=android-arm,android-arm64

opencv_dart: The way setup replaces the environment variable FLAG, all the custom devices are grouped into this script, which is easier to understand and more reasonable to use.

You can move the download and extract files out of SOURCE_DIR and into CACHE_DIR, where --clean-cache requires re-download, extract.

Clear SOURCE_DIR/jniLibs each time you prebuild and copy from CACHE_DIR

rainyl commented 3 months ago

Now I think it works fine.

if OPENCV_DART_ANDROID_ENABLED_ABI is defined, all specified ABIs will be processed as:

And then you can:

export OPENCV_DART_ANDROID_ENABLED_ABI="arm64-v8a,armeabi-v7a"
flutter build apk --target-platform=android-arm,android-arm64

@einsitang what do you think now? Whether it works for you?