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