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="ART_APEX_JARS='core-oj core-libart'" 41# 42# Calling into soong repeatedly is very slow; whenever it needs to be done 43# more than once, the var_cache.py or var_cache.sh script should be used instead. 44# 45 46# ------------------------------------------------------- 47 48# Echoes the result of get_build_var <var_name>. 49# Var lookup is cached, subsequent var lookups in any child process 50# (that includes a var-cache is free). The var must be in 'var_list' 51# to participate in the cache. 52# 53# Example: 54# local host_out="$(get_build_var HOST_OUT)" 55# 56# Note that build vars can often have spaces in them, 57# so the caller must take care to ensure space-correctness. 58get_build_var() { 59 local var_name="$1" 60 61 _var_cache_populate 62 _var_cache_build_dict 63 64 if [[ ${_VAR_CACHE_DICT[$var_name]+exists} ]]; then 65 echo "${_VAR_CACHE_DICT[$var_name]}" 66 return 0 67 else 68 echo "[ERROR] get_build_var: The variable '$var_name' is not in 'var_list', can't lookup." >&2 69 return 1 70 fi 71} 72 73# The above functions are "public" and are intentionally not exported. 74# User scripts must have "source var_cache.sh" to take advantage of caching. 75 76# ------------------------------------------------------- 77# Below functions are "private"; 78# do not call them outside of this file. 79 80_var_cache_populate() { 81 if [[ -n $ART_TOOLS_BUILD_VAR_CACHE ]]; then 82 _var_cache_debug "ART_TOOLS_BUILD_VAR_CACHE preset to (quotes added)..." 83 _var_cache_debug \""$ART_TOOLS_BUILD_VAR_CACHE"\" 84 return 0 85 fi 86 87 _var_cache_debug "Varcache missing... repopulate" 88 89 local this_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 90 local top="$this_dir/../../.." 91 92 local interesting_vars=() 93 while read -r line; do 94 if [[ -z $line ]] || [[ $line == '#'* ]]; then 95 continue; 96 fi 97 interesting_vars+=($line) 98 done < "$this_dir"/var_list 99 100 _var_cache_debug "Interesting vars: " ${interesting_vars[@]} 101 102 local flat_vars="${interesting_vars[*]}" 103 104 local var_values 105 _var_cache_show_command "$top"/build/soong/soong_ui.bash --dumpvars-mode -vars=\"${interesting_vars[*]}\" 106 107 # Invoke soong exactly once for optimal performance. 108 # soong_ui.bash must be invoked from $ANDROID_BUILD_TOP or it gets confused and breaks. 109 var_values="$(cd "$top" && "$top"/build/soong/soong_ui.bash --dumpvars-mode -vars="$flat_vars")" 110 111 # Export the ART_TOOLS_BUILD_VAR_CACHE in the same format as soong_ui.bash --dumpvars-mode. 112 export ART_TOOLS_BUILD_VAR_CACHE="$var_values" 113 114 _var_cache_debug ART_TOOLS_BUILD_VAR_CACHE=\"$var_values\" 115} 116 117_var_cache_build_dict() { 118 if [[ ${#_VAR_CACHE_DICT[@]} -ne 0 ]]; then 119 # Associative arrays cannot be exported, have 120 # a separate step to reconstruct the associative 121 # array from a flat variable. 122 return 0 123 fi 124 125 # Parse $ART_TOOLS_BUILD_VAR_CACHE, e.g. 126 # ART_APEX_JARS='core-oj core-libart conscrypt okhttp bouncycastle apache-xml' 127 128 local var_name 129 local var_value 130 local strip_quotes 131 132 _var_cache_debug "_var_cache_build_dict()" 133 134 declare -g -A _VAR_CACHE_DICT # global associative array. 135 while IFS='=' read -r var_name var_value; do 136 if [[ -z $var_name ]]; then 137 # skip empty lines, e.g. blank newline at the end 138 continue 139 fi 140 _var_cache_debug "Var_name was $var_name" 141 _var_cache_debug "Var_value was $var_value" 142 strip_quotes=${var_value//\'/} 143 _VAR_CACHE_DICT["$var_name"]="$strip_quotes" 144 done < <(echo "$ART_TOOLS_BUILD_VAR_CACHE") 145 146 _var_cache_debug ${#_VAR_CACHE_DICT[@]} -eq 0 147} 148 149_var_cache_debug() { 150 if ((_var_cache_debug_enabled)); then 151 echo "[DBG]: " "$@" >&2 152 fi 153} 154 155_var_cache_show_command() { 156 if (( _var_cache_show_commands || _var_cache_debug_enabled)); then 157 echo "$@" >&2 158 fi 159} 160 161while true; do 162 case $1 in 163 --help) 164 echo "Usage: $0 [--debug] [--show-commands] [--dump-cache] [--var <name>] [--var <name2>...]" 165 echo "" 166 echo "Exposes a function 'get_build_var' which returns the result of" 167 echo "a soong build variable." 168 echo "" 169 echo "Primarily intended to be used as 'source var_cache.sh'," 170 echo "but also allows interactive command line usage for simplifying development." 171 exit 0 172 ;; 173 --var) 174 echo -ne "$2=" 175 get_build_var "$2" 176 shift 177 ;; 178 --debug) 179 _var_cache_debug_enabled=1 180 ;; 181 --show-commands) 182 _var_cache_show_commands=1 183 ;; 184 --dump-cache) 185 _var_cache_populate 186 echo "ART_TOOLS_BUILD_VAR_CACHE=\"$ART_TOOLS_BUILD_VAR_CACHE\"" 187 ;; 188 *) 189 break 190 ;; 191 esac 192 shift 193done 194