我想要在gradle中增加一个宏传递给c++,实现打开关闭c++的模块功能。
mk文件中定义宏
LOCAL_CFLAGS、LOCAL_EXPORT_CFLAGS 有区别,注意区分。
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要求比较严格