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