1#!/bin/bash 2# 3# Copyright (C) 2018 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17# 18# !!! Keep up-to-date with var_cache.py 19# 20 21# 22# Provide a soong-build variable query mechanism that is cached 23# in the current process and any other subchild process that knows 24# how to parse the exported variable: 25# 26# export ART_TOOLS_BUILD_VAR_CACHE="..." 27# 28# Of the format: 29# 30# <key1>='<value1>'\n 31# <key2>='<value2>'\n 32# ... 33# <keyN>='<valueN>' 34# 35# Note: This is intentionally the same output format as 36# build/soong/soong_ui.bash --dumpvars-mode --vars "key1 key2 ... keyN" 37# 38# For example, this would be a valid var-cache: 39# 40# export ART_TOOLS_BUILD_VAR_CACHE="TARGET_CORE_JARS='core-oj core-libart' 41# HOST_CORE_JARS='core-oj-hostdex core-libart-hostdex'" 42# 43# Calling into soong repeatedly is very slow; whenever it needs to be done 44# more than once, the var_cache.py or var_cache.sh script should be used instead. 45# 46 47# ------------------------------------------------------- 48 49# Echoes the result of get_build_var <var_name>. 50# Var lookup is cached, subsequent var lookups in any child process 51# (that includes a var-cache is free). The var must be in 'var_list' 52# to participate in the cache. 53# 54# Example: 55# local host_out="$(get_build_var HOST_OUT)" 56# 57# Note that build vars can often have spaces in them, 58# so the caller must take care to ensure space-correctness. 59get_build_var() { 60 local var_name="$1" 61 62 _var_cache_populate 63 _var_cache_build_dict 64 65 if [[ ${_VAR_CACHE_DICT[$var_name]+exists} ]]; then 66 echo "${_VAR_CACHE_DICT[$var_name]}" 67 return 0 68 else 69 echo "[ERROR] get_build_var: The variable '$var_name' is not in 'var_list', can't lookup." >&2 70 return 1 71 fi 72} 73 74# The above functions are "public" and are intentionally not exported. 75# User scripts must have "source var_cache.sh" to take advantage of caching. 76 77# ------------------------------------------------------- 78# Below functions are "private"; 79# do not call them outside of this file. 80 81_var_cache_populate() { 82 if [[ -n $ART_TOOLS_BUILD_VAR_CACHE ]]; then 83 _var_cache_debug "ART_TOOLS_BUILD_VAR_CACHE preset to (quotes added)..." 84 _var_cache_debug \""$ART_TOOLS_BUILD_VAR_CACHE"\" 85 return 0 86 fi 87 88 _var_cache_debug "Varcache missing... repopulate" 89 90 local this_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 91 local top="$this_dir/../../.." 92 93 local interesting_vars=() 94 while read -r line; do 95 if [[ -z $line ]] || [[ $line == '#'* ]]; then 96 continue; 97 fi 98 interesting_vars+=($line) 99 done < "$this_dir"/var_list 100 101 _var_cache_debug "Interesting vars: " ${interesting_vars[@]} 102 103 local flat_vars="${interesting_vars[*]}" 104 105 local var_values 106 _var_cache_show_command "$top"/build/soong/soong_ui.bash --dumpvars-mode -vars=\"${interesting_vars[*]}\" 107 108 # Invoke soong exactly once for optimal performance. 109 # soong_ui.bash must be invoked from $ANDROID_BUILD_TOP or it gets confused and breaks. 110 var_values="$(cd "$top" && "$top"/build/soong/soong_ui.bash --dumpvars-mode -vars="$flat_vars")" 111 112 # Export the ART_TOOLS_BUILD_VAR_CACHE in the same format as soong_ui.bash --dumpvars-mode. 113 export ART_TOOLS_BUILD_VAR_CACHE="$var_values" 114 115 _var_cache_debug ART_TOOLS_BUILD_VAR_CACHE=\"$var_values\" 116} 117 118_var_cache_build_dict() { 119 if [[ ${#_VAR_CACHE_DICT[@]} -ne 0 ]]; then 120 # Associative arrays cannot be exported, have 121 # a separate step to reconstruct the associative 122 # array from a flat variable. 123 return 0 124 fi 125 126 # Parse $ART_TOOLS_BUILD_VAR_CACHE, e.g. 127 # TARGET_CORE_JARS='core-oj core-libart conscrypt okhttp bouncycastle apache-xml' 128 # HOST_CORE_JARS='core-oj-hostdex core-libart-hostdex ...' 129 130 local var_name 131 local var_value 132 local strip_quotes 133 134 _var_cache_debug "_var_cache_build_dict()" 135 136 declare -g -A _VAR_CACHE_DICT # global associative array. 137 while IFS='=' read -r var_name var_value; do 138 if [[ -z $var_name ]]; then 139 # skip empty lines, e.g. blank newline at the end 140 continue 141 fi 142 _var_cache_debug "Var_name was $var_name" 143 _var_cache_debug "Var_value was $var_value" 144 strip_quotes=${var_value//\'/} 145 _VAR_CACHE_DICT["$var_name"]="$strip_quotes" 146 done < <(echo "$ART_TOOLS_BUILD_VAR_CACHE") 147 148 _var_cache_debug ${#_VAR_CACHE_DICT[@]} -eq 0 149} 150 151_var_cache_debug() { 152 if ((_var_cache_debug_enabled)); then 153 echo "[DBG]: " "$@" >&2 154 fi 155} 156 157_var_cache_show_command() { 158 if (( _var_cache_show_commands || _var_cache_debug_enabled)); then 159 echo "$@" >&2 160 fi 161} 162 163while true; do 164 case $1 in 165 --help) 166 echo "Usage: $0 [--debug] [--show-commands] [--dump-cache] [--var <name>] [--var <name2>...]" 167 echo "" 168 echo "Exposes a function 'get_build_var' which returns the result of" 169 echo "a soong build variable." 170 echo "" 171 echo "Primarily intended to be used as 'source var_cache.sh'," 172 echo "but also allows interactive command line usage for simplifying development." 173 exit 0 174 ;; 175 --var) 176 echo -ne "$2=" 177 get_build_var "$2" 178 shift 179 ;; 180 --debug) 181 _var_cache_debug_enabled=1 182 ;; 183 --show-commands) 184 _var_cache_show_commands=1 185 ;; 186 --dump-cache) 187 _var_cache_populate 188 echo "ART_TOOLS_BUILD_VAR_CACHE=\"$ART_TOOLS_BUILD_VAR_CACHE\"" 189 ;; 190 *) 191 break 192 ;; 193 esac 194 shift 195done 196