| Colin Cross | e10ce18 | 2016-07-18 10:58:47 -0700 | [diff] [blame] | 1 | # Soong |
| 2 | |
| 3 | Soong is the replacement for the old Android make-based build system. It |
| 4 | replaces Android.mk files with Android.bp files, which are JSON-like simple |
| 5 | declarative descriptions of modules to build. |
| 6 | |
| Clay Murphy | 021e376 | 2019-01-08 10:55:51 -0800 | [diff] [blame] | 7 | See [Simple Build |
| 8 | Configuration](https://source.android.com/compatibility/tests/development/blueprints) |
| 9 | on source.android.com to read how Soong is configured for testing. |
| 10 | |
| Colin Cross | e10ce18 | 2016-07-18 10:58:47 -0700 | [diff] [blame] | 11 | ## Android.bp file format |
| 12 | |
| 13 | By design, Android.bp files are very simple. There are no conditionals or |
| 14 | control flow statements - any complexity is handled in build logic written in |
| Colin Cross | 068e0fe | 2016-12-13 15:23:47 -0800 | [diff] [blame] | 15 | Go. The syntax and semantics of Android.bp files are intentionally similar |
| 16 | to [Bazel BUILD files](https://www.bazel.io/versions/master/docs/be/overview.html) |
| 17 | when possible. |
| Colin Cross | e10ce18 | 2016-07-18 10:58:47 -0700 | [diff] [blame] | 18 | |
| 19 | ### Modules |
| 20 | |
| 21 | A module in an Android.bp file starts with a module type, followed by a set of |
| 22 | properties in `name: value,` format: |
| 23 | |
| 24 | ``` |
| 25 | cc_binary { |
| 26 | name: "gzip", |
| 27 | srcs: ["src/test/minigzip.c"], |
| 28 | shared_libs: ["libz"], |
| 29 | stl: "none", |
| 30 | } |
| 31 | ``` |
| 32 | |
| 33 | Every module must have a `name` property, and the value must be unique across |
| 34 | all Android.bp files. |
| 35 | |
| 36 | For a list of valid module types and their properties see |
| Dan Willemsen | b2fbbbb | 2019-03-01 13:13:20 -0800 | [diff] [blame] | 37 | [$OUT_DIR/soong/docs/soong_build.html](https://ci.android.com/builds/latest/branches/aosp-build-tools/targets/linux/view/soong_build.html). |
| Colin Cross | e10ce18 | 2016-07-18 10:58:47 -0700 | [diff] [blame] | 38 | |
| Colin Cross | 645332d | 2018-04-25 15:06:01 -0700 | [diff] [blame] | 39 | ### Globs |
| 40 | |
| 41 | Properties that take a list of files can also take glob patterns. Glob |
| 42 | patterns can contain the normal Unix wildcard `*`, for example "*.java". Glob |
| 43 | patterns can also contain a single `**` wildcard as a path element, which will |
| 44 | match zero or more path elements. For example, `java/**/*.java` will match |
| 45 | `java/Main.java` and `java/com/android/Main.java`. |
| 46 | |
| Colin Cross | e10ce18 | 2016-07-18 10:58:47 -0700 | [diff] [blame] | 47 | ### Variables |
| 48 | |
| 49 | An Android.bp file may contain top-level variable assignments: |
| 50 | ``` |
| 51 | gzip_srcs = ["src/test/minigzip.c"], |
| 52 | |
| 53 | cc_binary { |
| 54 | name: "gzip", |
| 55 | srcs: gzip_srcs, |
| 56 | shared_libs: ["libz"], |
| 57 | stl: "none", |
| 58 | } |
| 59 | ``` |
| 60 | |
| 61 | Variables are scoped to the remainder of the file they are declared in, as well |
| 62 | as any child blueprint files. Variables are immutable with one exception - they |
| 63 | can be appended to with a += assignment, but only before they have been |
| 64 | referenced. |
| 65 | |
| 66 | ### Comments |
| 67 | Android.bp files can contain C-style multiline `/* */` and C++ style single-line |
| 68 | `//` comments. |
| 69 | |
| 70 | ### Types |
| 71 | |
| 72 | Variables and properties are strongly typed, variables dynamically based on the |
| 73 | first assignment, and properties statically by the module type. The supported |
| 74 | types are: |
| 75 | * Bool (`true` or `false`) |
| Nan Zhang | 61eaedb | 2017-11-02 13:28:15 -0700 | [diff] [blame] | 76 | * Integers (`int`) |
| Colin Cross | e10ce18 | 2016-07-18 10:58:47 -0700 | [diff] [blame] | 77 | * Strings (`"string"`) |
| 78 | * Lists of strings (`["string1", "string2"]`) |
| 79 | * Maps (`{key1: "value1", key2: ["value2"]}`) |
| 80 | |
| 81 | Maps may values of any type, including nested maps. Lists and maps may have |
| 82 | trailing commas after the last value. |
| 83 | |
| 84 | ### Operators |
| 85 | |
| 86 | Strings, lists of strings, and maps can be appended using the `+` operator. |
| Nan Zhang | 61eaedb | 2017-11-02 13:28:15 -0700 | [diff] [blame] | 87 | Integers can be summed up using the `+` operator. Appending a map produces the |
| 88 | union of keys in both maps, appending the values of any keys that are present |
| 89 | in both maps. |
| Colin Cross | e10ce18 | 2016-07-18 10:58:47 -0700 | [diff] [blame] | 90 | |
| 91 | ### Defaults modules |
| 92 | |
| 93 | A defaults module can be used to repeat the same properties in multiple modules. |
| 94 | For example: |
| 95 | |
| 96 | ``` |
| 97 | cc_defaults { |
| 98 | name: "gzip_defaults", |
| 99 | shared_libs: ["libz"], |
| 100 | stl: "none", |
| 101 | } |
| 102 | |
| 103 | cc_binary { |
| 104 | name: "gzip", |
| 105 | defaults: ["gzip_defaults"], |
| 106 | srcs: ["src/test/minigzip.c"], |
| 107 | } |
| 108 | ``` |
| 109 | |
| Paul Duffin | 2e61fa6 | 2019-03-28 14:10:57 +0000 | [diff] [blame] | 110 | ### Packages |
| 111 | |
| 112 | The build is organized into packages where each package is a collection of related files and a |
| 113 | specification of the dependencies among them in the form of modules. |
| 114 | |
| 115 | A package is defined as a directory containing a file named `Android.bp`, residing beneath the |
| 116 | top-level directory in the build and its name is its path relative to the top-level directory. A |
| 117 | package includes all files in its directory, plus all subdirectories beneath it, except those which |
| 118 | themselves contain an `Android.bp` file. |
| 119 | |
| 120 | The modules in a package's `Android.bp` and included files are part of the module. |
| 121 | |
| 122 | For example, in the following directory tree (where `.../android/` is the top-level Android |
| 123 | directory) there are two packages, `my/app`, and the subpackage `my/app/tests`. Note that |
| 124 | `my/app/data` is not a package, but a directory belonging to package `my/app`. |
| 125 | |
| 126 | .../android/my/app/Android.bp |
| 127 | .../android/my/app/app.cc |
| 128 | .../android/my/app/data/input.txt |
| 129 | .../android/my/app/tests/Android.bp |
| 130 | .../android/my/app/tests/test.cc |
| 131 | |
| 132 | This is based on the Bazel package concept. |
| 133 | |
| Jeff Gaston | 44c0cd8 | 2017-11-29 19:51:52 -0800 | [diff] [blame] | 134 | ### Name resolution |
| 135 | |
| 136 | Soong provides the ability for modules in different directories to specify |
| 137 | the same name, as long as each module is declared within a separate namespace. |
| 138 | A namespace can be declared like this: |
| 139 | |
| 140 | ``` |
| 141 | soong_namespace { |
| 142 | imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"], |
| 143 | } |
| 144 | ``` |
| 145 | |
| 146 | Each Soong module is assigned a namespace based on its location in the tree. |
| 147 | Each Soong module is considered to be in the namespace defined by the |
| 148 | soong_namespace found in an Android.bp in the current directory or closest |
| 149 | ancestor directory, unless no such soong_namespace module is found, in which |
| 150 | case the module is considered to be in the implicit root namespace. |
| 151 | |
| 152 | When Soong attempts to resolve dependency D declared my module M in namespace |
| 153 | N which imports namespaces I1, I2, I3..., then if D is a fully-qualified name |
| 154 | of the form "//namespace:module", only the specified namespace will be searched |
| 155 | for the specified module name. Otherwise, Soong will first look for a module |
| 156 | named D declared in namespace N. If that module does not exist, Soong will look |
| 157 | for a module named D in namespaces I1, I2, I3... Lastly, Soong will look in the |
| 158 | root namespace. |
| 159 | |
| 160 | Until we have fully converted from Make to Soong, it will be necessary for the |
| 161 | Make product config to specify a value of PRODUCT_SOONG_NAMESPACES. Its value |
| 162 | should be a space-separated list of namespaces that Soong export to Make to be |
| 163 | built by the `m` command. After we have fully converted from Make to Soong, the |
| 164 | details of enabling namespaces could potentially change. |
| 165 | |
| Paul Duffin | 2e61fa6 | 2019-03-28 14:10:57 +0000 | [diff] [blame] | 166 | ### Visibility |
| 167 | |
| 168 | The `visibility` property on a module controls whether the module can be |
| 169 | used by other packages. Modules are always visible to other modules declared |
| 170 | in the same package. This is based on the Bazel visibility mechanism. |
| 171 | |
| 172 | If specified the `visibility` property must contain at least one rule. |
| 173 | |
| 174 | Each rule in the property must be in one of the following forms: |
| 175 | * `["//visibility:public"]`: Anyone can use this module. |
| 176 | * `["//visibility:private"]`: Only rules in the module's package (not its |
| 177 | subpackages) can use this module. |
| 178 | * `["//some/package:__pkg__", "//other/package:__pkg__"]`: Only modules in |
| 179 | `some/package` and `other/package` (defined in `some/package/*.bp` and |
| 180 | `other/package/*.bp`) have access to this module. Note that sub-packages do not |
| 181 | have access to the rule; for example, `//some/package/foo:bar` or |
| 182 | `//other/package/testing:bla` wouldn't have access. `__pkg__` is a special |
| 183 | module and must be used verbatim. It represents all of the modules in the |
| 184 | package. |
| 185 | * `["//project:__subpackages__", "//other:__subpackages__"]`: Only modules in |
| 186 | packages `project` or `other` or in one of their sub-packages have access to |
| 187 | this module. For example, `//project:rule`, `//project/library:lib` or |
| 188 | `//other/testing/internal:munge` are allowed to depend on this rule (but not |
| 189 | `//independent:evil`) |
| 190 | * `["//project"]`: This is shorthand for `["//project:__pkg__"]` |
| 191 | * `[":__subpackages__"]`: This is shorthand for `["//project:__subpackages__"]` |
| 192 | where `//project` is the module's package. e.g. using `[":__subpackages__"]` in |
| 193 | `packages/apps/Settings/Android.bp` is equivalent to |
| 194 | `//packages/apps/Settings:__subpackages__`. |
| 195 | * `["//visibility:legacy_public"]`: The default visibility, behaves as |
| 196 | `//visibility:public` for now. It is an error if it is used in a module. |
| 197 | |
| 198 | The visibility rules of `//visibility:public` and `//visibility:private` can |
| 199 | not be combined with any other visibility specifications. |
| 200 | |
| 201 | Packages outside `vendor/` cannot make themselves visible to specific packages |
| 202 | in `vendor/`, e.g. a module in `libcore` cannot declare that it is visible to |
| 203 | say `vendor/google`, instead it must make itself visible to all packages within |
| 204 | `vendor/` using `//vendor:__subpackages__`. |
| 205 | |
| 206 | If a module does not specify the `visibility` property the module is |
| 207 | `//visibility:legacy_public`. Once the build has been completely switched over to |
| 208 | soong it is possible that a global refactoring will be done to change this to |
| 209 | `//visibility:private` at which point all modules that do not currently specify |
| 210 | a `visibility` property will be updated to have |
| 211 | `visibility = [//visibility:legacy_public]` added. It will then be the owner's |
| 212 | responsibility to replace that with a more appropriate visibility. |
| 213 | |
| Colin Cross | e10ce18 | 2016-07-18 10:58:47 -0700 | [diff] [blame] | 214 | ### Formatter |
| 215 | |
| 216 | Soong includes a canonical formatter for blueprint files, similar to |
| 217 | [gofmt](https://golang.org/cmd/gofmt/). To recursively reformat all Android.bp files |
| 218 | in the current directory: |
| 219 | ``` |
| 220 | bpfmt -w . |
| 221 | ``` |
| 222 | |
| 223 | The canonical format includes 4 space indents, newlines after every element of a |
| 224 | multi-element list, and always includes a trailing comma in lists and maps. |
| 225 | |
| 226 | ### Convert Android.mk files |
| 227 | |
| 228 | Soong includes a tool perform a first pass at converting Android.mk files |
| 229 | to Android.bp files: |
| 230 | |
| 231 | ``` |
| 232 | androidmk Android.mk > Android.bp |
| 233 | ``` |
| 234 | |
| 235 | The tool converts variables, modules, comments, and some conditionals, but any |
| Colin Cross | 024c32e | 2016-09-26 15:42:42 -0700 | [diff] [blame] | 236 | custom Makefile rules, complex conditionals or extra includes must be converted |
| 237 | by hand. |
| 238 | |
| 239 | #### Differences between Android.mk and Android.bp |
| 240 | |
| 241 | * Android.mk files often have multiple modules with the same name (for example |
| 242 | for static and shared version of a library, or for host and device versions). |
| 243 | Android.bp files require unique names for every module, but a single module can |
| 244 | be built in multiple variants, for example by adding `host_supported: true`. |
| 245 | The androidmk converter will produce multiple conflicting modules, which must |
| 246 | be resolved by hand to a single module with any differences inside |
| 247 | `target: { android: { }, host: { } }` blocks. |
| Colin Cross | e10ce18 | 2016-07-18 10:58:47 -0700 | [diff] [blame] | 248 | |
| 249 | ## Build logic |
| 250 | |
| 251 | The build logic is written in Go using the |
| 252 | [blueprint](http://godoc.org/github.com/google/blueprint) framework. Build |
| 253 | logic receives module definitions parsed into Go structures using reflection |
| 254 | and produces build rules. The build rules are collected by blueprint and |
| 255 | written to a [ninja](http://ninja-build.org) build file. |
| 256 | |
| Dan Willemsen | bc20362 | 2018-01-22 20:56:10 -0800 | [diff] [blame] | 257 | ## Other documentation |
| 258 | |
| 259 | * [Best Practices](docs/best_practices.md) |
| 260 | * [Build Performance](docs/perf.md) |
| 261 | * [Generating CLion Projects](docs/clion.md) |
| Alex Light | ec868fc | 2018-04-17 16:50:48 -0700 | [diff] [blame] | 262 | * [Generating YouCompleteMe/VSCode compile\_commands.json file](docs/compdb.md) |
| Dan Willemsen | bc20362 | 2018-01-22 20:56:10 -0800 | [diff] [blame] | 263 | * Make-specific documentation: [build/make/README.md](https://android.googlesource.com/platform/build/+/master/README.md) |
| 264 | |
| Colin Cross | e10ce18 | 2016-07-18 10:58:47 -0700 | [diff] [blame] | 265 | ## FAQ |
| 266 | |
| 267 | ### How do I write conditionals? |
| 268 | |
| 269 | Soong deliberately does not support conditionals in Android.bp files. |
| 270 | Instead, complexity in build rules that would require conditionals are handled |
| 271 | in Go, where high level language features can be used and implicit dependencies |
| 272 | introduced by conditionals can be tracked. Most conditionals are converted |
| 273 | to a map property, where one of the values in the map will be selected and |
| 274 | appended to the top level properties. |
| 275 | |
| 276 | For example, to support architecture specific files: |
| 277 | ``` |
| 278 | cc_library { |
| 279 | ... |
| 280 | srcs: ["generic.cpp"], |
| 281 | arch: { |
| 282 | arm: { |
| 283 | srcs: ["arm.cpp"], |
| 284 | }, |
| 285 | x86: { |
| 286 | srcs: ["x86.cpp"], |
| 287 | }, |
| 288 | }, |
| 289 | } |
| 290 | ``` |
| 291 | |
| Colin Cross | 1a01e83 | 2017-01-13 18:00:19 -0800 | [diff] [blame] | 292 | See [art/build/art.go](https://android.googlesource.com/platform/art/+/master/build/art.go) |
| 293 | or [external/llvm/soong/llvm.go](https://android.googlesource.com/platform/external/llvm/+/master/soong/llvm.go) |
| 294 | for examples of more complex conditionals on product variables or environment variables. |
| 295 | |
| Colin Cross | aa070b4 | 2018-07-09 09:44:41 -0700 | [diff] [blame] | 296 | ## Developing for Soong |
| 297 | |
| 298 | To load Soong code in a Go-aware IDE, create a directory outside your android tree and then: |
| 299 | ```bash |
| 300 | apt install bindfs |
| 301 | export GOPATH=<path to the directory you created> |
| 302 | build/soong/scripts/setup_go_workspace_for_soong.sh |
| 303 | ``` |
| 304 | |
| 305 | This will bind mount the Soong source directories into the directory in the layout expected by |
| 306 | the IDE. |
| 307 | |
| Colin Cross | e10ce18 | 2016-07-18 10:58:47 -0700 | [diff] [blame] | 308 | ## Contact |
| 309 | |
| 310 | Email android-building@googlegroups.com (external) for any questions, or see |
| 311 | [go/soong](http://go/soong) (internal). |