bundletool icon indicating copy to clipboard operation
bundletool copied to clipboard

Split custom assets by device ABI?

Open jonathanpeppers opened this issue 4 years ago • 17 comments

Related to: https://github.com/google/bundletool/issues/116

I was reviewing the code and I don't see a way to have custom files split up per ABI:

https://github.com/google/bundletool/blob/ae0fc0162fd80d92ef8f4ef4527c066f0106942f/src/main/java/com/android/tools/build/bundletool/model/targeting/TargetedDirectorySegment.java#L52-L55

But you can do it for language or other "dimensions".

I work on .NET (for Android), and we have .NET assembly files such as:

assemblies/MultipleArch.dll
assemblies/armeabi-v7a/SingleArch.dll
assemblies/arm64-v8a/SingleArch.dll

I was looking for a way to split up these custom files per architecture. Is there a way to do this? Thanks!

jonathanpeppers avatar Nov 11 '20 22:11 jonathanpeppers

Unfortunately splitting assets by device ABI is not supported now and we don't have short term plans to support this.

ymakhno avatar Nov 12 '20 20:11 ymakhno

Thanks @ymakhno,

If I were to implement this feature, adding support for a path similar to assemblies/#abi_armeabi-v7a/SingleArch.dll.

Assuming I sent a PR and it made it in, would there need to be changes to Google Play's backend as well? Or would it work even if we had our own fork of bundletool?

jonathanpeppers avatar Nov 12 '20 21:11 jonathanpeppers

Any reason you can't put the .dll files under lib/?

plecesne avatar Nov 12 '20 22:11 plecesne

@plecesne thanks, I'll give the lib folder a try and see if it works.

jonathanpeppers avatar Nov 12 '20 22:11 jonathanpeppers

The lib folder seems like it has some expectations for .so files:

[BT : 1.2.0] error : Native library files need to have paths in form 'lib/<single-directory>/<file>.so' but found 'lib/HelloWorld.dll'.

In this case, we would want HelloWorld.dll in the base .apk. There would be only some assemblies that are armeabi-v7a or x86-specific.

jonathanpeppers avatar Nov 16 '20 22:11 jonathanpeppers

Could you please provide a bit more information about these assemblies to be able to identify a better solution for the problem? Why are some assemblies architecture specific and some not? Do architecture specific assemblies contain native code inside, are they effectively native libraries?

ymakhno avatar Nov 18 '20 20:11 ymakhno

These are .NET assemblies that contain IL that drives languages like C# or F#. It isn't native code. Our Android support was originally a product called Xamarin that we are working on moving to be a general feature of .NET.

A developer's C# code in their app would generally work on any architecture, but some libraries are highly optimized per architecture. An example would be parts of the Base Class Libraries such as System.Private.CoreLib.dll.

jonathanpeppers avatar Nov 18 '20 21:11 jonathanpeppers

Thank you for the explanation! Two more questions:

  • How big are architecture specific dlls?
  • How do you plan to use these dlls? Extract from APK to some folder and next load it or just read as InputStream from the APK itself?

ymakhno avatar Nov 19 '20 20:11 ymakhno

  • I compared two small apps and I saw about 1 - 2.2MB of assemblies per architecture. Larger applications could have more, I would think.
  • .dll files are stored uncompressed and we have native code that uses mmap to load them directly. This is similar to how extractNativeLibs="false" works, I think.

jonathanpeppers avatar Nov 19 '20 21:11 jonathanpeppers

Thanks! Probably instead of me spamming you with questions it would be easier for me to just play with the technology to understand which assemblies are architecture-specific and which are not and how changes in code affect size of both. Could you please share a link to a good manual I can use?

ymakhno avatar Nov 19 '20 21:11 ymakhno

We are still developing this, but we have working samples with preview builds here:

https://github.com/xamarin/net6-samples

To build an app bundle, you can build the Android project:

dotnet build HelloAndroid -p:Configuration=Release -p:AndroidPackageFormat=aab

And you should be able to find the build output in bin\Release\.

If you want to play with Xamarin, in general, you might be better off trying the guides for the stable product here. But we don't have these architecture-specific assemblies today.

jonathanpeppers avatar Nov 19 '20 23:11 jonathanpeppers

I've played with Xamarin a bit and understand your usecase better now.

Currently you put CLI assemblies under root folder inside aab. This folder by design contains files that should go to the main split and that's why files there are not splittable. But we can support platform targeting inside assets (like we already have for languages as an example) so in your case you will be able to put assemblies like presented below:

/
|--assets
|   |--assemblies
|   |   |-- SQLLite-net.dll
|   |   |
|   |   |-- platform#abi_armeabi-v7a
|   |   |    |-- System.Core.dll
|   |   |
|   |   |-- platform#abi_arm64-v8a
|   |   |    |-- System.Core.dll

Does it work for you? Will you be able to move assemblies to assets instead of root?

ymakhno avatar Dec 01 '20 14:12 ymakhno

@ymakhno yes, we can move them to assets. It actually might make more sense than picking our own directory name in the root.

Do you think platform#abi_armeabi-v7a would work today, or would this need to be added? Thanks!

jonathanpeppers avatar Dec 01 '20 14:12 jonathanpeppers

It won't work today, I'll try to land it into next bundletool release. Will update this ticket once done.

ymakhno avatar Dec 01 '20 15:12 ymakhno

Unfortunately I found out that solution that I wrote above won't be as easy to implement as I thought initially. I'll keep the issue open to keep it on our radar, but a short term workaround I can propose at the moment is only one described in #116.

ymakhno avatar Jan 22 '21 11:01 ymakhno

Thanks. Are you suggesting to put the files under lib? https://github.com/google/bundletool/issues/116#issuecomment-525328049

Would we have to rename their extension to .so? I was hitting this error when I tried: https://github.com/google/bundletool/issues/190#issuecomment-728357280

jonathanpeppers avatar Jan 22 '21 14:01 jonathanpeppers

I think if you rename to .so it will solve the problem, if you don't want Android Platform to treat this file as a library I think you can skip lib prefix and have something like assembly-core.dll.so.

ymakhno avatar Jan 22 '21 16:01 ymakhno