Android - Gradle - 当两种风格共享相同的依赖关系时,如何强制gradle仅构建特定配置

时间:2017-07-26 12:54:30

标签: android gradle android-gradle

我们开发了一个Android库,它有两种叫做#34; armv7"和" x86",它们中的每一个都依赖于特定于平台的本机(NDK)库,并且它们是分开捆绑的。

我们还有一个测试Android应用程序,它使用前面提到的库项目作为依赖项,也构建为两种不同的风格。此应用程序还依赖于Android兼容性库(appcompat)。

问题是,当我尝试只构建应用程序的一种风格时,它仍然构建了库的两种风格(参见下面的示例),这使得Android Studio中的编译时间很长(我们的NDK阶段非常冗长),并且阻止我们在Jenkins的Deployment作业中分离各种口味的构建。

为了演示这个问题,我已经创建了一个你可以在这里看到的演示项目: https://bitbucket.org/siltus/gradlebug/src

基本上你拥有的是android app和android库的骨架,两者都有两种风格:armv7和x86,app也依赖于appcompat。

App build.gralde

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"

    defaultConfig {
        applicationId "com.test.test1"
        minSdkVersion 19
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        debug {}
        release {}
    }

    productFlavors {
        armv7 {}
        x86 {}
    }
}

dependencies {
    armv7Compile 'com.android.support:appcompat-v7:20.0.0'    
    armv7Compile project(path: ':lib', configuration: 'armv7Debug')

    x86Compile 'com.android.support:appcompat-v7:20.0.0'
    x86Compile project(path: ':lib', configuration: 'x86Debug')

} 

图书馆build.gradle

apply plugin: 'com.android.library'


android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 25

        versionCode 1
        versionName "1.0"

        defaultPublishConfig "debug"
        publishNonDefault true
    }

    buildTypes {
        debug {}
        release {}
    }

    productFlavors {
        armv7 {}
        x86 {}
    }

} 

当我运行此命令时(注意我将其运行为干运行,但您可以跳过-m标志):

$ ./gradlew -m assembleArmv7Debug

这是我得到的输出(注意其名称中包含X86的lib的任务):

