[√]build.gradle,mk,c++预处理宏联动关系

简介: [√]build.gradle,mk,c++预处理宏联动关系

我想要在gradle中增加一个宏传递给c++,实现打开关闭c++的模块功能。

mk文件中定义宏

LOCAL_CFLAGS、LOCAL_EXPORT_CFLAGS 有区别,注意区分。

image.png

LOCAL_EXPORT_CFLAGS 是一个变量,用于在 Android 的构建系统中指定要导出的 C/C++ 标志。当一个模块(module)使用该变量设置了一些标志后,这些标志会被传递给依赖于该模块的其他模块。

在 Android 的构建系统中,每个模块都被视为一个相对独立的单元,模块之间可以相互依赖。这些模块可以是应用程序、库或模块化组件等。当一个模块依赖于另一个模块时,它需要知道被依赖模块的编译标志,以便正确地进行编译和链接。

通过使用 LOCAL_EXPORT_CFLAGS 变量,你可以将一些特定的 C/C++ 编译标志从当前模块导出,使其可用于依赖于当前模块的其他模块。

例如,在一个库模块的 Android.mk 文件中,你可以这样设置 LOCAL_EXPORT_CFLAGS 变量:

LOCAL_EXPORT_CFLAGS := -DDEBUG_MODE -I$(LOCAL_PATH)/include
LOCAL_CFLAGS += -DUSE_LEAK_TRACER=$(USE_LEAK_TRACER) # USE_LEAK_TRACER来自gradle

-DDEBUG_MODE 标志和 -I$(LOCAL_PATH)/include 标志导出到其他依赖于该库模块的模块中。这些标志可以用来启用调试模式,并指定包含文件的搜索路径。

当其他模块(如应用程序或其他库)依赖于这个库模块时,它们可以自动继承 LOCAL_EXPORT_CFLAGS 变量中的这些标志。这样,它们就可以使用这些标志来进行编译和链接。

-D 是一个编译器选项,用于定义预处理器宏(Preprocessor Macro)。

gradle中配置开关

在build.gradle中定义预处理宏

android{
    buildTypes{
        debug{
            buildConfigField("int", "USE_LEAKTRACE", "1") # 这个是给java使用的
            externalNativeBuild {
                ndkBuild {
                    arguments 'NDK_DEBUG=1', 'USE_LEAK_TRACER=1' # CPP发现在这里有效
                }
            }
        }
    }
}

如果报错Could not find method buildConfigField() for arguments [USE_LEAKTRACE] on BuildType_Decorated...,是因为buildConfigFiled参数填错导致的

每次构建过程中都会自动生成 BuildConfig.java 文件(位于 build/generated/source/buildConfig/{buildType}/{flavor} 目录下),其中包含了您在 build.gradle 文件中使用 buildConfigField 定义的字段。

使用反射获取正确的BuildConfigConfig

String buildConfigName = getPackageName() + ".BuildConfig";
try {
    Class<BuildConfig> buildConfigClass = (Class<BuildConfig>) Class.forName(buildConfigName);
    // 获取到gradle中配置的字段值
    Field field = buildConfigClass.getField("USE_LEAK_TRACER");
    int useLeakTracer = field.getInt(null);
    if (useLeakTracer > 0) {
        Log.d("initLeakTracer", "use leak tracer");
        LeakNotify.getInstance().show(this);
    }
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (NoSuchFieldException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
}

gradle中变量直接+即可

/**
 * Adds a new field to the generated BuildConfig class.
 *
 * <p>The field is generated as: {@code <type> <name> = <value>;}
 *
 * <p>This means each of these must have valid Java content. If the type is a String, then the
 * value should include quotes.
 *
 * @param type the type of the field
 * @param name the name of the field
 * @param value the value of the field
 */
public void buildConfigField(
        @NonNull String type,
        @NonNull String name,
        @NonNull String value) {
    ClassField alreadyPresent = getBuildConfigFields().get(name);
    if (alreadyPresent != null) {
        String message =
                String.format(
                        "BuildType(%s): buildConfigField '%s' value is being replaced: %s -> %s",
                        getName(), name, alreadyPresent.getValue(), value);
        errorReporter.handleSyncWarning(null, SyncIssue.TYPE_GENERIC, message);
    }
    addBuildConfigField(new ClassFieldImpl(type, name, value));
}

在mk文件中使用info打印log

$(info "log") # 注意空格问题,mk要求比较严格
目录
相关文章
|
7月前
|
编译器 Linux C++
【C++ 跨平台开发 】掌握 C++ 跨平台关键宏的使用
【C++ 跨平台开发 】掌握 C++ 跨平台关键宏的使用
161 3
|
7月前
|
存储 缓存 安全
【cmake 生成配置文件】CMake与现代C++:配置文件宏的深度探索与应用
【cmake 生成配置文件】CMake与现代C++:配置文件宏的深度探索与应用
280 0
|
7月前
|
编译器 程序员 Linux
C++系列九:预处理功能
C++系列九:预处理功能
|
7月前
|
安全 编译器 C语言
【C++ 编译器 版本支持】深度解读C++ 版本以及编译器版本相关宏
【C++ 编译器 版本支持】深度解读C++ 版本以及编译器版本相关宏
143 0
|
7月前
|
编译器 C语言 C++
深入探索C/C++预处理世界:预定义符号与宏定义的全方位指南
深入探索C/C++预处理世界:预定义符号与宏定义的全方位指南
162 0
|
7月前
|
机器学习/深度学习 人工智能 编解码
极智AI | 教你用C++实现一般模型推理图片预处理模块
大家好,我是极智视界,本文介绍了用 C++ 实现一般模型推理图片预处理的方法,通用性较强。
247 0
|
C++
C++宏 #与##的区别
C++宏 #与##的区别
61 0
|
JSON C语言 数据格式
【C/C++】防止不必要的局部宏替换
如何避免和防止宏定义在不必要的位置进行替换
246 0
|
编译器 C语言 C++
C/C++,不废话的宏使用技巧
C/C++,不废话的宏使用技巧
184 0