1# Build System Changes for Android.mk/Android.bp Writers 2 3## Soong genrules are now sandboxed 4 5Previously, soong genrules could access any files in the source tree, without specifying them as 6inputs. This makes them incorrect in incremental builds, and incompatible with RBE and Bazel. 7 8Now, genrules are sandboxed so they can only access their listed srcs. Modules denylisted in 9genrule/allowlists.go are exempt from this. You can also set `BUILD_BROKEN_GENRULE_SANDBOXING` 10in board config to disable this behavior. 11 12## Partitions are no longer affected by previous builds 13 14Partition builds used to include everything in their staging directories, and building an 15individual module will install it to the staging directory. Thus, previously, `m mymodule` followed 16by `m` would cause `mymodule` to be presinstalled on the device, even if it wasn't listed in 17`PRODUCT_PACKAGES`. 18 19This behavior has been changed, and now the partition images only include what they'd have if you 20did a clean build. This behavior can be disabled by setting the 21`BUILD_BROKEN_INCORRECT_PARTITION_IMAGES` environment variable or board config variable. 22 23Manually adding make rules that build to the staging directories without going through the make 24module system will not be compatible with this change. This includes many usages of 25`LOCAL_POST_INSTALL_CMD`. 26 27## Perform validation of Soong plugins 28 29Each Soong plugin will require manual work to migrate to Bazel. In order to 30minimize the manual work outside of build/soong, we are restricting plugins to 31those that exist today and those in vendor or hardware directories. 32 33If you need to extend the build system via a plugin, please reach out to the 34build team via email android-building@googlegroups.com (external) for any 35questions, or see [go/soong](http://go/soong) (internal). 36 37To omit the validation, `BUILD_BROKEN_PLUGIN_VALIDATION` expects a 38space-separated list of plugins to omit from the validation. This must be set 39within a product configuration .mk file, board config .mk file, or buildspec.mk. 40 41## Python 2 to 3 migration 42 43The path set when running builds now makes the `python` executable point to python 3, 44whereas on previous versions it pointed to python 2. If you still have python 2 scripts, 45you can change the shebang line to use `python2` explicitly. This only applies for 46scripts run directly from makefiles, or from soong genrules. This behavior can be 47temporarily overridden by setting the `BUILD_BROKEN_PYTHON_IS_PYTHON2` environment 48variable to `true`. It's only an environment variable and not a product config variable 49because product config sometimes calls python code. 50 51In addition, `python_*` soong modules no longer allow python 2. This can be temporarily 52overridden by setting the `BUILD_BROKEN_USES_SOONG_PYTHON2_MODULES` product configuration 53variable to `true`. 54 55Python 2 is slated for complete removal in V. 56 57## Stop referencing sysprop_library directly from cc modules 58 59For the migration to Bazel, we are no longer mapping sysprop_library targets 60to their generated `cc_library` counterparts when dependning on them from a 61cc module. Instead, directly depend on the generated module by prefixing the 62module name with `lib`. For example, depending on the following module: 63 64``` 65sysprop_library { 66 name: "foo", 67 srcs: ["foo.sysprop"], 68} 69``` 70 71from a module named `bar` can be done like so: 72 73``` 74cc_library { 75 name: "bar", 76 srcs: ["bar.cc"], 77 deps: ["libfoo"], 78} 79``` 80 81Failure to do this will result in an error about a missing variant. 82 83## Gensrcs starts disallowing depfile property 84 85To migrate all gensrcs to Bazel, we are restricting the use of depfile property 86because Bazel requires specifying the dependencies directly. 87 88To fix existing uses, remove depfile and directly specify all the dependencies 89in .bp files. For example: 90 91``` 92gensrcs { 93 name: "framework-cppstream-protos", 94 tools: [ 95 "aprotoc", 96 "protoc-gen-cppstream", 97 ], 98 cmd: "mkdir -p $(genDir)/$(in) " + 99 "&& $(location aprotoc) " + 100 " --plugin=$(location protoc-gen-cppstream) " + 101 " -I . " + 102 " $(in) ", 103 srcs: [ 104 "bar.proto", 105 ], 106 output_extension: "srcjar", 107} 108``` 109where `bar.proto` imports `external.proto` would become 110 111``` 112gensrcs { 113 name: "framework-cppstream-protos", 114 tools: [ 115 "aprotoc", 116 "protoc-gen-cpptream", 117 ], 118 tool_files: [ 119 "external.proto", 120 ], 121 cmd: "mkdir -p $(genDir)/$(in) " + 122 "&& $(location aprotoc) " + 123 " --plugin=$(location protoc-gen-cppstream) " + 124 " $(in) ", 125 srcs: [ 126 "bar.proto", 127 ], 128 output_extension: "srcjar", 129} 130``` 131as in https://android-review.googlesource.com/c/platform/frameworks/base/+/2125692/. 132 133`BUILD_BROKEN_DEPFILE` can be used to allowlist usage of depfile in `gensrcs`. 134 135If `depfile` is needed for generating javastream proto, `java_library` with `proto.type` 136set `stream` is the alternative solution. Sees 137https://android-review.googlesource.com/c/platform/packages/modules/Permission/+/2118004/ 138for an example. 139 140## Genrule starts disallowing directory inputs 141 142To better specify the inputs to the build, we are restricting use of directories 143as inputs to genrules. 144 145To fix existing uses, change inputs to specify the inputs and update the command 146accordingly. For example: 147 148``` 149genrule: { 150 name: "foo", 151 srcs: ["bar"], 152 cmd: "cp $(location bar)/*.xml $(gendir)", 153 ... 154} 155``` 156 157would become 158 159``` 160genrule: { 161 name: "foo", 162 srcs: ["bar/*.xml"], 163 cmd: "cp $(in) $(gendir)", 164 ... 165} 166``` 167 168`BUILD_BROKEN_INPUT_DIR_MODULES` can be used to allowlist specific directories 169with genrules that have input directories. 170 171## Dexpreopt starts enforcing `<uses-library>` checks (for Java modules) 172 173In order to construct correct class loader context for dexpreopt, build system 174needs to know about the shared library dependencies of Java modules listed in 175the `<uses-library>` tags in the manifest. Since the build system does not have 176access to the manifest contents, that information must be present in the build 177files. In simple cases Soong is able to infer it from its knowledge of Java SDK 178libraries and the `libs` property in Android.bp, but in more complex cases it is 179necessary to add the missing information in Android.bp/Android.mk manually. 180 181To specify a list of libraries for a given modules, use: 182 183* Android.bp properties: `uses_libs`, `optional_uses_libs` 184* Android.mk variables: `LOCAL_USES_LIBRARIES`, `LOCAL_OPTIONAL_USES_LIBRARIES` 185 186If a library is in `libs`, it usually should *not* be added to the above 187properties, and Soong should be able to infer the `<uses-library>` tag. But 188sometimes a library also needs additional information in its 189Android.bp/Android.mk file (e.g. when it is a `java_library` rather than a 190`java_sdk_library`, or when the library name is different from its module name, 191or when the module is defined in Android.mk rather than Android.bp). In such 192cases it is possible to tell the build system that the library provides a 193`<uses-library>` with a given name (however, this is discouraged and will be 194deprecated in the future, and it is recommended to fix the underlying problem): 195 196* Android.bp property: `provides_uses_lib` 197* Android.mk variable: `LOCAL_PROVIDES_USES_LIBRARY` 198 199It is possible to disable the check on a per-module basis. When doing that it is 200also recommended to disable dexpreopt, as disabling a failed check will result 201in incorrect class loader context recorded in the .odex file, which will cause 202class loader context mismatch and dexopt at first boot. 203 204* Android.bp property: `enforce_uses_lib` 205* Android.mk variable: `LOCAL_ENFORCE_USES_LIBRARIES` 206 207Finally, it is possible to globally disable the check: 208 209* For a given product: `PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true` 210* On the command line: `RELAX_USES_LIBRARY_CHECK=true` 211 212The environment variable overrides the product variable, so it is possible to 213disable the check for a product, but quickly re-enable it for a local build. 214 215## `LOCAL_REQUIRED_MODULES` requires listed modules to exist {#BUILD_BROKEN_MISSING_REQUIRED_MODULES} 216 217Modules listed in `LOCAL_REQUIRED_MODULES`, `LOCAL_HOST_REQUIRED_MODULES` and 218`LOCAL_TARGET_REQUIRED_MODULES` need to exist unless `ALLOW_MISSING_DEPENDENCIES` 219is set. 220 221To temporarily relax missing required modules check, use: 222 223`BUILD_BROKEN_MISSING_REQUIRED_MODULES := true` 224 225## Changes in system properties settings 226 227### Product variables 228 229System properties for each of the partition is supposed to be set via following 230product config variables. 231 232For system partition, 233 234* `PRODUCT_SYSTEM_PROPERTIES` 235* `PRODUCT_SYSTEM_DEFAULT_PROPERTIES` is highly discouraged. Will be deprecated. 236 237For vendor partition, 238 239* `PRODUCT_VENDOR_PROPERTIES` 240* `PRODUCT_PROPERTY_OVERRIDES` is highly discouraged. Will be deprecated. 241* `PRODUCT_DEFAULT_PROPERTY_OVERRIDES` is also discouraged. Will be deprecated. 242 243For odm partition, 244 245* `PRODUCT_ODM_PROPERTIES` 246 247For system_ext partition, 248 249* `PRODUCT_SYSTEM_EXT_PROPERTIES` 250 251For product partition, 252 253* `PRODUCT_PRODUCT_PROPERTIES` 254 255### Duplication is not allowed within a partition 256 257For each partition, having multiple sysprop assignments for the same name is 258prohibited. For example, the following will now trigger an error: 259 260`PRODUCT_VENDOR_PROPERTIES += foo=true foo=false` 261 262Having duplication across partitions are still allowed. So, the following is 263not an error: 264 265`PRODUCT_VENDOR_PROPERTIES += foo=true` 266`PRODUCT_SYSTEM_PROPERTIES += foo=false` 267 268In that case, the final value is determined at runtime. The precedence is 269 270* product 271* odm 272* vendor 273* system_ext 274* system 275 276So, `foo` becomes `true` because vendor has higher priority than system. 277 278To temporarily turn the build-time restriction off, use 279 280`BUILD_BROKEN_DUP_SYSPROP := true` 281 282### Optional assignments 283 284System properties can now be set as optional using the new syntax: 285 286`name ?= value` 287 288Then the system property named `name` gets the value `value` only when there 289is no other non-optional assignments having the same name. For example, the 290following is allowed and `foo` gets `true` 291 292`PRODUCT_VENDOR_PROPERTIES += foo=true foo?=false` 293 294Note that the order between the optional and the non-optional assignments 295doesn't matter. The following gives the same result as above. 296 297`PRODUCT_VENDOR_PROPERTIES += foo?=false foo=true` 298 299Optional assignments can be duplicated and in that case their order matters. 300Specifically, the last one eclipses others. 301 302`PRODUCT_VENDOR_PROPERTIES += foo?=apple foo?=banana foo?=mango` 303 304With above, `foo` becomes `mango` since its the last one. 305 306Note that this behavior is different from the previous behavior of preferring 307the first one. To go back to the original behavior for compatability reason, 308use: 309 310`BUILD_BROKEN_DUP_SYSPROP := true` 311 312## ELF prebuilts in `PRODUCT_COPY_FILES` {#BUILD_BROKEN_ELF_PREBUILT_PRODUCT_COPY_FILES} 313 314ELF prebuilts in `PRODUCT_COPY_FILES` that are installed into these paths are an 315error: 316 317* `<partition>/bin/*` 318* `<partition>/lib/*` 319* `<partition>/lib64/*` 320 321Define prebuilt modules and add them to `PRODUCT_PACKAGES` instead. 322To temporarily relax this check and restore the behavior prior to this change, 323set `BUILD_BROKEN_ELF_PREBUILT_PRODUCT_COPY_FILES := true` in `BoardConfig.mk`. 324 325## COPY_HEADERS usage now produces warnings {#copy_headers} 326 327We've considered `BUILD_COPY_HEADERS`/`LOCAL_COPY_HEADERS` to be deprecated for 328a long time, and the places where it's been able to be used have shrinked over 329the last several releases. Equivalent functionality is not available in Soong. 330 331See the [build/soong/docs/best_practices.md#headers] for more information about 332how best to handle headers in Android. 333 334## `m4` is not available on `$PATH` 335 336There is a prebuilt of it available in prebuilts/build-tools, and a make 337variable `M4` that contains the path. 338 339Beyond the direct usage, whenever you use bison or flex directly, they call m4 340behind the scene, so you must set the M4 environment variable (and depend upon 341it for incremental build correctness): 342 343``` 344$(intermediates)/foo.c: .KATI_IMPLICIT_OUTPUTS := $(intermediates)/foo.h 345$(intermediates)/foo.c: $(LOCAL_PATH)/foo.y $(M4) $(BISON) $(BISON_DATA) 346 M4=$(M4) $(BISON) ... 347``` 348 349## Rules executed within limited environment 350 351With `ALLOW_NINJA_ENV=false` (soon to be the default), ninja, and all the 352rules/actions executed within it will only have access to a limited number of 353environment variables. Ninja does not track when environment variables change 354in order to trigger rebuilds, so changing behavior based on arbitrary variables 355is not safe with incremental builds. 356 357Kati and Soong can safely use environment variables, so the expectation is that 358you'd embed any environment variables that you need to use within the command 359line generated by those tools. See the [export section](#export_keyword) below 360for examples. 361 362For a temporary workaround, you can set `ALLOW_NINJA_ENV=true` in your 363environment to restore the previous behavior, or set 364`BUILD_BROKEN_NINJA_USES_ENV_VAR := <var> <var2> ...` in your `BoardConfig.mk` 365to allow specific variables to be passed through until you've fixed the rules. 366 367## LOCAL_C_INCLUDES outside the source/output trees are an error {#BUILD_BROKEN_OUTSIDE_INCLUDE_DIRS} 368 369Include directories are expected to be within the source tree (or in the output 370directory, generated during the build). This has been checked in some form 371since Oreo, but now has better checks. 372 373There's now a `BUILD_BROKEN_OUTSIDE_INCLUDE_DIRS` variable, that when set, will 374turn these errors into warnings temporarily. I don't expect this to last more 375than a release, since they're fairly easy to clean up. 376 377Neither of these cases are supported by Soong, and will produce errors when 378converting your module. 379 380### Absolute paths 381 382This has been checked since Oreo. The common reason to hit this is because a 383makefile is calculating a path, and ran abspath/realpath/etc. This is a problem 384because it makes your build non-reproducible. It's very unlikely that your 385source path is the same on every machine. 386 387### Using `../` to leave the source/output directories 388 389This is the new check that has been added. In every case I've found, this has 390been a mistake in the Android.mk -- assuming that `LOCAL_C_INCLUDES` (which is 391relative to the top of the source tree) acts like `LOCAL_SRC_FILES` (which is 392relative to `LOCAL_PATH`). 393 394Since this usually isn't a valid path, you can almost always just remove the 395offending line. 396 397 398## `BOARD_HAL_STATIC_LIBRARIES` and `LOCAL_HAL_STATIC_LIBRARIES` are obsolete {#BOARD_HAL_STATIC_LIBRARIES} 399 400Define proper HIDL / Stable AIDL HAL instead. 401 402* For libhealthd, use health HAL. See instructions for implementing 403 health HAL: 404 405 * [hardware/interfaces/health/2.1/README.md] for health 2.1 HAL (recommended) 406 * [hardware/interfaces/health/1.0/README.md] for health 1.0 HAL 407 408* For libdumpstate, use at least Dumpstate HAL 1.0. 409 410## PRODUCT_STATIC_BOOT_CONTROL_HAL is obsolete {#PRODUCT_STATIC_BOOT_CONTROL_HAL} 411 412`PRODUCT_STATIC_BOOT_CONTROL_HAL` was the workaround to allow sideloading with 413statically linked boot control HAL, before shared library HALs were supported 414under recovery. Android Q has added such support (HALs will be loaded in 415passthrough mode), and the workarounds are being removed. Targets should build 416and install the recovery variant of boot control HAL modules into recovery 417image, similar to the ones installed for normal boot. See the change to 418crosshatch for example of this: 419 420* [device/google/crosshatch/bootctrl/Android.bp] for `bootctrl.sdm845` building 421 rules 422* [device/google/crosshatch/device.mk] for installing `bootctrl.sdm845.recovery` 423 and `android.hardware.boot@1.0-impl.recovery` into recovery image 424 425[device/google/crosshatch/bootctrl/Android.bp]: https://android.googlesource.com/device/google/crosshatch/+/master/bootctrl/Android.bp 426[device/google/crosshatch/device.mk]: https://android.googlesource.com/device/google/crosshatch/+/master/device.mk 427 428## Deprecation of `BUILD_*` module types 429 430See [build/make/Deprecation.md](Deprecation.md) for the current status. 431 432## `PRODUCT_HOST_PACKAGES` split from `PRODUCT_PACKAGES` {#PRODUCT_HOST_PACKAGES} 433 434Previously, adding a module to `PRODUCT_PACKAGES` that supported both the host 435and the target (`host_supported` in Android.bp; two modules with the same name 436in Android.mk) would cause both to be built and installed. In many cases you 437only want either the host or target versions to be built/installed by default, 438and would be over-building with both. So `PRODUCT_PACKAGES` will be changing to 439just affect target modules, while `PRODUCT_HOST_PACKAGES` is being added for 440host modules. 441 442Functional differences between `PRODUCT_PACKAGES` and `PRODUCT_HOST_PACKAGES`: 443 444* `PRODUCT_HOST_PACKAGES` does not have `_ENG`/`_DEBUG` variants, as that's a 445 property of the target, not the host. 446* `PRODUCT_HOST_PACKAGES` does not support `LOCAL_MODULE_OVERRIDES`. 447* `PRODUCT_HOST_PACKAGES` requires listed modules to exist, and be host 448 modules. (Unless `ALLOW_MISSING_DEPENDENCIES` is set) 449 450This is still an active migration, so currently it still uses 451`PRODUCT_PACKAGES` to make installation decisions, but verifies that if we used 452`PRODUCT_HOST_PACKAGES`, it would trigger installation for all of the same host 453packages. This check ignores shared libraries, as those are not normally 454necessary in `PRODUCT_*PACKAGES`, and tended to be over-built (especially the 45532-bit variants). 456 457Future changes will switch installation decisions to `PRODUCT_HOST_PACKAGES` 458for host modules, error when there's a host-only module in `PRODUCT_PACKAGES`, 459and do some further cleanup where `LOCAL_REQUIRED_MODULES` are still merged 460between host and target modules with the same name. 461 462## `*.c.arm` / `*.cpp.arm` deprecation {#file_arm} 463 464In Android.mk files, you used to be able to change LOCAL_ARM_MODE for each 465source file by appending `.arm` to the end of the filename in 466`LOCAL_SRC_FILES`. 467 468Soong does not support this uncommonly used behavior, instead expecting those 469files to be split out into a separate static library that chooses `arm` over 470`thumb` for the entire library. This must now also be done in Android.mk files. 471 472## Windows cross-compiles no longer supported in Android.mk 473 474Modules that build for Windows (our only `HOST_CROSS` OS currently) must now be 475defined in `Android.bp` files. 476 477## `LOCAL_MODULE_TAGS := eng debug` are obsolete {#LOCAL_MODULE_TAGS} 478 479`LOCAL_MODULE_TAGS` value `eng` and `debug` are now obsolete. They allowed 480modules to specify that they should always be installed on `-eng`, or `-eng` 481and `-userdebug` builds. This conflicted with the ability for products to 482specify which modules should be installed, effectively making it impossible to 483build a stripped down product configuration that did not include those modules. 484 485For the equivalent functionality, specify the modules in `PRODUCT_PACKAGES_ENG` 486or `PRODUCT_PACKAGES_DEBUG` in the appropriate product makefiles. 487 488Core android packages like `su` got added to the list in 489`build/make/target/product/base_system.mk`, but for device-specific modules 490there are often better base product makefiles to use instead. 491 492## `USER` deprecation {#USER} 493 494`USER` will soon be `nobody` in many cases due to the addition of a sandbox 495around the Android build. Most of the time you shouldn't need to know the 496identity of the user running the build, but if you do, it's available in the 497make variable `BUILD_USERNAME` for now. 498 499Similarly, the `hostname` tool will also be returning a more consistent value 500of `android-build`. The real value is available as `BUILD_HOSTNAME`. 501 502## `BUILD_NUMBER` removal from Android.mk {#BUILD_NUMBER} 503 504`BUILD_NUMBER` should not be used directly in Android.mk files, as it would 505trigger them to be re-read every time the `BUILD_NUMBER` changes (which it does 506on every build server build). If possible, just remove the use so that your 507builds are more reproducible. If you do need it, use `BUILD_NUMBER_FROM_FILE`: 508 509``` make 510$(LOCAL_BUILT_MODULE): 511 mytool --build_number $(BUILD_NUMBER_FROM_FILE) -o $@ 512``` 513 514That will expand out to a subshell that will read the current `BUILD_NUMBER` 515whenever it's run. It will not re-run your command if the build number has 516changed, so incremental builds will have the build number from the last time 517the particular output was rebuilt. 518 519## `DIST_DIR`, `dist_goal`, and `dist-for-goals` {#dist} 520 521`DIST_DIR` and `dist_goal` are no longer available when reading Android.mk 522files (or other build tasks). Always use `dist-for-goals` instead, which takes 523a PHONY goal, and a list of files to copy to `$DIST_DIR`. Whenever `dist` is 524specified, and the goal would be built (either explicitly on the command line, 525or as a dependency of something on the command line), that file will be copied 526into `$DIST_DIR`. For example, 527 528``` make 529$(call dist-for-goals,foo,bar/baz) 530``` 531 532will copy `bar/baz` into `$DIST_DIR/baz` when `m foo dist` is run. 533 534#### FILE_NAME_TAG {#FILE_NAME_TAG} 535 536To embed the `BUILD_NUMBER` (or for local builds, `eng.${USER}`), include 537`FILE_NAME_TAG_PLACEHOLDER` in the destination: 538 539``` make 540# you can use dist-for-goals-with-filenametag function 541$(call dist-for-goals-with-filenametag,foo,bar.zip) 542# or use FILE_NAME_TAG_PLACEHOLDER manually 543$(call dist-for-goals,foo,bar.zip:baz-FILE_NAME_TAG_PLACEHOLDER.zip) 544``` 545 546Which will produce `$DIST_DIR/baz-1234567.zip` on build servers which set 547`BUILD_NUMBER=1234567`, or `$DIST_DIR/baz-eng.builder.zip` for local builds. 548 549If you just want to append `BUILD_NUMBER` at the end of basename, use 550`dist-for-goals-with-filenametag` instead of `dist-for-goals`. 551 552#### Renames during copy 553 554Instead of specifying just a file, a destination name can be specified, 555including subdirectories: 556 557``` make 558$(call dist-for-goals,foo,bar/baz:logs/foo.log) 559``` 560 561will copy `bar/baz` into `$DIST_DIR/logs/foo.log` when `m foo dist` is run. 562 563## `.PHONY` rule enforcement {#phony_targets} 564 565There are several new warnings/errors meant to ensure the proper use of 566`.PHONY` targets in order to improve the speed and reliability of incremental 567builds. 568 569`.PHONY`-marked targets are often used as shortcuts to provide "friendly" names 570for real files to be built, but any target marked with `.PHONY` is also always 571considered dirty, needing to be rebuilt every build. This isn't a problem for 572aliases or one-off user-requested operations, but if real builds steps depend 573on a `.PHONY` target, it can get quite expensive for what should be a tiny 574build. 575 576``` make 577...mk:42: warning: PHONY target "out/.../foo" looks like a real file (contains a "/") 578``` 579 580Between this warning and the next, we're requiring that `.PHONY` targets do not 581have "/" in them, and real file targets do have a "/". This makes it more 582obvious when reading makefiles what is happening, and will help the build 583system differentiate these in the future too. 584 585``` make 586...mk:42: warning: writing to readonly directory: "kernel-modules" 587``` 588 589This warning will show up for one of two reasons: 590 5911. The target isn't intended to be a real file, and should be marked with 592 `.PHONY`. This would be the case for this example. 5932. The target is a real file, but it's outside the output directories. All 594 outputs from the build system should be within the output directory, 595 otherwise `m clean` is unable to clean the build, and future builds may not 596 work properly. 597 598``` make 599...mk:42: warning: real file "out/.../foo" depends on PHONY target "buildbins" 600``` 601 602If the first target isn't intended to be a real file, then it should be marked 603with `.PHONY`, which will satisfy this warning. This isn't the case for this 604example, as we require `.PHONY` targets not to have '/' in them. 605 606If the second (PHONY) target is a real file, it may unnecessarily be marked 607with `.PHONY`. 608 609### `.PHONY` and calling other build systems 610 611One common pattern (mostly outside AOSP) that we've seen hit these warning is 612when building with external build systems (firmware, bootloader, kernel, etc). 613Those are often marked as `.PHONY` because the Android build system doesn't 614have enough dependencies to know when to run the other build system again 615during an incremental build. 616 617We recommend to build these outside of Android, and deliver prebuilts into the 618Android tree instead of decreasing the speed and reliability of the incremental 619Android build. 620 621In cases where that's not desired, to preserve the speed of Android 622incrementals, over-specifying dependencies is likely a better option than 623marking it with `.PHONY`: 624 625``` make 626out/target/.../zImage: $(sort $(shell find -L $(KERNEL_SRCDIR))) 627 ... 628``` 629 630For reliability, many of these other build systems do not guarantee the same 631level of incremental build assurances as the Android Build is attempting to do 632-- without custom checks, Make doesn't rebuild objects when CFLAGS change, etc. 633In order to fix this, our recommendation is to do clean builds for each of 634these external build systems every time anything they rely on changes. For 635relatively smaller builds (like the kernel), this may be reasonable as long as 636you're not trying to actively debug the kernel. 637 638## `export` and `unexport` deprecation {#export_keyword} 639 640The `export` and `unexport` keywords are obsolete, and will throw errors when 641used. 642 643Device specific configuration should not be able to affect common core build 644steps -- we're looking at triggering build steps to be invalidated if the set 645of environment variables they can access changes. If device specific 646configuration is allowed to change those, switching devices with the same 647output directory could become significantly more expensive than it already can 648be. 649 650If used during Android.mk files, and later tasks, it is increasingly likely 651that they are being used incorrectly. Attempting to change the environment for 652a single build step, and instead setting it for hundreds of thousands. 653 654It is not recommended to just move the environment variable setting outside of 655the build (in vendorsetup.sh, or some other configuration script or wrapper). 656We expect to limit the environment variables that the build respects in the 657future, others will be cleared. (There will be methods to get custom variables 658into the build, just not to every build step) 659 660Instead, write the export commands into the rule command lines themselves: 661 662``` make 663$(intermediates)/generated_output.img: 664 rm -rf $@ 665 export MY_ENV_A="$(MY_A)"; make ... 666``` 667 668If you want to set many environment variables, and/or use them many times, 669write them out to a script and source the script: 670 671``` make 672envsh := $(intermediates)/env.sh 673$(envsh): 674 rm -rf $@ 675 echo 'export MY_ENV_A="$(MY_A)"' >$@ 676 echo 'export MY_ENV_B="$(MY_B)"' >>$@ 677 678$(intermediates)/generated_output.img: PRIVATE_ENV := $(envsh) 679$(intermediates)/generated_output.img: $(envsh) a/b/c/package.sh 680 rm -rf $@ 681 source $(PRIVATE_ENV); make ... 682 source $(PRIVATE_ENV); a/b/c/package.sh ... 683``` 684 685## Implicit make rules are obsolete {#implicit_rules} 686 687Implicit rules look something like the following: 688 689``` make 690$(TARGET_OUT_SHARED_LIBRARIES)/%_vendor.so: $(TARGET_OUT_SHARED_LIBRARIES)/%.so 691 ... 692 693%.o : %.foo 694 ... 695``` 696 697These can have wide ranging effects across unrelated modules, so they're now obsolete. Instead, use static pattern rules, which are similar, but explicitly match the specified outputs: 698 699``` make 700libs := $(foreach lib,libfoo libbar,$(TARGET_OUT_SHARED_LIBRARIES)/$(lib)_vendor.so) 701$(libs): %_vendor.so: %.so 702 ... 703 704files := $(wildcard $(LOCAL_PATH)/*.foo) 705gen := $(patsubst $(LOCAL_PATH)/%.foo,$(intermediates)/%.o,$(files)) 706$(gen): %.o : %.foo 707 ... 708``` 709 710## Removing '/' from Valid Module Names {#name_slash} 711 712The build system uses module names in path names in many places. Having an 713extra '/' or '../' being inserted can cause problems -- and not just build 714breaks, but stranger invalid behavior. 715 716In every case we've seen, the fix is relatively simple: move the directory into 717`LOCAL_MODULE_RELATIVE_PATH` (or `LOCAL_MODULE_PATH` if you're still using it). 718If this causes multiple modules to be named the same, use unique module names 719and `LOCAL_MODULE_STEM` to change the installed file name: 720 721``` make 722include $(CLEAR_VARS) 723LOCAL_MODULE := ver1/code.bin 724LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/firmware 725... 726include $(BUILD_PREBUILT) 727 728include $(CLEAR_VARS) 729LOCAL_MODULE := ver2/code.bin 730LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/firmware 731... 732include $(BUILD_PREBUILT) 733``` 734 735Can be rewritten as: 736 737``` 738include $(CLEAR_VARS) 739LOCAL_MODULE := ver1_code.bin 740LOCAL_MODULE_STEM := code.bin 741LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/firmware/ver1 742... 743include $(BUILD_PREBUILT) 744 745include $(CLEAR_VARS) 746LOCAL_MODULE := ver2_code.bin 747LOCAL_MODULE_STEM := code.bin 748LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/firmware/ver2 749... 750include $(BUILD_PREBUILT) 751``` 752 753You just need to make sure that any other references (`PRODUCT_PACKAGES`, 754`LOCAL_REQUIRED_MODULES`, etc) are converted to the new names. 755 756## Valid Module Names {#name} 757 758We've adopted lexical requirements very similar to [Bazel's 759requirements](https://docs.bazel.build/versions/master/build-ref.html#name) for 760target names. Valid characters are `a-z`, `A-Z`, `0-9`, and the special 761characters `_.+-=,@~`. This currently applies to `LOCAL_PACKAGE_NAME`, 762`LOCAL_MODULE`, and `LOCAL_MODULE_SUFFIX`, and `LOCAL_MODULE_STEM*`. 763 764Many other characters already caused problems if you used them, so we don't 765expect this to have a large effect. 766 767## PATH Tools {#PATH_Tools} 768 769The build has started restricting the external host tools usable inside the 770build. This will help ensure that build results are reproducible across 771different machines, and catch mistakes before they become larger issues. 772 773To start with, this includes replacing the $PATH with our own directory of 774tools, mirroring that of the host PATH. The only difference so far is the 775removal of the host GCC tools. Anything that is not explicitly in the 776configuration as allowed will continue functioning, but will generate a log 777message. This is expected to become more restrictive over time. 778 779The configuration is located in build/soong/ui/build/paths/config.go, and 780contains all the common tools in use in many builds. Anything not in that list 781will currently print a warning in the `$OUT_DIR/soong.log` file, including the 782command and arguments used, and the process tree in order to help locate the 783usage. 784 785In order to fix any issues brought up by these checks, the best way to fix them 786is to use tools checked into the tree -- either as prebuilts, or building them 787as host tools during the build. 788 789As a temporary measure, you can set `TEMPORARY_DISABLE_PATH_RESTRICTIONS=true` 790in your environment to temporarily turn off the error checks and allow any tool 791to be used (with logging). Beware that GCC didn't work well with the interposer 792used for logging, so this may not help in all cases. 793 794## Deprecating / obsoleting envsetup.sh variables in Makefiles 795 796It is not required to source envsetup.sh before running a build. Many scripts, 797including a majority of our automated build systems, do not do so. Make will 798transparently make every environment variable available as a make variable. 799This means that relying on environment variables only set up in envsetup.sh will 800produce different output for local users and scripted users. 801 802Many of these variables also include absolute path names, which we'd like to 803keep out of the generated files, so that you don't need to do a full rebuild if 804you move the source tree. 805 806To fix this, we're marking the variables that are set in envsetup.sh as 807deprecated in the makefiles. This will trigger a warning every time one is read 808(or written) inside Kati. Once all the warnings have been removed for a 809particular variable, we'll switch it to obsolete, and any references will become 810errors. 811 812### envsetup.sh variables with make equivalents 813 814| instead of | use | 815|--------------------------------------------------------------|----------------------| 816| OUT {#OUT} | PRODUCT_OUT | 817| ANDROID_HOST_OUT {#ANDROID_HOST_OUT} | HOST_OUT | 818| ANDROID_PRODUCT_OUT {#ANDROID_PRODUCT_OUT} | PRODUCT_OUT | 819| ANDROID_HOST_OUT_TESTCASES {#ANDROID_HOST_OUT_TESTCASES} | HOST_OUT_TESTCASES | 820| ANDROID_TARGET_OUT_TESTCASES {#ANDROID_TARGET_OUT_TESTCASES} | TARGET_OUT_TESTCASES | 821 822All of the make variables may be relative paths from the current directory, or 823absolute paths if the output directory was specified as an absolute path. If you 824need an absolute variable, convert it to absolute during a rule, so that it's 825not expanded into the generated ninja file: 826 827``` make 828$(PRODUCT_OUT)/gen.img: my/src/path/gen.sh 829 export PRODUCT_OUT=$$(cd $(PRODUCT_OUT); pwd); cd my/src/path; ./gen.sh -o $${PRODUCT_OUT}/gen.img 830``` 831 832### ANDROID_BUILD_TOP {#ANDROID_BUILD_TOP} 833 834In Android.mk files, you can always assume that the current directory is the 835root of the source tree, so this can just be replaced with '.' (which is what 836$TOP is hardcoded to), or removed entirely. If you need an absolute path, see 837the instructions above. 838 839### Stop using PATH directly {#PATH} 840 841This isn't only set by envsetup.sh, but it is modified by it. Due to that it's 842rather easy for this to change between different shells, and it's not ideal to 843reread the makefiles every time this changes. 844 845In most cases, you shouldn't need to touch PATH at all. When you need to have a 846rule reference a particular binary that's part of the source tree or outputs, 847it's preferrable to just use the path to the file itself (since you should 848already be adding that as a dependency). 849 850Depending on the rule, passing the file path itself may not be feasible due to 851layers of unchangable scripts/binaries. In that case, be sure to add the 852dependency, but modify the PATH within the rule itself: 853 854``` make 855$(TARGET): myscript my/path/binary 856 PATH=my/path:$$PATH myscript -o $@ 857``` 858 859### Stop using PYTHONPATH directly {#PYTHONPATH} 860 861Like PATH, this isn't only set by envsetup.sh, but it is modified by it. Due to 862that it's rather easy for this to change between different shells, and it's not 863ideal to reread the makefiles every time. 864 865The best solution here is to start switching to Soong's python building support, 866which packages the python interpreter, libraries, and script all into one file 867that no longer needs PYTHONPATH. See fontchain_lint for examples of this: 868 869* [external/fonttools/Lib/fontTools/Android.bp] for python_library_host 870* [frameworks/base/Android.bp] for python_binary_host 871* [frameworks/base/data/fonts/Android.mk] to execute the python binary 872 873If you still need to use PYTHONPATH, do so within the rule itself, just like 874path: 875 876``` make 877$(TARGET): myscript.py $(sort $(shell find my/python/lib -name '*.py')) 878 PYTHONPATH=my/python/lib:$$PYTHONPATH myscript.py -o $@ 879``` 880### Stop using PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE directly {#PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE} 881 882Specify Framework Compatibility Matrix Version in device manifest by adding a `target-level` 883attribute to the root element `<manifest>`. If `PRODUCT_COMPATIBILITY_MATRIX_LEVEL_OVERRIDE` 884is 26 or 27, you can add `"target-level"="1"` to your device manifest instead. 885 886### Stop using USE_CLANG_PLATFORM_BUILD {#USE_CLANG_PLATFORM_BUILD} 887 888Clang is the default and only supported Android compiler, so there is no reason 889for this option to exist. 890 891### Stop using clang property 892 893The clang property has been deleted from Soong. To fix any build errors, remove the clang 894property from affected Android.bp files using bpmodify. 895 896 897``` make 898go run bpmodify.go -w -m=module_name -remove-property=true -property=clang filepath 899``` 900 901`BUILD_BROKEN_CLANG_PROPERTY` can be used as temporarily workaround 902 903 904### Stop using clang_cflags and clang_asflags 905 906clang_cflags and clang_asflags are deprecated. 907To fix any build errors, use bpmodify to either 908 - move the contents of clang_asflags/clang_cflags into asflags/cflags or 909 - delete clang_cflags/as_flags as necessary 910 911To Move the contents: 912``` make 913go run bpmodify.go -w -m=module_name -move-property=true -property=clang_cflags -new-location=cflags filepath 914``` 915 916To Delete: 917``` make 918go run bpmodify.go -w -m=module_name -remove-property=true -property=clang_cflags filepath 919``` 920 921`BUILD_BROKEN_CLANG_ASFLAGS` and `BUILD_BROKEN_CLANG_CFLAGS` can be used as temporarily workarounds 922 923### Other envsetup.sh variables {#other_envsetup_variables} 924 925* ANDROID_TOOLCHAIN 926* ANDROID_TOOLCHAIN_2ND_ARCH 927* ANDROID_DEV_SCRIPTS 928* ANDROID_EMULATOR_PREBUILTS 929* ANDROID_PRE_BUILD_PATHS 930 931These are all exported from envsetup.sh, but don't have clear equivalents within 932the makefile system. If you need one of them, you'll have to set up your own 933version. 934 935## Soong config variables 936 937### Soong config string variables must list all values they can be set to 938 939In order to facilitate the transition to bazel, all soong_config_string_variables 940must only be set to a value listed in their `values` property, or an empty string. 941It is a build error otherwise. 942 943Example Android.bp: 944``` 945soong_config_string_variable { 946 name: "my_string_variable", 947 values: [ 948 "foo", 949 "bar", 950 ], 951} 952 953soong_config_module_type { 954 name: "my_cc_defaults", 955 module_type: "cc_defaults", 956 config_namespace: "my_namespace", 957 variables: ["my_string_variable"], 958 properties: [ 959 "shared_libs", 960 "static_libs", 961 ], 962} 963``` 964Product config: 965``` 966$(call soong_config_set,my_namespace,my_string_variable,baz) # Will be an error as baz is not listed in my_string_variable's values. 967``` 968 969[build/soong/Changes.md]: https://android.googlesource.com/platform/build/soong/+/master/Changes.md 970[build/soong/docs/best_practices.md#headers]: https://android.googlesource.com/platform/build/soong/+/master/docs/best_practices.md#headers 971[external/fonttools/Lib/fontTools/Android.bp]: https://android.googlesource.com/platform/external/fonttools/+/master/Lib/fontTools/Android.bp 972[frameworks/base/Android.bp]: https://android.googlesource.com/platform/frameworks/base/+/master/Android.bp 973[frameworks/base/data/fonts/Android.mk]: https://android.googlesource.com/platform/frameworks/base/+/master/data/fonts/Android.mk 974[hardware/interfaces/health/1.0/README.md]: https://android.googlesource.com/platform/hardware/interfaces/+/master/health/1.0/README.md 975[hardware/interfaces/health/2.1/README.md]: https://android.googlesource.com/platform/hardware/interfaces/+/master/health/2.1/README.md 976