Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi arch support for Android #1392

Closed
teobugslayer opened this issue Jan 13, 2016 · 23 comments
Closed

Multi arch support for Android #1392

teobugslayer opened this issue Jan 13, 2016 · 23 comments
Labels

Comments

@teobugslayer
Copy link
Contributor

Multi arch support for Android

Overview

Users of NativeScript face conflicting goals when using architecture-dependant native code (*.so files).
During development they want to build their program very quickly to iterate very fast. They usually develop for x86 emulator (like Genymotion or Visual Studio) and arm-based testing devices.

When publishing to Google Play Store, they may need to split the archive to avoid the 100 MB file size limit currently imposed.

Additional obstacle is that 64-bit Android does not allow mixing 64-bit and 32-bit architecture-dependent native code. When a single dependency introduces a 64-bit .so file, all dependencies must be 64-bit as well. This can easily slip during development, when people usually use 32-bit devices and emulators.

Proposed work flow

We need to solve these problems in couple of places: The CLI, the Docs and the Gradle scripts

I propose this behavior:

  • Android runtime introduces aarch64 build [Android runtime]
  • introduce options to control the architectures included in the apk during build:
    • --arch all (default), armeabi-v7a, arm64-v8a, x86, x86_64. Multiple architectures are allowed. The names are the IDs taken from Android docs [CLI]
  • this option must be passed to the gradle build script [CLI, Android runtime]
  • Gradle build script builds the correct apk [Android runtime]
  • If a pluging is missing requested architecture, stop the build. This does not apply when only jars are used [Android runtime]
  • The option is mandatory for the future publish command. It is also mandatory for build --release (but see bellow for comments). When building without --release, it is not mandatory. [CLI]
  • document the proper structure of NativeScript plugin to allow including of .so files. See http://docs.nativescript.org/runtimes/android/getting-started/project-structure and http://docs.nativescript.org/plugins/plugins [@ErjanGavalji]

iOS

Apple has different requirements for publishing to App Store. I believe that build and publish commands can differ in this case. iOS specific functionality should be addressed in a dedicated issue.

Comments:

  • If we make --arch mandatory for building in release mode, AppBuilder team will need to revise the BpcTooling to introduce it. Also, this may not be the optimal behavior for the user.
@NathanaelA

This comment was marked as abuse.

@Plamen5kov
Copy link
Contributor

In the fourth case:

"If a pluging is missing requested architecture, stop the build. This does not apply when only jars or aars are used [Android runtime]"

.aar files can contain .so files so we should take care of that too.

@teobugslayer
Copy link
Contributor Author

@Plamen5kov - updated the text, thank you!

@slavchev
Copy link

👍

@teobugslayer teobugslayer changed the title Proposal for multi arch support for Android in NativeScript Multi arch support for Android in NativeScript Jan 14, 2016
@teobugslayer teobugslayer changed the title Multi arch support for Android in NativeScript Multi arch support for Android Jan 14, 2016
@blagoev
Copy link
Contributor

blagoev commented Jan 14, 2016

@teobugslayer some notes
The apk limit is 100MB currently.

We need to think support for all scenarios in http://developer.android.com/google/play/publishing/multiple-apks.html

Also if there is no 64bit libs in my app why the option is mandatory. A 32bit app will run fine on 64 bit devices.

I think we should package a single apk by default (and as per the guidance) and introduce complexity only when user wants it. And If he wants it allow all possible options. The tns build tools should not constrain the developer.

@teobugslayer
Copy link
Contributor Author

