【问题标题】:Set Android.mk flag through Gradle depending on build type根据构建类型通过 Gradle 设置 Android.mk 标志
【发布时间】:2017-05-20 10:49:08
【问题描述】:

我需要在 Android.mk 文件中设置一个标志,告诉 C 代码它是否处于调试模式。

LOCAL_MODULE := auth
LOCAL_SRC_FILES := auth.c
LOCAL_CFLAGS := -DDEBUG_MODE=0
LOCAL_EXPORT_CFLAGS := $(LOCAL_CFLAGS)
LOCAL_LDLIBS := -llog
LOCAL_C_INCLUDES := auth.h

include $(BUILD_SHARED_LIBRARY)

问题是我在构建版本时经常忘记更改值,反之亦然,所以我期待一种自动完成的方法。

我尝试将Android.mk 更改为:

LOCAL_CFLAGS := -DDEBUG_MODE

并将build.gradle 更改为以下内容:

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 25
    }

    buildTypes {
        release {
            debuggable false
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            ndk {
                cFlags = " -DDEBUG_MODE=0 "
            }
        }
        debug {
            debuggable true
            minifyEnabled false
            shrinkResources false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            ndk {
                cFlags = " -DDEBUG_MODE=1 "
            }
        }
    }

    sourceSets.main {
        jni.srcDirs = ['src/main/none']
        jniLibs.srcDirs = ["src/main/libs"]
    }

    externalNativeBuild {
        ndkBuild {
            path 'src/main/jni/Android.mk'
        }
    }
    return void
}

这还不够,标志不会根据构建类型而改变。我发现很少有这方面的信息,上面的代码是我在互联网上阅读的结果。 您对如何使其正常工作有什么建议吗?

【问题讨论】:

    标签: android android-ndk android-gradle-plugin build.gradle


    【解决方案1】:

    在构建类型中使用externalNativeBuild { ndkBuild {。请注意,标志将添加到APP_CFLAGS(即所有模块),而不是LOCAL_CFLAGS

    build.gradle:

    android {
        compileSdkVersion 25
        buildToolsVersion "25.0.2"
        defaultConfig {
            applicationId "com.example.ndkbuildtest"
            minSdkVersion 21
            targetSdkVersion 25
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
            externalNativeBuild {
                ndkBuild {
                    abiFilters "armeabi-v7a"
                    arguments "APP_STL:=gnustl_static"
                    cppFlags "-std=c++11","-frtti","-fexceptions"
                }
            }
        }
        buildTypes {
            release {
                externalNativeBuild {
                    ndkBuild {
                        cFlags "-DDEBUG_MODE=0"
                    }
                }
            }
            debug {
                externalNativeBuild {
                    ndkBuild {
                        cFlags "-DDEBUG_MODE=1"
                    }
                }
            }
        }
        externalNativeBuild {
            ndkBuild {
                path "Android.mk"
            }
        }
    }
    

    Android.mk:

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := native-lib
    LOCAL_SRC_FILES := src/main/cpp/native-lib.cpp
    include $(BUILD_SHARED_LIBRARY)
    

    native-lib.cpp:

    #include <jni.h>
    #include <string>
    
    #if DEBUG_MODE
    #error "Debug mode enabled!
    #endif
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ndkbuildtest_MainActivity_stringFromJNI(
            JNIEnv *env,
            jobject /* this */) {
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    

    【讨论】:

    • 标志值仍始终为 0(未设置)。但是,我在 gradle 重新同步或更改构建类型时都看不到任何 ndk 构建过程
    • 您在哪里以及如何测试标志的值?请注意,测试LOCAL_CFLAGS 将不起作用,因为标志正在添加到APP_CFLAGS。不过,检查 C 代码中的标志对我来说效果很好(我使用的是 gradle 插件的 2.3.1 版)。
    • 我从 mk 文件中删除了 LOCAL_CFLAGS := -DDEBUG_MODE=0 并使用 # if DEBUG_MODE (gradle 2.3.2) 在 C 代码中进行测试
    • 您的 Application.mk 或 Android.mk 中是否有 APP_FLAGS :=?我添加了一个更完整的示例,适用于 2.3.2(如果我 gradlew assembleDebug #error 触发,如果我 gradlew assembleRelease 没有触发)。
    • 我让它工作了。问题是 gradle sourceSets 属性,它使项目使用旧的本机预编译库(我通常通过终端编译的库)进行编译。删除 gradle 属性已解决。
    【解决方案2】:

    您可以在 Application.mk 文件中执行此操作,只需这几行。

    ## DEBUG MODE
    APP_ABI := armeabi-v7a  #Add your target ABI's or change, it's up to you.
    APP_CFLAGS += -UNDEBUG -O0 -g -ggdb 
    APP_OPTIM := debug
    APP_CPPFLAGS += -DDMZ_DEBUG=1
    

    【讨论】:

    • 请解释代码的实际作用,否则不清楚如何将其与其余代码集成
    • 发布模式是默认的,并生成高度优化的二进制文件。调试模式生成更容易调试的未优化二进制文件。当您添加 APP_OPTIM := 调试行时,它会生成可调试的源代码,并运行所有调试行。阅读 APP_OPTIM 部分:developer.android.com/ndk/guides/application_mk.html
    • 这并不能解决问题,我每次在发布或调试中构建 Android 项目时仍然需要更改 APP_OPTIM 值。我需要一种将 Android 项目构建类型反映到 mk 文件中的方法,唯一的方法是通过 gradle(也许使用任务?)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-18
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多