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