:app:preBuild SKIPPED
:app:preArmv7DebugBuild SKIPPED
:app:checkArmv7DebugManifest SKIPPED
:app:preArmv7ReleaseBuild SKIPPED
:app:preX86DebugBuild SKIPPED
:app:preX86ReleaseBuild SKIPPED
:lib:preBuild SKIPPED
:lib:preArmv7DebugBuild SKIPPED
:lib:checkArmv7DebugManifest SKIPPED
:lib:prepareArmv7DebugDependencies SKIPPED
:lib:compileArmv7DebugAidl SKIPPED
:lib:compileArmv7DebugNdk SKIPPED
:lib:compileLint SKIPPED
:lib:copyArmv7DebugLint SKIPPED
:lib:mergeArmv7DebugShaders SKIPPED
:lib:compileArmv7DebugShaders SKIPPED
:lib:generateArmv7DebugAssets SKIPPED
:lib:mergeArmv7DebugAssets SKIPPED
:lib:mergeArmv7DebugProguardFiles SKIPPED
:lib:packageArmv7DebugRenderscript SKIPPED
:lib:compileArmv7DebugRenderscript SKIPPED
:lib:generateArmv7DebugResValues SKIPPED
:lib:generateArmv7DebugResources SKIPPED
:lib:packageArmv7DebugResources SKIPPED
:lib:processArmv7DebugManifest SKIPPED
:lib:generateArmv7DebugBuildConfig SKIPPED
:lib:processArmv7DebugResources SKIPPED
:lib:generateArmv7DebugSources SKIPPED
:lib:incrementalArmv7DebugJavaCompilationSafeguard SKIPPED
:lib:compileArmv7DebugJavaWithJavac SKIPPED
:lib:processArmv7DebugJavaRes SKIPPED
:lib:transformResourcesWithMergeJavaResForArmv7Debug SKIPPED
:lib:transformClassesAndResourcesWithSyncLibJarsForArmv7Debug SKIPPED
:lib:mergeArmv7DebugJniLibFolders SKIPPED
:lib:transformNative_libsWithMergeJniLibsForArmv7Debug SKIPPED
:lib:transformNative_libsWithSyncJniLibsForArmv7Debug SKIPPED
:lib:bundleArmv7Debug SKIPPED
:lib:preX86DebugBuild SKIPPED
:lib:checkX86DebugManifest SKIPPED
:lib:prepareX86DebugDependencies SKIPPED
:lib:compileX86DebugAidl SKIPPED
:lib:compileX86DebugNdk SKIPPED
:lib:copyX86DebugLint SKIPPED
:lib:mergeX86DebugShaders SKIPPED
:lib:compileX86DebugShaders SKIPPED
:lib:generateX86DebugAssets SKIPPED
:lib:mergeX86DebugAssets SKIPPED
:lib:mergeX86DebugProguardFiles SKIPPED
:lib:packageX86DebugRenderscript SKIPPED
:lib:compileX86DebugRenderscript SKIPPED
:lib:generateX86DebugResValues SKIPPED
:lib:generateX86DebugResources SKIPPED
:lib:packageX86DebugResources SKIPPED
:lib:processX86DebugManifest SKIPPED
:lib:generateX86DebugBuildConfig SKIPPED
:lib:processX86DebugResources SKIPPED
:lib:generateX86DebugSources SKIPPED
:lib:incrementalX86DebugJavaCompilationSafeguard SKIPPED
:lib:compileX86DebugJavaWithJavac SKIPPED
:lib:processX86DebugJavaRes SKIPPED
:lib:transformResourcesWithMergeJavaResForX86Debug SKIPPED
:lib:transformClassesAndResourcesWithSyncLibJarsForX86Debug SKIPPED
:lib:mergeX86DebugJniLibFolders SKIPPED
:lib:transformNative_libsWithMergeJniLibsForX86Debug SKIPPED
:lib:transformNative_libsWithSyncJniLibsForX86Debug SKIPPED
:lib:bundleX86Debug SKIPPED
:app:prepareComAndroidSupportAppcompatV72000Library SKIPPED
:app:prepareComAndroidSupportSupportV42000Library SKIPPED
:app:prepareGradlebugLibUnspecifiedArmv7DebugLibrary SKIPPED
:app:prepareArmv7DebugDependencies SKIPPED
:app:compileArmv7DebugAidl SKIPPED
:app:compileArmv7DebugRenderscript SKIPPED
:app:generateArmv7DebugBuildConfig SKIPPED
:app:generateArmv7DebugResValues SKIPPED
:app:generateArmv7DebugResources SKIPPED
:app:mergeArmv7DebugResources SKIPPED
:app:processArmv7DebugManifest SKIPPED
:app:processArmv7DebugResources SKIPPED
:app:generateArmv7DebugSources SKIPPED
:app:incrementalArmv7DebugJavaCompilationSafeguard SKIPPED
:app:compileArmv7DebugJavaWithJavac SKIPPED
:app:compileArmv7DebugNdk SKIPPED
:app:compileArmv7DebugSources SKIPPED
:app:mergeArmv7DebugShaders SKIPPED
:app:compileArmv7DebugShaders SKIPPED
:app:generateArmv7DebugAssets SKIPPED
:app:mergeArmv7DebugAssets SKIPPED
:app:transformClassesWithDexForArmv7Debug SKIPPED
:app:mergeArmv7DebugJniLibFolders SKIPPED
:app:transformNative_libsWithMergeJniLibsForArmv7Debug SKIPPED
:app:processArmv7DebugJavaRes SKIPPED
:app:transformResourcesWithMergeJavaResForArmv7Debug SKIPPED
:app:validateSigningArmv7Debug SKIPPED
:app:packageArmv7Debug SKIPPED
:app:assembleArmv7Debug SKIPPED
:lib:compileArmv7DebugSources SKIPPED
:lib:assembleArmv7Debug SKIPPED

BUILD SUCCESSFUL

Total time: 1.631 secs

为了清楚地了解谁添加了x86 flavor任务的依赖关系,我使用Visteg gradle plugin生成了一个DOT文件,我使用此命令将其呈现给PNG:

$ dot -T png build/reports/visteg.dot -o visteg.dot.png

这就是我所拥有的:

dependency graph

如果你仔细观察,你会看到任务":lib:bundleX86Debug"有效地触发所有其他X86构建任务是":app:prepeareComAndroidSupportAppcompatV72000Library"任务。

虽然不了解这两个不相关的依赖项之间的联系(因为库不依赖于Appcompat)。

我试图改变的事情,并不重要:

  • Gradle android插件版本+ gradle版本
  • 构建工具版本
  • Android SDK目标/编译/最低设置
  • 使用除Appcompat依赖性
  • 之外的其他maven库依赖项

唯一可行的是当我为appcompat使用两个不同的版本时。例如:

armv7Compile 'com.android.support:appcompat-v7:20.0.0'    
armv7Compile project(path: ':lib', configuration: 'armv7Debug')

x86Compile 'com.android.support:appcompat-v7:21.0.0'
x86Compile project(path: ':lib', configuration: 'x86Debug')

当我这样做时,这是之前相同gradle命令的输出:

