• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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