使用 ABI 拆分启用 externalNativeBuild

Posted

技术标签:

【中文标题】使用 ABI 拆分启用 externalNativeBuild【英文标题】:Enabling externalNativeBuild with ABI split 【发布时间】:2017-03-06 00:55:14 【问题描述】:

我已经从ndk-build 切换到cmake 构建系统。但无法使 APK 拆分功能起作用。

这是我的应用程序build.gradle 文件

构建的结果只有一个文件 - foo.bar-armeabi-v7a-release-1.5.1.apk。 如果我正在为 x86 模拟器构建应用程序,结果是 foo.bar-x86-release-1.5.1.apk

buildscript 
    repositories 
        maven  url 'https://maven.fabric.io/public' 
    
    dependencies 
        classpath 'io.fabric.tools:gradle:1.+'
    

apply plugin: 'com.android.application'
apply plugin: 'io.fabric'

repositories 
    jcenter()
    maven  url 'https://maven.fabric.io/public' 


android 
    compileOptions.encoding = 'ISO-8859-1'
    compileSdkVersion CompiledSdkVersion
    buildToolsVersion BuildToolsVersion

    defaultConfig 
        applicationId "foo.bar"
        minSdkVersion MinSdkVersion
        targetSdkVersion TargetSdkVersion
        versionCode VersionCode
        versionName VersionName
        vectorDrawables.useSupportLibrary = true

        externalNativeBuild 
            cmake 
                cppFlags "-fexceptions", "-std=c++11"
            
        

        ndk 
            abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
        
    

    signingConfigs 
        release 
            storeFile file("..\\release.keystore")
        
    

    lintOptions 
        checkReleaseBuilds false
        abortOnError false
    

    buildTypes 
        release 
            signingConfig signingConfigs.release
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
        
    

    splits 
        abi 
            enable true
            reset()
            include "armeabi", "armeabi-v7a", "arm64-v8a", "mips", "mips64", "x86", "x86_64"
            universalApk true
        
    

    project.ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'arm64-v8a': 3, 'mips': 5, 'mips64': 6, 'x86': 8, 'x86_64': 9]
    android.applicationVariants.all  variant ->
        variant.outputs.each  output ->
            output.versionCodeOverride = project.ext.versionCodes.get(output.getFilter(com.android.build.OutputFile.FilterType.ABI), 0) * 1000000 + android.defaultConfig.versionCode
            output.outputFile = new File(output.outputFile.parent, output.outputFile.name.replace(".apk", "-$variant.versionName.apk"))
        
    

    externalNativeBuild 
        cmake 
            path 'src/main/jni/CMakeLists.txt'
        
    


crashlytics 
    enableNdk false // too many reports for third-party modules
    androidNdkOut '.externalNativeBuild/cmake/release'
    androidNdkLibsOut 'src/main/libs'


dependencies 
    compile project(':common-sources')
    compile project(':chess-board-library')
    compile project(':number-picker')

    compile files('libs/kxml2-2.3.0.jar')
    compile files('libs/StartADLib-1.0.1.jar')

    compile Dependencies.appCompat
    compile Dependencies.cardView
    compile Dependencies.firebaseAds
    compile Dependencies.googleAnalytics
    compile Dependencies.googlePlus
    compile Dependencies.googleGames

    compile(Dependencies.crashlytics) 
        transitive = true
    
    compile(Dependencies.crashlyticsNdk) 
        transitive = true
    


apply plugin: 'com.google.gms.google-services'

附:如果您可以重现错误但找不到解决方案,请投票my issue in Google's bug tracker。

【问题讨论】:

【参考方案1】:

看起来这是构建工具中的错误。即使使用旧的 ndk-build,ABI 拆分也不起作用。

在研究过程中,我发现了一个很好的解决方法 - 直接从命令行启动构建。

gradlew assembleDebug

gradlew assembleRelease

命令需要从项目的根目录启动。

非常感谢this sudden comment :)

【讨论】:

【参考方案2】:

您的问题似乎出在您的 variables.outputs.each 代码中。一方面,getFilter 只接受一个参数。 (参见Output class 实现。)

请参阅this post,了解为什么不应该使用 com.android.build.OutputFile.ABI(改用 OutputFile.FilterType.ABI)。此问题导致该海报的拆分 APK 失败。

【讨论】:

getFilter 接受一个参数,这是真的。代码output.getFilter(com.android.build.OutputFile.ABI) 中只有一个参数。我试图将com.android.build.OutputFile.ABI 更改为com.android.build.OutputFile.FilterType.ABI,但这没有帮助。 对不起,你是对的,我看错了代码。您可以尝试简化代码,看看是否有所作为。 我尝试进行实验,但没有成功。该代码在升级到 externalBuild 之前肯定有效,所以我相信它。

以上是关于使用 ABI 拆分启用 externalNativeBuild的主要内容,如果未能解决你的问题,请参考以下文章

滑过和拆分视图未启用

如何在 Xcode 中启用 Neon 指令

仅在将 sourceSets 与其他 ABI 的库一起使用时支持 x86 ABI

ABI 管理

如何使用旧 ABI 编译 GCC 5 的 boost?

GCC 5 ABI 更改