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