1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168

build / android / docs / build_config.md [blame]

# Introduction

This document describes the `.build_config.json` files that are used by the
Chromium build system for Android-specific targets like APK, resources,
and more.

[TOC]

# I. Overview of .build_config.json files:

The Android build requires performing computations about dependencies in
various targets, which are not possible with the GN build language. To address
this, `.build_config.json` files are written during the build to store the needed
per-target information as JSON files.

They are always written to `$target_gen_dir/${target_name}.build_config.json`.

Many scripts under [`build/android/gyp/`](build/android_gyp/), which are used
during the build, can also accept parameter arguments using
`@FileArg references`, which look like:

    --some-param=@FileArg(<filename>:<key1>:<key2>:..<keyN>)

This placeholder will ensure that `<filename>` is read as a JSON file, then
return the value at `[key1][key2]...[keyN]` for the `--some-param` option.

Apart from that, the scripts do not need to know anything about the structure
of `.build_config.json` files (but the GN rules that invoke them do and select
which `@FileArg()` references to use).

For a concrete example, consider the following GN fragment:

```gn
# From //ui/android/BUILD.gn:
android_resources("ui_java_resources") {
  custom_package = "org.chromium.ui"
  resource_dirs = [ "java/res" ]
  deps = [
    ":ui_strings_grd",
  ]
}
```

This will end up generating the following JSON file under
`$CHROMIUM_OUTPUT_DIR/gen/ui/android/ui_java_resources.build_config.json`:

```json
{
  "deps_info": {
    "deps_configs": [
      "gen/ui/android/ui_strings_grd.build_config.json"
    ],
    "name": "ui_java_resources.build_config.json",
    "package_name": "org.chromium.ui",
    "path": "gen/ui/android/ui_java_resources.build_config.json",
    "r_text": "gen/ui/android/ui_java_resources_R.txt",
    "resources_dirs": [
      "../../ui/android/java/res"
    ],
    "resources_zip": "resource_zips/ui/android/ui_java_resources.resources.zip",
    "srcjar": "gen/ui/android/ui_java_resources.srcjar",
    "type": "android_resources"
  },
  "gradle": {},
  "resources": {
    "dependency_zips": [
      "resource_zips/ui/android/ui_strings_grd.resources.zip"
    ],
    "extra_package_names": [],
  }
}
```

NOTE: All path values in `.build_config.json` files are relative to your
`$CHROMIUM_OUTPUT_DIR`.

# II. Generation of .build_config.json files:

They are generated by the GN [`write_build_config()`](gn_write_build_config)
internal template, which ends up invoking
[`write_build_config.py`](write_build_config_py). For our example above, this
is with the following parameters:

```
python ../../build/android/gyp/write_build_config.py \
    --type=android_resources \
    --depfile gen/ui/android/ui_java_resources__build_config_crbug_908819.d \
    --deps-configs=\[\"gen/ui/android/ui_strings_grd.build_config.json\"\] \
    --build-config gen/ui/android/ui_java_resources.build_config.json \
    --resources-zip resource_zips/ui/android/ui_java_resources.resources.zip \
    --package-name org.chromium.ui \
    --r-text gen/ui/android/ui_java_resources_R.txt \
    --resource-dirs=\[\"../../ui/android/java/res\"\] \
    --srcjar gen/ui/android/ui_java_resources.srcjar
```

Note that *most* of the content of the JSON file comes from command-line
parameters, but not all of it.

In particular, the `resources['dependency_zips']` entry was computed by
inspecting the content of all dependencies (here, only
`ui_string_grd.build_config.json`), and collecting their
`deps_configs['resources_zip']` values.

Because a target's `.build_config.json` file will always be generated after
that of all of its dependencies,
[`write_build_config.py`](write_build_config_py) can traverse the
whole (transitive) set of direct *and* indirect dependencies for a given target
and extract useful information out of it.

This is the kind of processing that cannot be done at the GN language level,
and is very powerful for Android builds.


# III. Usage of .build_config.json files:

In addition to being parsed by `write_build_config.py`, when they are listed
in the `--deps-configs` of a given target, the `.build_config.json` files are used
by other scripts under [build/android/gyp/] to build stuff.

For example, the GN `android_resources` template uses it to invoke the
[`process_resources.py`] script with the following command, in order to
generate various related files (e.g. `ui_java_resources_R.txt`):

```sh
python ../../build/android/gyp/process_resources.py \
    --depfile gen/ui/android/ui_java_resources_1.d \
    --android-sdk-jar ../../third_party/android_sdk/public/platforms/android-29/android.jar \
    --aapt-path ../../third_party/android_sdk/public/build-tools/29.0.2/aapt \
    --dependencies-res-zips=@FileArg\(gen/ui/android/ui_java_resources.build_config.json:resources:dependency_zips\) \
    --extra-res-packages=@FileArg\(gen/ui/android/ui_java_resources.build_config.json:resources:extra_package_names\) \
    --resource-dirs=\[\"../../ui/android/java/res\"\] \
    --debuggable \
    --resource-zip-out resource_zips/ui/android/ui_java_resources.resources.zip \
    --r-text-out gen/ui/android/ui_java_resources_R.txt \
    --srcjar-out gen/ui/android/ui_java_resources.srcjar \
    --non-constant-id \
    --custom-package org.chromium.ui \
    --shared-resources
```

Note the use of `@FileArg()` references here, to tell the script where to find
the information it needs.


# IV. Format of .build_config.json files:

Thanks to `@FileArg()` references, Python build scripts under
[`build/android/gyp/`](build/android/gyp/)  do not need to know anything
about the internal format of `.build_config.json` files.

This format is decided between internal GN build rules and
[`write_build_config.py`][write_build_config_py]. Since these changes rather
often, the format documentation is kept inside the Python script itself, but
can be extracted as a Markdown file and visualized with the following commands:

```sh
# Extract .build_config.json format documentation
build/android/gyp/write_build_config.py \
  --generate-markdown-format-doc > /tmp/format.md

# Launch a browser to visualize the format documentation.
python tools/md_browser/md_browser.py -d /tmp /tmp/format.md
```

[build/android/gyp/]: https://chromium.googlesource.com/chromium/src/build/+/main/android/gyp/
[gn_write_build_config]: https://cs.chromium.org/chromium/src/build/config/android/internal_rules.gni?q=write_build_config&sq=package:chromium
[write_build_config_py]: https://chromium.googlesource.com/chromium/src/build/+/main/android/gyp/write_build_config.py