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