diff --git a/scripts/run-ckati.sh b/scripts/run-ckati.sh new file mode 100755 index 000000000..b670c8af8 --- /dev/null +++ b/scripts/run-ckati.sh @@ -0,0 +1,91 @@ +#! /bin/bash -eu + +# Run CKati step separately, tracing given Makefile variables. +# It is expected that the regular Android null build (`m nothing`) +# has been run so that $OUT_DIR/soong/Android-${TARGET_PRODUCT}.mk, +# $OUT_DIR/soong/make_vars-${TARGET_PRODUCT}.mk, etc. files exist. +# +# The output file is in JSON format and can be processed with, say, +# `jq`. For instance, the following invocation outputs all assignment +# traces concisely: +# jq -c '.assignments[] | (select (.operation == "assign")) | {("n"): .name, ("l"): .value_stack[0]?, ("v"): .value }' out/ckati.trace +# generates +# {"n":"","l":":","v":""} +# ... + +function die() { format=$1; shift; printf "$format\n" $@; exit 1; } +function usage() { die "Usage: %s [-o FILE] VAR ...\n(without -o the output goes to ${outfile})" ${0##*/}; } + +[[ -d build/soong ]] || die "run this script from the top of the Android source tree" +declare -r out=${OUT_DIR:-out} +[[ -x ${out}/soong_ui ]] || die "run Android build first" +: ${TARGET_PRODUCT:?not set, run lunch?} +: ${TARGET_BUILD_VARIANT:?not set, run lunch?} +declare -r androidmk=${out}/soong/Android-${TARGET_PRODUCT}.mk +declare -r makevarsmk=${out}/soong/make_vars-${TARGET_PRODUCT}.mk +declare -r target_device_dir=$(${out}/soong_ui --dumpvar-mode TARGET_DEVICE_DIR) +: ${target_device_dir:?cannot find device directory for ${TARGET_PRODUCT}} +declare -r target_device=$(${out}/soong_ui --dumpvar-mode TARGET_DEVICE) +: ${target_device:?cannot find target device for ${TARGET_PRODUCT}} +declare -r timestamp_file=${out}/build_date.txt +# Files should exist, so ls should succeed: +ls -1d "$androidmk" "$makevarsmk" "$target_device_dir" "$timestamp_file" >/dev/null + +outfile=${out}/ckati.trace +while getopts "ho:" opt; do + case $opt in + h) usage ;; + o) outfile=$OPTARG ;; + ?) usage ;; + esac +done + +if (($#>0)); then + declare -a tracing=(--variable_assignment_trace_filter="$*" --dump_variable_assignment_trace "$outfile") +else + printf "running ckati without tracing variables\n" +fi + +# Touch one input for ckati, otherwise it will just print +# 'No need to regenerate ninja file' and exit. +touch "$androidmk" +prebuilts/build-tools/linux-x86/bin/ckati \ + --gen_all_targets \ + -i \ + --ignore_optional_include=out/%.P \ + --ninja \ + --ninja_dir=out \ + --ninja_suffix=-${TARGET_PRODUCT} \ + --no_builtin_rules \ + --no_ninja_prelude \ + --regen \ + --top_level_phony \ + --use_find_emulator \ + --use_ninja_phony_output \ + --use_ninja_symlink_outputs \ + --werror_find_emulator \ + --werror_implicit_rules \ + --werror_overriding_commands \ + --werror_phony_looks_real \ + --werror_real_to_phony \ + --werror_suffix_rules \ + --werror_writable \ + --writable out/ \ + -f build/make/core/main.mk \ + "${tracing[@]}" \ + ANDROID_JAVA_HOME=prebuilts/jdk/jdk17/linux-x86 \ + ASAN_SYMBOLIZER_PATH=$PWD/prebuilts/clang/host/linux-x86/llvm-binutils-stable/llvm-symbolizer \ + BUILD_DATETIME_FILE="$timestamp_file" \ + BUILD_HOSTNAME=$(hostname) \ + BUILD_USERNAME="$USER" \ + JAVA_HOME=$PWD/prebuilts/jdk/jdk17/linux-x86 \ + KATI_PACKAGE_MK_DIR="{$out}/target/product/${target_device}/CONFIG/kati_packaging" \ + OUT_DIR="$out" \ + PATH="$PWD/prebuilts/build-tools/path/linux-x86:$PWD/${out}/.path" \ + PYTHONDONTWRITEBYTECODE=1 \ + SOONG_ANDROID_MK="$androidmk" \ + SOONG_MAKEVARS_MK="$makevarsmk" \ + TARGET_BUILD_VARIANT="$TARGET_BUILD_VARIANT" \ + TARGET_DEVICE_DIR="$target_device_dir" \ + TARGET_PRODUCT=${TARGET_PRODUCT} \ + TMPDIR="$PWD/$out/soong/.temp"