xref: /aosp_15_r20/build/soong/docs/perf.md (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker# Build Performance
2*333d2b36SAndroid Build Coastguard Worker
3*333d2b36SAndroid Build Coastguard Worker## Debugging Build Performance
4*333d2b36SAndroid Build Coastguard Worker
5*333d2b36SAndroid Build Coastguard Worker### Tracing
6*333d2b36SAndroid Build Coastguard Worker
7*333d2b36SAndroid Build Coastguard Workersoong_ui has tracing built in, so that every build execution's trace can be
8*333d2b36SAndroid Build Coastguard Workerviewed.  Just open `$OUT_DIR/build.trace.gz` in Chrome's <chrome://tracing>, or
9*333d2b36SAndroid Build Coastguard Workerwith [catapult's trace viewer][catapult trace_viewer]. The last few traces are
10*333d2b36SAndroid Build Coastguard Workerstored in `build.trace.#.gz` (larger numbers are older). The associated logs
11*333d2b36SAndroid Build Coastguard Workerare stored in `soong.#.log` and `verbose.#.log.gz`.
12*333d2b36SAndroid Build Coastguard Worker
13*333d2b36SAndroid Build Coastguard Worker![trace example](./trace_example.png)
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Worker### Critical path
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workersoong_ui logs the wall time of the longest dependency chain compared to the
18*333d2b36SAndroid Build Coastguard Workerelapsed wall time in `$OUT_DIR/soong.log`.  For example:
19*333d2b36SAndroid Build Coastguard Worker```
20*333d2b36SAndroid Build Coastguard Workercritical path took 3m10s
21*333d2b36SAndroid Build Coastguard Workerelapsed time 5m16s
22*333d2b36SAndroid Build Coastguard Workerperfect parallelism ratio 60%
23*333d2b36SAndroid Build Coastguard Workercritical path:
24*333d2b36SAndroid Build Coastguard Worker    0:00 build out/target/product/generic_arm64/obj/FAKE/sepolicy_neverallows_intermediates/policy_2.conf
25*333d2b36SAndroid Build Coastguard Worker    0:04 build out/target/product/generic_arm64/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows
26*333d2b36SAndroid Build Coastguard Worker    0:13 build out/target/product/generic_arm64/obj/ETC/plat_sepolicy.cil_intermediates/plat_sepolicy.cil
27*333d2b36SAndroid Build Coastguard Worker    0:01 build out/target/product/generic_arm64/obj/ETC/plat_pub_versioned.cil_intermediates/plat_pub_versioned.cil
28*333d2b36SAndroid Build Coastguard Worker    0:02 build out/target/product/generic_arm64/obj/ETC/vendor_sepolicy.cil_intermediates/vendor_sepolicy.cil
29*333d2b36SAndroid Build Coastguard Worker    0:16 build out/target/product/generic_arm64/obj/ETC/sepolicy_intermediates/sepolicy
30*333d2b36SAndroid Build Coastguard Worker    0:00 build out/target/product/generic_arm64/obj/ETC/plat_seapp_contexts_intermediates/plat_seapp_contexts
31*333d2b36SAndroid Build Coastguard Worker    0:00 Install: out/target/product/generic_arm64/system/etc/selinux/plat_seapp_contexts
32*333d2b36SAndroid Build Coastguard Worker    0:02 build out/target/product/generic_arm64/obj/NOTICE.txt
33*333d2b36SAndroid Build Coastguard Worker    0:00 build out/target/product/generic_arm64/obj/NOTICE.xml.gz
34*333d2b36SAndroid Build Coastguard Worker    0:00 build out/target/product/generic_arm64/system/etc/NOTICE.xml.gz
35*333d2b36SAndroid Build Coastguard Worker    0:01 Installed file list: out/target/product/generic_arm64/installed-files.txt
36*333d2b36SAndroid Build Coastguard Worker    1:00 Target system fs image: out/target/product/generic_arm64/obj/PACKAGING/systemimage_intermediates/system.img
37*333d2b36SAndroid Build Coastguard Worker    0:01 Install system fs image: out/target/product/generic_arm64/system.img
38*333d2b36SAndroid Build Coastguard Worker    0:01 Target vbmeta image: out/target/product/generic_arm64/vbmeta.img
39*333d2b36SAndroid Build Coastguard Worker    1:26 Package target files: out/target/product/generic_arm64/obj/PACKAGING/target_files_intermediates/aosp_arm64-target_files-6663974.zip
40*333d2b36SAndroid Build Coastguard Worker    0:01 Package: out/target/product/generic_arm64/aosp_arm64-img-6663974.zip
41*333d2b36SAndroid Build Coastguard Worker    0:01 Dist: /buildbot/dist_dirs/aosp-master-linux-aosp_arm64-userdebug/6663974/aosp_arm64-img-6663974.zip
42*333d2b36SAndroid Build Coastguard Worker```
43*333d2b36SAndroid Build Coastguard Worker
44*333d2b36SAndroid Build Coastguard WorkerIf the elapsed time is much longer than the critical path then additional
45*333d2b36SAndroid Build Coastguard Workerparallelism on the build machine will improve total build times. If there are
46*333d2b36SAndroid Build Coastguard Workerlong individual times listed in the critical path then improving build times
47*333d2b36SAndroid Build Coastguard Workerfor those steps or adjusting dependencies so that those steps can run earlier
48*333d2b36SAndroid Build Coastguard Workerin the build graph will improve total build times.
49*333d2b36SAndroid Build Coastguard Worker
50*333d2b36SAndroid Build Coastguard Worker### Soong
51*333d2b36SAndroid Build Coastguard Worker
52*333d2b36SAndroid Build Coastguard WorkerSoong proper (i.e., `soong_build` executable that processes the blueprint
53*333d2b36SAndroid Build Coastguard Workerfiles) can be traced and profiled using the standard Go tools. It understands
54*333d2b36SAndroid Build Coastguard Workerthe `-trace`, `-cpuprofile`, and `-memprofile` command line arguments.
55*333d2b36SAndroid Build Coastguard WorkerSetting `SOONG_PROFILE_CPU` and/or `SOONG_PROFILE_MEM` environment variables
56*333d2b36SAndroid Build Coastguard Workerfor the build enables respective profiling, e.g., running
57*333d2b36SAndroid Build Coastguard Worker
58*333d2b36SAndroid Build Coastguard Worker```shell
59*333d2b36SAndroid Build Coastguard WorkerSOONG_PROFILE_CPU=/tmp/foo m ..._
60*333d2b36SAndroid Build Coastguard Worker```
61*333d2b36SAndroid Build Coastguard Worker
62*333d2b36SAndroid Build Coastguard Workersaves CPU profile for each Soong invocation in /tmp/foo._step_ file, where
63*333d2b36SAndroid Build Coastguard Worker_step_ is Soong execution step. The main step is `build`. The others as
64*333d2b36SAndroid Build Coastguard Worker`soong_docs` (not all of them necessarily run during the build).
65*333d2b36SAndroid Build Coastguard WorkerThe profiles can be inspected with `go tool pprof` from the command line or
66*333d2b36SAndroid Build Coastguard Workerwith _Run>Open Profiler Snapshot_ in IntelliJ IDEA.
67*333d2b36SAndroid Build Coastguard Worker
68*333d2b36SAndroid Build Coastguard Worker### Kati
69*333d2b36SAndroid Build Coastguard Worker
70*333d2b36SAndroid Build Coastguard WorkerIn general, the slow path of reading Android.mk files isn't particularly
71*333d2b36SAndroid Build Coastguard Workerperformance sensitive, since it doesn't need to happen on every build. It is
72*333d2b36SAndroid Build Coastguard Workerimportant for the fast-path (detecting whether it needs to regenerate the ninja
73*333d2b36SAndroid Build Coastguard Workerfile) to be fast however. And it shouldn't hit the slow path too often -- so
74*333d2b36SAndroid Build Coastguard Workerdon't rely on output of a `$(shell)` command that includes the current timestamp,
75*333d2b36SAndroid Build Coastguard Workeror read a file that's going to change on every build.
76*333d2b36SAndroid Build Coastguard Worker
77*333d2b36SAndroid Build Coastguard Worker#### Regen check is slow
78*333d2b36SAndroid Build Coastguard Worker
79*333d2b36SAndroid Build Coastguard WorkerIn most cases, we've found that the fast-path is slow because all of the
80*333d2b36SAndroid Build Coastguard Worker`$(shell)` commands need to be re-executed to determine if their output changed.
81*333d2b36SAndroid Build Coastguard WorkerThe `$OUT_DIR/verbose.log.gz` contains statistics from the regen check:
82*333d2b36SAndroid Build Coastguard Worker
83*333d2b36SAndroid Build Coastguard Worker```
84*333d2b36SAndroid Build Coastguard Workerverbose: *kati*: regen check time: 0.754030
85*333d2b36SAndroid Build Coastguard Workerverbose: *kati*: glob time (regen): 0.545859 / 43840
86*333d2b36SAndroid Build Coastguard Workerverbose: *kati*: shell time (regen): 0.278095 / 66 (59 unique)
87*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   0.012 / 1 mkdir -p out/target/product/generic && echo Android/aosp_arm/generic:R/AOSP.MASTER/$(date -d @$(cat out/build_date.txt) +%m%d%H%M):eng/test-keys >out/target/product/generic/build_fingerprint.txt && grep " " out/target/product/generic/build_fingerprint.txt
88*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   0.010 / 1 echo 'com.android.launcher3.config.FlagOverrideSampleTest com.android.launcher3.logging.FileLogTest com.android.launcher3.model.AddWorkspaceItemsTaskTest com.android.launcher3.model.CacheDataUpdatedTaskTest com.android.launcher3.model.DbDowngradeHelperTest com.android.launcher3.model.GridBackupTableTest com.android.launcher3.model.GridSizeMigrationTaskTest com.android.launcher3.model.PackageInstallStateChangedTaskTest com.android.launcher3.popup.PopupPopulatorTest com.android.launcher3.util.GridOccupancyTest com.android.launcher3.util.IntSetTest' | tr ' ' '\n' | cat
89*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   0.010 / 1 cd cts/tests/framework/base/windowmanager ; find -L  * -name "Components.java" -and -not -name ".*"
90*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   0.010 / 1 git -C test/framework/build log -s -n 1 --format="%cd" --date=format:"%Y%m%d_%H%M%S" 2>/dev/null
91*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   0.009 / 2 cd development/samples/ShortcutDemo/publisher ; find -L  ../common/src -name "*.java" -and -not -name ".*"
92*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   0.009 / 2 cd development/samples/ShortcutDemo/launcher ; find -L  ../common/src -name "*.java" -and -not -name ".*"
93*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   0.009 / 1 if ! cmp -s out/target/product/generic/obj/CONFIG/kati_packaging/dist.mk.tmp out/target/product/generic/obj/CONFIG/kati_packaging/dist.mk; then mv out/target/product/generic/obj/CONFIG/kati_packaging/dist.mk.tmp out/target/product/generic/obj/CONFIG/kati_packaging/dist.mk; else rm out/target/product/generic/obj/CONFIG/kati_packaging/dist.mk.tmp; fi
94*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   0.008 / 1 mkdir -p out/target/product/generic && echo R/AOSP.MASTER/$(cat out/build_number.txt):eng/test-keys >out/target/product/generic/build_thumbprint.txt && grep " " out/target/product/generic/build_thumbprint.txt
95*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   0.007 / 1 echo 'com.android.customization.model.clock.BaseClockManagerTest com.android.customization.model.clock.ClockManagerTest com.android.customization.model.grid.GridOptionsManagerTest com.android.customization.model.theme.ThemeManagerTest' | tr ' ' '\n' | cat
96*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   0.007 / 1 uname -sm
97*333d2b36SAndroid Build Coastguard Workerverbose: *kati*: stat time (regen): 0.361907 / 1241
98*333d2b36SAndroid Build Coastguard Worker```
99*333d2b36SAndroid Build Coastguard Worker
100*333d2b36SAndroid Build Coastguard WorkerIn this case, the total time spent checking was 0.75 seconds, even though the
101*333d2b36SAndroid Build Coastguard Workerother "(regen)" numbers add up to more than that (some parts are parallelized
102*333d2b36SAndroid Build Coastguard Workerwhere possible). Often times, the biggest contributor is the `$(shell)` times
103*333d2b36SAndroid Build Coastguard Worker-- in this case, 66 calls took 0.27s. The top 10 longest shell functions are
104*333d2b36SAndroid Build Coastguard Workerprinted.
105*333d2b36SAndroid Build Coastguard Worker
106*333d2b36SAndroid Build Coastguard WorkerAll the longest commands in this case are all variants of a call to `find`, but
107*333d2b36SAndroid Build Coastguard Workerthis is where using pure make functions instead of calling out to the shell can
108*333d2b36SAndroid Build Coastguard Workermake a performance impact -- many calls to check if `26 > 20` can add up. We've
109*333d2b36SAndroid Build Coastguard Workeradded some basic math functions in `math.mk` to help some common use cases that
110*333d2b36SAndroid Build Coastguard Workerused to be rather expensive when they were used too often.
111*333d2b36SAndroid Build Coastguard Worker
112*333d2b36SAndroid Build Coastguard WorkerThere are some optimizations in place for find commands -- if Kati can
113*333d2b36SAndroid Build Coastguard Workerunderstand the find command, the built-in find emulator can turn some of them
114*333d2b36SAndroid Build Coastguard Workerinto glob or stat checks (falling back to calling `find` if one of those imply
115*333d2b36SAndroid Build Coastguard Workerthat the output may change). Many of the common macros produce find commands
116*333d2b36SAndroid Build Coastguard Workerthat Kati can understand, but if you're writing your own, you may want to
117*333d2b36SAndroid Build Coastguard Workerexperiment with other options if they're showing up in this list. For example,
118*333d2b36SAndroid Build Coastguard Workerif this was significantly more expensive (either in runtime, or was called
119*333d2b36SAndroid Build Coastguard Workeroften):
120*333d2b36SAndroid Build Coastguard Worker
121*333d2b36SAndroid Build Coastguard Worker```
122*333d2b36SAndroid Build Coastguard Worker.../kati.go:127: *kati*:  0.015 cd libcore && (find luni/src/test/java -name "*.java" 2> /dev/null) | grep -v -f java_tests_blacklist
123*333d2b36SAndroid Build Coastguard Worker```
124*333d2b36SAndroid Build Coastguard Worker
125*333d2b36SAndroid Build Coastguard WorkerIt may be more efficient to move the grep into make, so that the `find` portion
126*333d2b36SAndroid Build Coastguard Workercan be rewritten and cached:
127*333d2b36SAndroid Build Coastguard Worker
128*333d2b36SAndroid Build Coastguard Worker```
129*333d2b36SAndroid Build Coastguard Worker$(filter-out $(file <$(LOCAL_PATH)/java_tests_blacklist),$(call all-java-files-under,luni/src/test/java))
130*333d2b36SAndroid Build Coastguard Worker```
131*333d2b36SAndroid Build Coastguard Worker
132*333d2b36SAndroid Build Coastguard WorkerOthers can be simplified by just switching to an equivalent find command that
133*333d2b36SAndroid Build Coastguard WorkerKati understands:
134*333d2b36SAndroid Build Coastguard Worker
135*333d2b36SAndroid Build Coastguard Worker```
136*333d2b36SAndroid Build Coastguard Worker.../kati.go:127: *kati*:  0.217 find device vendor -type f -name \*.pk8 -o -name verifiedboot\* -o -name \*.x509.pem -o -name oem\*.prop | sort
137*333d2b36SAndroid Build Coastguard Worker```
138*333d2b36SAndroid Build Coastguard Worker
139*333d2b36SAndroid Build Coastguard WorkerBy adding the implicit `-a` and moving the `| sort` to Make, this can now be
140*333d2b36SAndroid Build Coastguard Workercached by Kati:
141*333d2b36SAndroid Build Coastguard Worker
142*333d2b36SAndroid Build Coastguard Worker```
143*333d2b36SAndroid Build Coastguard Worker$(sort $(shell find device vendor -type -f -a -name \*.pk8 -o -name verifiedboot\* -o -name \*.x509.pem -o -name oem\*.prop))
144*333d2b36SAndroid Build Coastguard Worker```
145*333d2b36SAndroid Build Coastguard Worker
146*333d2b36SAndroid Build Coastguard WorkerKati has now learned about the implicit `-a`, so this particular change is no
147*333d2b36SAndroid Build Coastguard Workerlonger necessary, but the basic concept holds.
148*333d2b36SAndroid Build Coastguard Worker
149*333d2b36SAndroid Build Coastguard Worker#### Kati regens too often
150*333d2b36SAndroid Build Coastguard Worker
151*333d2b36SAndroid Build Coastguard WorkerKati prints out what triggered the slow path to be taken -- this can be a
152*333d2b36SAndroid Build Coastguard Workerchanged file, a changed environment variable, or different output from a
153*333d2b36SAndroid Build Coastguard Worker`$(shell)` command:
154*333d2b36SAndroid Build Coastguard Worker
155*333d2b36SAndroid Build Coastguard Worker```
156*333d2b36SAndroid Build Coastguard Workerout/soong/Android-aosp_arm.mk was modified, regenerating...
157*333d2b36SAndroid Build Coastguard Worker```
158*333d2b36SAndroid Build Coastguard Worker
159*333d2b36SAndroid Build Coastguard WorkerThe state is stored in `$OUT_DIR/.kati_stamp*` files, and can be (partially)
160*333d2b36SAndroid Build Coastguard Workerread with the `ckati_stamp_dump` tool in prebuilts/build-tools. More debugging
161*333d2b36SAndroid Build Coastguard Workeris available when ckati is run with `--regen_debug`, but that can be a lot of
162*333d2b36SAndroid Build Coastguard Workerdata to understand.
163*333d2b36SAndroid Build Coastguard Worker
164*333d2b36SAndroid Build Coastguard Worker#### Debugging the slow path
165*333d2b36SAndroid Build Coastguard Worker
166*333d2b36SAndroid Build Coastguard WorkerKati will now dump out information about which Makefiles took the most time to
167*333d2b36SAndroid Build Coastguard Workerexecute. This is also in the `verbose.log.gz` file:
168*333d2b36SAndroid Build Coastguard Worker
169*333d2b36SAndroid Build Coastguard Worker```
170*333d2b36SAndroid Build Coastguard Workerverbose: *kati*: included makefiles: 73.640833 / 232810 (1066 unique)
171*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:  18.389 /     1 out/soong/Android-aosp_arm.mk
172*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:  13.137 / 20144 build/make/core/soong_cc_prebuilt.mk
173*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:  11.743 / 27666 build/make/core/base_rules.mk
174*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   2.289 /     1 art/Android.mk
175*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   2.054 /     1 art/build/Android.cpplint.mk
176*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   1.955 / 28269 build/make/core/clear_vars.mk
177*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   1.795 /   283 build/make/core/package.mk
178*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   1.790 /   283 build/make/core/package_internal.mk
179*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   1.757 / 17382 build/make/core/link_type.mk
180*333d2b36SAndroid Build Coastguard Workerverbose: *kati*:   1.078 /   297 build/make/core/aapt2.mk
181*333d2b36SAndroid Build Coastguard Worker```
182*333d2b36SAndroid Build Coastguard Worker
183*333d2b36SAndroid Build Coastguard WorkerThis shows that soong_cc_prebuilt.mk was included 20144 times, for a total time
184*333d2b36SAndroid Build Coastguard Workerspent of 13.137 secounds. While Android-aosp_arm.mk was only included once, and
185*333d2b36SAndroid Build Coastguard Workertook 18.389 seconds. In this case, Android-aosp_arm.mk is the only file that
186*333d2b36SAndroid Build Coastguard Workerincludes soong_cc_prebuilt.mk, so we can safely assume that 13 of the 18 seconds
187*333d2b36SAndroid Build Coastguard Workerin Android-aosp_arm.mk was actually spent within soong_cc_prebuilt.mk (or
188*333d2b36SAndroid Build Coastguard Workersomething that it included, like base_rules.mk).
189*333d2b36SAndroid Build Coastguard Worker
190*333d2b36SAndroid Build Coastguard WorkerBy default this only includes the top 10 entries, but you can ask for the stats
191*333d2b36SAndroid Build Coastguard Workerfor any makefile to be printed with `$(KATI_profile_makefile)`:
192*333d2b36SAndroid Build Coastguard Worker
193*333d2b36SAndroid Build Coastguard Worker```
194*333d2b36SAndroid Build Coastguard Worker$(KATI_profile_makefile build/make/core/product.mk)
195*333d2b36SAndroid Build Coastguard Worker```
196*333d2b36SAndroid Build Coastguard Worker
197*333d2b36SAndroid Build Coastguard WorkerWith these primitives, it's possible to get the timing information for small
198*333d2b36SAndroid Build Coastguard Workerchunks, or even single lines, of a makefile. Just move the lines you want to
199*333d2b36SAndroid Build Coastguard Workermeasure into a new makefile, and replace their use with an `include` of the
200*333d2b36SAndroid Build Coastguard Workernew makefile. It's possible to analyze where the time is being spent by doing
201*333d2b36SAndroid Build Coastguard Workera binary search using this method, but you do need to be careful not to split
202*333d2b36SAndroid Build Coastguard Workerconditionals across two files (the ifeq/else/endif must all be in the same file).
203*333d2b36SAndroid Build Coastguard Worker
204*333d2b36SAndroid Build Coastguard Worker### Ninja
205*333d2b36SAndroid Build Coastguard Worker
206*333d2b36SAndroid Build Coastguard Worker#### Understanding why something rebuilt
207*333d2b36SAndroid Build Coastguard Worker
208*333d2b36SAndroid Build Coastguard WorkerAdd `NINJA_ARGS="-d explain"` to your environment before a build, this will cause
209*333d2b36SAndroid Build Coastguard Workerninja to print out explanations on why actions were taken. Start reading from the
210*333d2b36SAndroid Build Coastguard Workerbeginning, as this much data can be hard to read:
211*333d2b36SAndroid Build Coastguard Worker
212*333d2b36SAndroid Build Coastguard Worker```
213*333d2b36SAndroid Build Coastguard Worker$ cd art
214*333d2b36SAndroid Build Coastguard Worker$ mma
215*333d2b36SAndroid Build Coastguard Worker$ touch runtime/jit/profile_compilation_info.h
216*333d2b36SAndroid Build Coastguard Worker$ NINJA_ARGS="-d explain" mma
217*333d2b36SAndroid Build Coastguard Worker...
218*333d2b36SAndroid Build Coastguard Workerninja explain: output out/soong/.intermediates/art/tools/cpp-define-generator/cpp-define-generator-data/linux_glibc_x86_64/obj/art/tools/cpp-define-generator/main.o older than most recent input art/runtime/jit/profile_compilation_info.h (
219*333d2b36SAndroid Build Coastguard Worker1516683538 vs 1516685188)
220*333d2b36SAndroid Build Coastguard Workerninja explain: out/soong/.intermediates/art/tools/cpp-define-generator/cpp-define-generator-data/linux_glibc_x86_64/obj/art/tools/cpp-define-generator/main.o is dirty
221*333d2b36SAndroid Build Coastguard Workerninja explain: out/soong/.intermediates/art/tools/cpp-define-generator/cpp-define-generator-data/linux_glibc_x86_64/cpp-define-generator-data is dirty
222*333d2b36SAndroid Build Coastguard Workerninja explain: out/soong/host/linux-x86/bin/cpp-define-generator-data is dirty
223*333d2b36SAndroid Build Coastguard Workerninja explain: out/soong/.intermediates/art/tools/cpp-define-generator/cpp-define-generator-asm-support/gen/asm_support_gen.h is dirty
224*333d2b36SAndroid Build Coastguard Workerninja explain: out/soong/.intermediates/art/cmdline/art_cmdline_tests/android_arm_armv7-a_core_cmdline_parser_test/obj/art/cmdline/cmdline_parser_test.o is dirty
225*333d2b36SAndroid Build Coastguard Worker...
226*333d2b36SAndroid Build Coastguard Worker```
227*333d2b36SAndroid Build Coastguard Worker
228*333d2b36SAndroid Build Coastguard WorkerIn this case, art/cmdline/cmdline_parser_test.o was rebuilt because it uses
229*333d2b36SAndroid Build Coastguard Workerasm_support_gen.h, which was generated by cpp-define-generator-data, which uses
230*333d2b36SAndroid Build Coastguard Workerprofile_compilation_info.h.
231*333d2b36SAndroid Build Coastguard Worker
232*333d2b36SAndroid Build Coastguard WorkerYou'll likely need to cross-reference this data against the build graph in the
233*333d2b36SAndroid Build Coastguard Workervarious .ninja files. The files are (mostly) human-readable, but a (slow) web
234*333d2b36SAndroid Build Coastguard Workerinterface can be used by running `NINJA_ARGS="-t browse <target>" m`.
235*333d2b36SAndroid Build Coastguard Worker
236*333d2b36SAndroid Build Coastguard WorkerThere is also `SOONG_UI_NINJA_ARGS`, which passes ninja arguments to soong ui's
237*333d2b36SAndroid Build Coastguard Workerninja invocations, e.g. to emit $OUT_DIR/soong/build.ninja, $OUT_DIR/soong/module-graph.json, etc.
238*333d2b36SAndroid Build Coastguard Worker
239*333d2b36SAndroid Build Coastguard Worker```bash
240*333d2b36SAndroid Build Coastguard Worker$ m nothing
241*333d2b36SAndroid Build Coastguard Worker$ touch Android.bp
242*333d2b36SAndroid Build Coastguard Worker$ SOONG_UI_NINJA_ARGS="-d explain" m nothing
243*333d2b36SAndroid Build Coastguard Worker...
244*333d2b36SAndroid Build Coastguard Workerninja explain: restat of output out/soong/build.ninja older than most recent input Android.bp
245*333d2b36SAndroid Build Coastguard Worker...
246*333d2b36SAndroid Build Coastguard Worker```
247*333d2b36SAndroid Build Coastguard Worker
248*333d2b36SAndroid Build Coastguard Worker#### Builds take a long time
249*333d2b36SAndroid Build Coastguard Worker
250*333d2b36SAndroid Build Coastguard WorkerIf the long part in the trace view of a build is a relatively solid block, then
251*333d2b36SAndroid Build Coastguard Workerthe performance is probably more related to how much time the actual build
252*333d2b36SAndroid Build Coastguard Workercommands are taking than having extra dependencies, or slowdowns in
253*333d2b36SAndroid Build Coastguard Workersoong/kati/ninja themselves.
254*333d2b36SAndroid Build Coastguard Worker
255*333d2b36SAndroid Build Coastguard WorkerBeyond looking at visible outliers in the trace view, we don't have any tooling
256*333d2b36SAndroid Build Coastguard Workerto help in this area yet. It's possible to aggregate some of the raw data
257*333d2b36SAndroid Build Coastguard Workertogether, but since our builds are heavily parallelized, it's particularly easy
258*333d2b36SAndroid Build Coastguard Workerfor build commands to impact unrelated build commands. This is an area we'd
259*333d2b36SAndroid Build Coastguard Workerlike to improve -- we expect keeping track of user/system time per-action would
260*333d2b36SAndroid Build Coastguard Workerprovide more reliable data, but tracking some full-system data (memory/swap
261*333d2b36SAndroid Build Coastguard Workeruse, disk bandwidth, etc) may also be necessary.
262*333d2b36SAndroid Build Coastguard Worker
263*333d2b36SAndroid Build Coastguard Worker## Known Issues
264*333d2b36SAndroid Build Coastguard Worker
265*333d2b36SAndroid Build Coastguard Worker### Common
266*333d2b36SAndroid Build Coastguard Worker
267*333d2b36SAndroid Build Coastguard Worker### <= Android 10 (Q): mm
268*333d2b36SAndroid Build Coastguard Worker
269*333d2b36SAndroid Build Coastguard WorkerSoong always loads the entire module graph, so as modules convert from Make to
270*333d2b36SAndroid Build Coastguard WorkerSoong, `mm` is becoming closer to `mma`. This produces more correct builds, but
271*333d2b36SAndroid Build Coastguard Workerdoes slow down builds, as we need to verify/produce/load a larger build graph.
272*333d2b36SAndroid Build Coastguard Worker
273*333d2b36SAndroid Build Coastguard WorkerAs of Android Q, loading large build graphs is fast, and in Android R, `mm` is
274*333d2b36SAndroid Build Coastguard Workernow an alias of `mma`.
275*333d2b36SAndroid Build Coastguard Worker
276*333d2b36SAndroid Build Coastguard Worker### Android 8.1 (Oreo MR1)
277*333d2b36SAndroid Build Coastguard Worker
278*333d2b36SAndroid Build Coastguard WorkerIn some cases, a tree would get into a state where Soong would be run twice on
279*333d2b36SAndroid Build Coastguard Workerevery incremental build, even if there was nothing to do. This was fixed in
280*333d2b36SAndroid Build Coastguard Workermaster with [these changes][blueprint_microfactory], but they were too
281*333d2b36SAndroid Build Coastguard Workersignificant to backport at the time. And while they fix this particular issue,
282*333d2b36SAndroid Build Coastguard Workerthey appear to cause ninja to spend more time during every build loading the
283*333d2b36SAndroid Build Coastguard Worker`.ninja_log` / `.ninja_deps` files, especially as they become larger.
284*333d2b36SAndroid Build Coastguard Worker
285*333d2b36SAndroid Build Coastguard WorkerA workaround to get out of this state is to remove the build.ninja entry from
286*333d2b36SAndroid Build Coastguard Worker`$OUT_DIR/.ninja_log`:
287*333d2b36SAndroid Build Coastguard Worker
288*333d2b36SAndroid Build Coastguard Worker```
289*333d2b36SAndroid Build Coastguard Workersed -i "/\/build.ninja/d" $(get_build_var OUT_DIR)/.ninja_log
290*333d2b36SAndroid Build Coastguard Worker```
291*333d2b36SAndroid Build Coastguard Worker
292*333d2b36SAndroid Build Coastguard Worker[catapult trace_viewer]: https://github.com/catapult-project/catapult/blob/master/tracing/README.md
293*333d2b36SAndroid Build Coastguard Worker[ninja parse optimization]: https://android-review.googlesource.com/c/platform/external/ninja/+/461005
294*333d2b36SAndroid Build Coastguard Worker[blueprint_microfactory]: https://android-review.googlesource.com/q/topic:%22blueprint_microfactory%22+status:merged
295