【问题标题】:How to set variable according to gradle flavors如何根据gradle风味设置变量
【发布时间】:2016-07-02 09:55:17
【问题描述】:

我想将一个变量 test 传递给 NDK,我为每个风格设置了不同的变量作为对 NDK 的定义。但由于某种原因,他总是通过最后一种味道的价值。

这是 build.gradle:

apply plugin: 'com.android.library'

def test

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"
    defaultPublishConfig "flavorARelease"
    publishNonDefault true

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 17

        ndk {
            moduleName "test"
            ldLibs "log"
        }
    }

    productFlavors {    
        flavorA {
            test = 1
        }

        flavorB {
            test = 2
        }    
    }

    buildTypes {    
        debug {
            ndk {
                if (cFlags == null) { cFlags = "" }
                cFlags = cFlags + " -DLOGGING=1 -DTEST="+test+" "
            }
            minifyEnabled false
        }
        release {
            ndk {
                if (cFlags == null) { cFlags = "" }
                cFlags = cFlags + " -DLOGGING=0 -DTEST="+test+" "
            }
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
}

这里是生成的 Android.mk 中的 CFLAG 行

构建/中间体/ndk/flavorA/debug/Android.mk:

LOCAL_CFLAGS :=  -DLOGGING=1 -DTEST=2

我期待-DTEST=1在这里

build/intermediates/ndk/flavorB/debug/Android.mk:

LOCAL_CFLAGS :=  -DLOGGING=1 -DTEST=2

那么我的错误在哪里?或者我怎样才能实现我的目标?另请考虑真正的问题更复杂,如果可能,我想在“buildTypes”部分中进行这些定义。

【问题讨论】:

    标签: android gradle android-ndk cflags


    【解决方案1】:

    您可以使用buildConfigField

    productFlavors {
        demo {
            buildConfigField "int", "FOO", "1"
            buildConfigField "String", "FOO_STRING", "\"foo1\""
        }
        full {
            buildConfigField "int", "FOO", "2"
            buildConfigField "String", "FOO_STRING", "\"foo2\""
        }
    }
    

    【讨论】:

    • 你将如何在#ifdef 中从 C 中访问它?这仅适用于 Java AFAIK。
    • 如何在 Java 中使用它?
    • @sean 在 Java 中就像 BuildConfig.FOOBuildConfig.FOO_STRING 一样调用。
    • 你如何为每个风格和每个 buildType 制作不同的 buildConfigField ?
    【解决方案2】:

    我找到了解决办法:

    首先代替def test为所有productFlavors指定一个新字段

    productFlavors.all {
        ext.dTest = null
    }
    

    然后在每个风味中设置这个字段(代码不变)

    productFlavors {    
        flavorA {
            dTest = 1
        }
    
        flavorB {
            dTest = 2
        }    
    }
    

    最后你可以在 buildTypes 中做到这一点

    buildTypes {    
        all {
             productFlavors {
                all {
                    ndk {
                        if (cFlags == null) { cFlags = "" }
                        cFlags = cFlags + " -DTEST="+dTest+" "
                    }
                }
            }
        }
        debug {           
            minifyEnabled false
            ndk {
                if (cFlags == null) { cFlags = "" }
                cFlags = cFlags + " -DLOGGING=1 "
            }
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    
            ndk {
                if (cFlags == null) { cFlags = "" }
                cFlags = cFlags + " -DLOGGING=0 "
            }
        }
    }
    

    这里是完整文件:

    apply plugin: 'com.android.library'
    
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.2"
        defaultPublishConfig "flavorARelease"
        publishNonDefault true
    
        defaultConfig {
            minSdkVersion 15
            targetSdkVersion 17
    
            ndk {
                moduleName "dTest"
                ldLibs "log"
            }
        }
    
        productFlavors.all {
            ext.dTest = null
        }
    
        productFlavors {    
            flavorA {
                dTest = 1
            }
    
            flavorB {
                dTest = 2
            }    
        }
    
    
        buildTypes {    
            all {
                productFlavors {
                    all {
                        ndk {
                            if (cFlags == null) { cFlags = "" }
                            cFlags = cFlags + " -DTEST="+dTest+" "
                        }
                    }
                }
            }
            debug {           
                minifyEnabled false
                ndk {
                    if (cFlags == null) { cFlags = "" }
                    cFlags = cFlags + " -DLOGGING=1 "
                }
            }
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    
                ndk {
                    if (cFlags == null) { cFlags = "" }
                    cFlags = cFlags + " -DLOGGING=0 "
                }
            }
        }
    
    }
    

    【讨论】:

    • 测试扩展了 ConventionTask。因此,您的 productFlavors 不会构建,因为您使用保留关键字作为变量。
    • 不确定您指的是问题还是解决方案。在我的真实项目中,它不是test,而是一组不同的变量。如果这个例子因为使用test 而被破坏,你能修复它吗?自从我在这个问题上苦苦挣扎后,我真的又对 gradle 生锈了。 - 将所有出现的test 更改为dTest 已经成功了吗?
    • 我指的是 productFlavors,您在其中声明 Test。我继续并重命名了变量。谢谢!
    • @Torge 这里的变量 cFlags 是什么?
    • 我也需要分别在debug和release中直接实现没有ndk和dtest的同样的事情
    猜你喜欢
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多