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