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