BuildRule
that can generate a
BuildConfig.java
file and compile it so it can be
used as a Java library.
This rule functions as a java_library
that can be used as a dependency of an android_library
, but whose implementation may be swapped out by the android_binary
that
transitively includes the android_build_config
. Specifically, its compile-time
implementation will use non-constant-expression (see JLS 15.28), placeholder values (because they
cannot be inlined) for the purposes of compilation that will be swapped out with final,
production values (that can be inlined) when building the final APK. Consider the following
example:
android_build_config(
name = 'build_config',
package = 'com.example.pkg',
)
# The .java files in this library may contain references to the boolean
# com.example.pkg.BuildConfig.DEBUG because :build_config is in the deps.
android_library(
name = 'mylib',
srcs = glob(['src/**/*.java']),
deps = [
':build_config',
],
)
android_binary(
name = 'debug',
package_type = 'DEBUG',
keystore = '//keystores:debug',
manifest = 'AndroidManifest.xml',
target = 'Google Inc.:Google APIs:19',
deps = [
':mylib',
],
)
android_binary(
name = 'release',
package_type = 'RELEASE',
keystore = '//keystores:release',
manifest = 'AndroidManifest.xml',
target = 'Google Inc.:Google APIs:19',
deps = [
':mylib',
],
)
The
:mylib
rule will be compiled against a version of
BuildConfig.java
whose
contents are:
package com.example.pkg;
public class BuildConfig {
private BuildConfig() {}
public static final boolean DEBUG = !Boolean.parseBoolean(null);
}
Note that the value is not a constant expression, so it cannot be inlined by
javac
. When
building
:debug
and
:release
, the
BuildConfig.class
file that
:mylib
was compiled against will not be included in the APK as the other transitive Java deps of
the
android_binary
will. The
BuildConfig.class
will be replaced with one that
corresponds to the value of the
package_type
argument to the
android_binary
rule.
For example,
:debug
will include a
BuildConfig.class
file that is compiled from:
package com.example.pkg;
public class BuildConfig {
private BuildConfig() {}
public static final boolean DEBUG = true;
}
whereas
:release
will include a
BuildConfig.class
file that is compiled from:
package com.example.pkg;
public class BuildConfig {
private BuildConfig() {}
public static final boolean DEBUG = false;
}
This swap happens before ProGuard is run as part of building the APK, so it will be able to
exploit the "final-ness" of the
DEBUG
constant in any whole-program optimization that it
performs.