@blagoev, when we switch to using combined 32 and 64 bit {N} runtime, there always will be 64 bit code in the APK. We can either make the option mandatory (again, only for the "publish" command"), or default to something which we consider "safe", like, 32-bit only build, all build, or something else. Opinions?

@blagoev
Copy link
Contributor

blagoev commented Feb 8, 2016

@teobugslayer for the publish command only it is ok to have this to be mandatory. If there are no other 64bit libs in the project we can build against a 32bit only runtime. We just need to make sure the build fails if there is one plugin which does not have a 64bit library on 64 builds.

@NathanaelA

This comment was marked as abuse.

@calebeaires
Copy link

👍

@rosen-vladimirov rosen-vladimirov removed this from the 2.0 milestone Mar 31, 2016
@ddfreiling
Copy link

ddfreiling commented Jun 8, 2016

Hello. I was wondering if there is still no way to make tns build for a specific android architecture?

In an app we're currently working on we want to use libVLC through a plugin. But it really slows down our development process that we arent able to build for one architecture at a time.

If anyone knows of a manual fix to the build.gradle file it would be very much appreciated. Maybe something like abiFilters?

@enchev
Copy link
Contributor

enchev commented Jun 13, 2016

Hey @Plamen5kov,

Do you know such manual fix?

@ddfreiling
Copy link

ddfreiling commented Jun 13, 2016

@enchev
I used to be able to do this in my plugin include.gradle file:

android {
    productFlavors {
        'nativescript-plugin-name' {
            dimension 'nativescript-plugin-name'

            // Setting below requires 'android.useDeprecatedNdk=true'
            // in platforms/android/gradle.properties file.
            ndk {
                abiFilters 'armeabi-v7a'
            }
        ...

But it doesn't seem like it's possible anymore in the latest version of Nativescript CLI.

@Plamen5kov
Copy link
Contributor

Hi @dfg-nota
I don't believe the new version of cli can change the way include.gradle works. What you're doing should be working. Let me check it out and i'll get back to you.
Could you give me the version of CLI you're using?

@ddfreiling
Copy link

ddfreiling commented Jun 13, 2016

@Plamen5kov I just checked my platforms/android/configurations folder after a build and it seems my plugin include.gradle file from above is turned into this:

android {
    productFlavors {
              "F0" {
                dimension "nativescriptpluginname"
              }
            }
}
dependencies {
    compile 'de.mrmaffen:vlc-android-sdk:1.9.8'
}

ndk abiFilters was removed. It seems the replaceProductFlavorInContent function in build.gradle strips it out.

@Plamen5kov
Copy link
Contributor

Hi @dfg-nota,
I tested it out and you're right, you can open an issue in the android-runtime.

@ansarizafar
Copy link

I am facing the same issue. Is there any work around available?

@Plamen5kov
Copy link
Contributor

Hi @ansarizafar,
You can reduce the apk size for android. You can look at the documentation here under the APKs with ABI splits section. Additionally you can look at this issue.

@tsonevn tsonevn added this to the 2.6.0 (TBD) milestone Dec 5, 2016
@pkoleva pkoleva modified the milestone: 2.6.0 (TBD) Jan 26, 2017
@Plamen5kov Plamen5kov removed their assignment Mar 29, 2017
@ghost
Copy link

ghost commented Mar 31, 2017

@Plamen5kov Any chance this will get in 3.0? It's a pain having to double my build time and run commands twice, compiling arm and x86 separately, especially at scale

@Plamen5kov
Copy link
Contributor

Plamen5kov commented Mar 31, 2017

Hi @vbresults you can use this PR, where abi split configuration is respected and once tns build android is ran there are two resulting apk files:

testapp-debug-x86.apk
testapp-debug-armeabi-v7a.apk

I can't tell if there will be functionality enabled in cli to help with the workflow for 3.0, but you would be able to edit the app.gradle file and it's changes will be respected.

@petekanev
Copy link
Contributor

Starting with android runtime v3.0.0 when abi split configuration is provided in the app/App_Resources/Android/app.gradle script, apks for all distinct architectures will be output, allowing the developer to publish smaller packages in the Google Play Store.

Please refer to the Publishing for Android article if you want to learn how to setup ABI splits.

Closing this as resolved.

@ghost
Copy link

ghost commented Jul 30, 2017

@Plamen5kov @Pip3r4o The splits code sample/doc doesn't set a different versionCode for each ABI and therefore it can't be used to publish to the app stores.

Please update the docs, this is what I use (armv7 adds 2 to the base version code, x86 adds 4) at the bottom of my app.gradle:

ext.abiCodes = ['armeabi-v7a': 2, x86: 4]

android.applicationVariants.all { variant ->
	variant.outputs.each { output ->
		def baseAbiVersionCode = project.ext.abiCodes.get(output.getFilter("ABI"))

		if (baseAbiVersionCode != null) {
			output.versionCodeOverride = baseAbiVersionCode + variant.versionCode
		}
	}
}

@petekanev
Copy link
Contributor

@vbresults Thanks for reporting that behavior. What you point out is indeed the case with the APKs, they don't have a distinct version code themselves. The respective code configuring the apks can be found here - https://github.com/NativeScript/android-runtime/blob/master/build-artifacts/project-template-gradle/build.gradle#L162 . Do you have a suggestion on general naming of apks configured with separate ABIs? The abiCodes list with the 2 and 4 versions appears non-standard.

Would you be willing to submit a PR?

@ghost
Copy link

ghost commented Jul 31, 2017

@Pip3r4o The official guide (where I got 95% of my code) shows a convention but I personally don't want to be locked into their versionCode * 1000 formula. What to do here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests