#!/bin/bash # # Copyright (C) 2018 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # !!! Keep up-to-date with var_cache.py # # # Provide a soong-build variable query mechanism that is cached # in the current process and any other subchild process that knows # how to parse the exported variable: # # export ART_TOOLS_BUILD_VAR_CACHE="..." # # Of the format: # # =''\n # =''\n # ... # ='' # # Note: This is intentionally the same output format as # build/soong/soong_ui.bash --dumpvars-mode --vars "key1 key2 ... keyN" # # For example, this would be a valid var-cache: # # export ART_TOOLS_BUILD_VAR_CACHE="ART_APEX_JARS='core-oj core-libart'" # # Calling into soong repeatedly is very slow; whenever it needs to be done # more than once, the var_cache.py or var_cache.sh script should be used instead. # # ------------------------------------------------------- # Echoes the result of get_build_var . # Var lookup is cached, subsequent var lookups in any child process # (that includes a var-cache is free). The var must be in 'var_list' # to participate in the cache. # # Example: # local host_out="$(get_build_var HOST_OUT)" # # Note that build vars can often have spaces in them, # so the caller must take care to ensure space-correctness. get_build_var() { local var_name="$1" _var_cache_populate _var_cache_build_dict if [[ ${_VAR_CACHE_DICT[$var_name]+exists} ]]; then echo "${_VAR_CACHE_DICT[$var_name]}" return 0 else echo "[ERROR] get_build_var: The variable '$var_name' is not in 'var_list', can't lookup." >&2 return 1 fi } # The above functions are "public" and are intentionally not exported. # User scripts must have "source var_cache.sh" to take advantage of caching. # ------------------------------------------------------- # Below functions are "private"; # do not call them outside of this file. _var_cache_populate() { if [[ -n $ART_TOOLS_BUILD_VAR_CACHE ]]; then _var_cache_debug "ART_TOOLS_BUILD_VAR_CACHE preset to (quotes added)..." _var_cache_debug \""$ART_TOOLS_BUILD_VAR_CACHE"\" return 0 fi _var_cache_debug "Varcache missing... repopulate" local this_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" local top="$this_dir/../../.." local interesting_vars=() while read -r line; do if [[ -z $line ]] || [[ $line == '#'* ]]; then continue; fi interesting_vars+=($line) done < "$this_dir"/var_list _var_cache_debug "Interesting vars: " ${interesting_vars[@]} local flat_vars="${interesting_vars[*]}" local var_values _var_cache_show_command "$top"/build/soong/soong_ui.bash --dumpvars-mode -vars=\"${interesting_vars[*]}\" # Invoke soong exactly once for optimal performance. # soong_ui.bash must be invoked from $ANDROID_BUILD_TOP or it gets confused and breaks. var_values="$(cd "$top" && "$top"/build/soong/soong_ui.bash --dumpvars-mode -vars="$flat_vars")" # Export the ART_TOOLS_BUILD_VAR_CACHE in the same format as soong_ui.bash --dumpvars-mode. export ART_TOOLS_BUILD_VAR_CACHE="$var_values" _var_cache_debug ART_TOOLS_BUILD_VAR_CACHE=\"$var_values\" } _var_cache_build_dict() { if [[ ${#_VAR_CACHE_DICT[@]} -ne 0 ]]; then # Associative arrays cannot be exported, have # a separate step to reconstruct the associative # array from a flat variable. return 0 fi # Parse $ART_TOOLS_BUILD_VAR_CACHE, e.g. # ART_APEX_JARS='core-oj core-libart conscrypt okhttp bouncycastle apache-xml' local var_name local var_value local strip_quotes _var_cache_debug "_var_cache_build_dict()" declare -g -A _VAR_CACHE_DICT # global associative array. while IFS='=' read -r var_name var_value; do if [[ -z $var_name ]]; then # skip empty lines, e.g. blank newline at the end continue fi _var_cache_debug "Var_name was $var_name" _var_cache_debug "Var_value was $var_value" strip_quotes=${var_value//\'/} _VAR_CACHE_DICT["$var_name"]="$strip_quotes" done < <(echo "$ART_TOOLS_BUILD_VAR_CACHE") _var_cache_debug ${#_VAR_CACHE_DICT[@]} -eq 0 } _var_cache_debug() { if ((_var_cache_debug_enabled)); then echo "[DBG]: " "$@" >&2 fi } _var_cache_show_command() { if (( _var_cache_show_commands || _var_cache_debug_enabled)); then echo "$@" >&2 fi } while true; do case $1 in --help) echo "Usage: $0 [--debug] [--show-commands] [--dump-cache] [--var ] [--var ...]" echo "" echo "Exposes a function 'get_build_var' which returns the result of" echo "a soong build variable." echo "" echo "Primarily intended to be used as 'source var_cache.sh'," echo "but also allows interactive command line usage for simplifying development." exit 0 ;; --var) echo -ne "$2=" get_build_var "$2" shift ;; --debug) _var_cache_debug_enabled=1 ;; --show-commands) _var_cache_show_commands=1 ;; --dump-cache) _var_cache_populate echo "ART_TOOLS_BUILD_VAR_CACHE=\"$ART_TOOLS_BUILD_VAR_CACHE\"" ;; *) break ;; esac shift done