Skip to main content

android_build_config

name

def name(
*,
name: str,
default_target_platform: None | str = ...,
target_compatible_with: list[str] = ...,
compatible_with: list[str] = ...,
exec_compatible_with: list[str] = ...,
visibility: list[str] = ...,
within_view: list[str] = ...,
metadata: OpaqueMetadata = ...,
tests: list[str] = ...,
modifiers: OpaqueMetadata = ...,
_android_toolchain: str = ...,
_apple_platforms: dict[str, str] = ...,
_build_only_native_code: bool = ...,
_is_building_android_binary: bool = ...,
_java_toolchain: str = ...,
contacts: list[str] = ...,
default_host_platform: None | str = ...,
labels: list[str] = ...,
licenses: list[str] = ...,
package: str = ...,
values: list[str] = ...,
values_file: None | str = ...,
) -> None

An android_build_config() rule is used to generate a BuildConfig class with global configuration variables that other android_library() rules can compile against. Currently, the only variable exposed by BuildConfig is a global boolean named DEBUG, much like the BuildConfig.java generated by the official Android build tools based on Gradle.

Parameters

  • name: name of the target

  • default_target_platform: specifies the default target platform, used when no platforms are specified on the command line

  • target_compatible_with: a list of constraints that are required to be satisfied for this target to be compatible with a configuration

  • compatible_with: a list of constraints that are required to be satisfied for this target to be compatible with a configuration

  • exec_compatible_with: a list of constraints that are required to be satisfied for this target to be compatible with an execution platform

  • visibility: a list of visibility patterns restricting what targets can depend on this one

  • within_view: a list of visibility patterns restricting what this target can depend on

  • metadata: a key-value map of metadata associated with this target

  • tests: a list of targets that provide tests for this one

  • modifiers: an array of modifiers associated with this target

  • package: Name of the Java package to use in the generated BuildConfig.java file. Most developers set this to the application id declared in the manifest via <manifest package="APP_ID">. Example: com.facebook.orca.

  • values: List of strings that defines additional fields (and values) that should be declared in the generated BuildConfig.java file. Like DEBUG, the values will be non-constant-expressions that evaluate to the value specified in the file at compilation time. To override the values in an APK, specify build_config_values or build_config_values_file in android_binary().

  • values_file: Optional path to a file that defines additional fields (and values) that should be declared in the generated BuildConfig.java file. Like DEBUG, the values will be non-constant-expressions that evaluate to the value specified in the file at compilation time. To override the values in an APK, specify build_config_values or build_config_values_file in android_binary().

    Note that values_file can be a generated file, as can build_config_values_file as demonstrated in the example below.

Details

The fields in the generated BuildConfig class will be non-constant-expressions (see JLS 15.28). However, if BuildConfig is packaged into an APK, it will be replaced with a new version where:

  • The fields will be set to literal values (i.e., constant expressions).
  • The boolean BuildConfig.DEBUG field will correspond to that of the package_type argument to the android_binary() rule that is packaging it.

This transformation is done before ProGuard is applied (if applicable), so that it can propagate constants from BuildConfig and eliminate dead code.

Examples:

Here is an example of an android_build_config() rule that is transitively included by both debug and release versions of an android_binary() rule. The value of com.example.pkg.BuildConfig.DEBUG will be different in each APK even though they both transitively depend on the same :build_config rule.


android_build_config(
name = 'build_config',
package = 'com.example.pkg',
values = [
'String COMMIT_ID = "0000000000000000000000000000000000000000"',
],
)

# The .java files in this library may contain references to the boolean
# com.example.pkg.BuildConfig.DEBUG because :build_config is in the deps.
# It could also reference BuildConfig.COMMIT_ID.
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',
],
)

# The contents of the file generated by this rule might be:
#
# String COMMIT_ID = "7bf804bdf71fdbfc99cce3b155b3643f022c6fa4"
#
# Note that the output of :build_config_release_values will be cached by Buck.
# Assuming that generate_release_build_config.py depends on state that is not
# expressed by its deps (which violates a fundamental invariant in Buck!), a
# workaround is to ensure that the inputs to :build_config_release_values are
# changed in some way before :release is built to ensure that the output from
# :build_config_release_values is not pulled from cache. For example:
#
# $ buck build :release
# $ uuidgen > dummy_state_file.txt
# $ buck build :release
#
# This makes sure that generate_release_build_config.py is re-run before
# :release is rebuilt. This is much cheaper than deleting your build cache
# before rebuilding.
genrule(
name = 'build_config_release_values',
srcs = [ 'generate_release_build_config.py', 'dummy_state_file.txt' ],
bash = 'generate_release_build_config.py $OUT',
out = 'build_config_release_values.txt',
)

android_binary(
name = 'release',
package_type = 'RELEASE',
keystore = '//keystores:release',
manifest = 'AndroidManifest.xml',
target = 'Google Inc.:Google APIs:19',
build_config_values_file = ':build_config_release_values',
deps = [
':mylib',
],
)