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 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