1# mkcompare: Compare generated Android-TARGET.mk makefiles 2 3## Summary 4 5This tool shows the differences between two `Android-`_target_`.mk` makefile. 6This makefile contains information about the Soong build graph that is exposed 7to Make (Android.mk) and packaging rules. 8 9## Usage 10 11```shell 12# run product config 13$ lunch ${target} 14 15# run soong for reference build 16$ m nothing && cp out/soong/Android-${target}.mk Android-${target}.mk.ref 17 18# apply your local changes.. 19$ m nothing && cp out/soong/Android-${target}.mk Android-${target}.mk.new 20 21# compare! 22$ GOWORK=$PWD/build/bazel/mkcompare/go.work go run android/bazel/mkcompare/cmd \ 23 -json \ 24 Android-${target}.mk.ref \ 25 Android-${target}.mk.new > ${target}.mk.json 26``` 27 28## Options ## 29 30The comparator optionally: 31 32* Generates a JSON file with all the differences (`-json`). This option turns off all out output. 33* Stops after finding given _N_ different modules `-m N`) 34* Ignores variables with given names (`--ignore_variables=VAR,...`) 35* Shows per-variable value difference (`--show_module_diffs`) 36* For each module type, shows the names of the modules with this difference (`--show_type_modules`) 37 38## How it works 39 40We assume that both makefiles were generated for the same configuration (i.e., 41the same _target_ value, and our goal is thus to find out the difference that 42a change contributes to the Makefile interface between Soong and Make. 43 44Currently, the comparator inspects only the module sections of a file. 45 46A _module section_ looks something like this: 47```makefile 48include $(CLEAR_VARS) # <module type> 49LOCAL_MODULE := mymod 50LOCAL_MODULE_CLASS := ETC 51include $(BUILD_PREBUILT) 52``` 53 54i.e., it always starts with `include $(CLEAR_VARS)` ('module header') line 55and spans until the blank line. Before a blank line there is an 56`include <mkfile>` line ('module footer'), which may be followed by a few extra 57variable assignments. Between those two `include ` lines are the assignment lines. 58 59The name of the module is synthesized from the value of the `LOCAL_MODULE` variable 60and target configuration, e.g, `apex_tzdata.com.android.tzdata|cls:ETC|target_arch:arm64` 61or `aac_dec_fuzzer|cls:EXECUTABLES|host_arch:x86_64` 62 63The module header includes the module type as a comment (the plan was to use the 64_mkfile_ on the footer line, but it proved to be common to most of the modules, 65so Soong was modified to provide a module detailed module type as a comment 66on the header line). 67 68A module section in the reference file is compared with the 69identically named module section of our file. The following items are compared: 70 71* module types 72* the number of extra lines following the section footer 73* the variables and their values 74 75## Summary Output 76 77The default outputs look as follows: 78``` 79159 missing modules, by type: 80 apex.apexBundle.files (159 modules) 81 82Missing variables (14): 83 ... 84 LOCAL_REQUIRED_MODULES, by type: 85 art_cc_library (2 modules) 86 art_cc_library_static (4 modules) 87 cc_library (28 modules) 88 cc_library_shared (2 modules) 89 LOCAL_SHARED_LIBRARIES, by type: 90 art_cc_library (60 modules) 91 .... 92Extra variables (7): 93 LOCAL_EXPORT_CFLAGS, by type: 94 cc_library (4 modules) 95 LOCAL_EXPORT_C_INCLUDE_DEPS, by type: 96 art_cc_library (28 modules) 97 ... 98Diff variables: (18) 99 LOCAL_EXPORT_C_INCLUDE_DEPS, by type: 100 aidl_interface.go_android/soong/aidl.wrapLibraryFactory.func1__topDownMutatorModule (1721 modules) 101 art_cc_library (12 modules) 102 LOCAL_PREBUILT_MODULE_FILE, by type: 103 apex.apexBundle (7 modules) 104 apex.apexBundle.files (625 modules) 105 ... 106``` 107 108## JSON Output ## 109 110It looks like this: 111```JSON 112{ 113 "RefPath": "<...>/out/soong/Android-aosp_arm64.mk", 114 "OurPath": "<...>/out.mixed/soong/Android-aosp_arm64.mk", 115 "MissingModules": [ 116 "adbd.com.android.adbd|cls:EXECUTABLES|target_arch:arm64", 117 "android.hardware.common-V2-ndk.com.android.media.swcodec|cls:SHARED_LIBRARIES|target_arch:arm64", 118 "android.hardware.graphics.allocator-V1-ndk.com.android.media.swcodec|cls:SHARED_LIBRARIES|target_arch:arm64", 119 "android.hardware.graphics.allocator@2.0.com.android.media.swcodec|cls:SHARED_LIBRARIES|target_arch:arm64", 120 ... 121 ], 122 "DiffModules": [ 123 { 124 "Name": "_makenames|cls:EXECUTABLES|target_arch:arm64", 125 "RefLocation": 137674, 126 "OurLocation": 137673, 127 "MissingVars": [ "LOCAL_SHARED_LIBRARIES", "LOCAL_STATIC_LIBRARIES" ], 128 "DiffVars": [ 129 { 130 "Name": "LOCAL_PREBUILT_MODULE_FILE", 131 "MissingItems": [ "out/soong/.intermediates/external/libcap/_makenames/android_arm64_armv8-a/_makenames" ], 132 "ExtraItems": [ "out/bazel-bin/external/libcap/_makenames" ] 133 }, 134 { 135 "Name": "LOCAL_SOONG_UNSTRIPPED_BINARY", 136 "MissingItems": [ "out/soong/.intermediates/external/libcap/_makenames/android_arm64_armv8-a/unstripped/_makenames" ], 137 "ExtraItems": [ "out/bazel-bin/external/libcap/_makenames_unstripped" ] 138 } 139 ] 140 }, 141 ... 142 ] 143} 144``` 145Use JSON query tool like [`jq`](https://github.com/stedolan/jq) to slice and dice it. 146