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