:app:preBuild SKIPPED
:app:preArmv7DebugBuild SKIPPED
:app:checkArmv7DebugManifest SKIPPED
:app:preArmv7ReleaseBuild SKIPPED
:lib:preBuild SKIPPED
:lib:preArmv7DebugBuild SKIPPED
:lib:checkArmv7DebugManifest SKIPPED
:lib:prepareArmv7DebugDependencies SKIPPED
:lib:compileArmv7DebugAidl SKIPPED
:lib:compileArmv7DebugNdk SKIPPED
:lib:compileLint SKIPPED
:lib:copyArmv7DebugLint SKIPPED
:lib:mergeArmv7DebugShaders SKIPPED
:lib:compileArmv7DebugShaders SKIPPED
:lib:generateArmv7DebugAssets SKIPPED
:lib:mergeArmv7DebugAssets SKIPPED
:lib:mergeArmv7DebugProguardFiles SKIPPED
:lib:packageArmv7DebugRenderscript SKIPPED
:lib:compileArmv7DebugRenderscript SKIPPED
:lib:generateArmv7DebugResValues SKIPPED
:lib:generateArmv7DebugResources SKIPPED
:lib:packageArmv7DebugResources SKIPPED
:lib:processArmv7DebugManifest SKIPPED
:lib:generateArmv7DebugBuildConfig SKIPPED
:lib:processArmv7DebugResources SKIPPED
:lib:generateArmv7DebugSources SKIPPED
:lib:incrementalArmv7DebugJavaCompilationSafeguard SKIPPED
:lib:compileArmv7DebugJavaWithJavac SKIPPED
:lib:processArmv7DebugJavaRes SKIPPED
:lib:transformResourcesWithMergeJavaResForArmv7Debug SKIPPED
:lib:transformClassesAndResourcesWithSyncLibJarsForArmv7Debug SKIPPED
:lib:mergeArmv7DebugJniLibFolders SKIPPED
:lib:transformNative_libsWithMergeJniLibsForArmv7Debug SKIPPED
:lib:transformNative_libsWithSyncJniLibsForArmv7Debug SKIPPED
:lib:bundleArmv7Debug SKIPPED
:app:prepareComAndroidSupportAppcompatV72000Library SKIPPED
:app:prepareComAndroidSupportSupportV42000Library SKIPPED
:app:prepareGradlebugLibUnspecifiedArmv7DebugLibrary SKIPPED
:app:prepareArmv7DebugDependencies SKIPPED
:app:compileArmv7DebugAidl SKIPPED
:app:compileArmv7DebugRenderscript SKIPPED
:app:generateArmv7DebugBuildConfig SKIPPED
:app:generateArmv7DebugResValues SKIPPED
:app:generateArmv7DebugResources SKIPPED
:app:mergeArmv7DebugResources SKIPPED
:app:processArmv7DebugManifest SKIPPED
:app:processArmv7DebugResources SKIPPED
:app:generateArmv7DebugSources SKIPPED
:app:incrementalArmv7DebugJavaCompilationSafeguard SKIPPED
:app:compileArmv7DebugJavaWithJavac SKIPPED
:app:compileArmv7DebugNdk SKIPPED
:app:compileArmv7DebugSources SKIPPED
:app:mergeArmv7DebugShaders SKIPPED
:app:compileArmv7DebugShaders SKIPPED
:app:generateArmv7DebugAssets SKIPPED
:app:mergeArmv7DebugAssets SKIPPED
:app:transformClassesWithDexForArmv7Debug SKIPPED
:app:mergeArmv7DebugJniLibFolders SKIPPED
:app:transformNative_libsWithMergeJniLibsForArmv7Debug SKIPPED
:app:processArmv7DebugJavaRes SKIPPED
:app:transformResourcesWithMergeJavaResForArmv7Debug SKIPPED
:app:validateSigningArmv7Debug SKIPPED
:app:packageArmv7Debug SKIPPED
:app:assembleArmv7Debug SKIPPED
:lib:compileArmv7DebugSources SKIPPED
:lib:assembleArmv7Debug SKIPPED

BUILD SUCCESSFUL

Total time: 1.199 secs

如果没有任何X86构建任务,依赖图会更简单:

enter image description here

所以我的预感是Gradle为每个依赖项准备任务,但是当它看到两个不同风格的相同依赖项(库和版本)时,它会有效地合并任务,它将运行两种风格。

我无法找到关于该错误或已经存在的错误提示的任何文档,并且在打开错误提示之前一步,我想也许有人读到这个会有一个想法,我怎么能覆盖这种行为,或者会指出我的配置出了什么问题。

谢谢!

0 个答案:

没有答案