我想要在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要求比较严格