1# Copyright 2017, The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import os 16import re 17import tempfile 18import subprocess 19 20_env = dict(os.environ) 21 22def _getEnvBoolean(var, default): 23 val = _env.get(var) 24 if val: 25 if val == "True" or val == "true": 26 return True 27 if val == "False" or val == "false": 28 return False 29 return default 30 31_DUMP_MANY_VARS_LIST = ['HOST_2ND_ARCH_PREFIX', 32 'TARGET_2ND_ARCH', 33 'TARGET_ARCH', 34 'HOST_PREFER_32_BIT', 35 'HOST_OUT_EXECUTABLES', 36 'ANDROID_JAVA_TOOLCHAIN', 37 'ANDROID_COMPILE_WITH_JACK', 38 'USE_D8_BY_DEFAULT'] 39_DUMP_MANY_VARS = None # To be set to a dictionary with above list being the keys, 40 # and the build variable being the value. 41def _dump_many_vars(var_name): 42 """ 43 Reach into the Android build system to dump many build vars simultaneously. 44 Since the make system is so slow, we want to avoid calling into build frequently. 45 """ 46 global _DUMP_MANY_VARS 47 global _DUMP_MANY_VARS_LIST 48 49 # Look up var from cache. 50 if _DUMP_MANY_VARS: 51 return _DUMP_MANY_VARS[var_name] 52 53 all_vars=" ".join(_DUMP_MANY_VARS_LIST) 54 55 # The command is taken from build/envsetup.sh to fetch build variables. 56 command = ("build/soong/soong_ui.bash --dumpvars-mode --vars=\"%s\"") % (all_vars) 57 58 config = subprocess.Popen(command, 59 stdout=subprocess.PIPE, 60 universal_newlines=True, 61 shell=True, 62 cwd=ANDROID_BUILD_TOP).communicate()[0] # read until EOF, select stdin 63 # Prints out something like: 64 # TARGET_ARCH='arm64' 65 # HOST_ARCH='x86_64' 66 _DUMP_MANY_VARS = {} 67 for line in config.split("\n"): 68 # Split out "$key='$value'" via regex. 69 match = re.search("([^=]+)='([^']*)", line) 70 if not match: 71 continue 72 key = match.group(1) 73 value = match.group(2) 74 _DUMP_MANY_VARS[key] = value 75 76 return _DUMP_MANY_VARS[var_name] 77 78def _get_build_var(var_name): 79 return _dump_many_vars(var_name) 80 81def _get_build_var_boolean(var, default): 82 val = _get_build_var(var) 83 if val: 84 if val == "True" or val == "true": 85 return True 86 if val == "False" or val == "false": 87 return False 88 return default 89 90def get_env(key): 91 return _env.get(key) 92 93def _get_android_build_top(): 94 path_to_top = _env.get('ANDROID_BUILD_TOP') 95 if not path_to_top: 96 # nothing set. try to guess it based on the relative path of this env.py file. 97 this_file_path = os.path.realpath(__file__) 98 path_to_top = os.path.join(os.path.dirname(this_file_path), '../../../') 99 path_to_top = os.path.realpath(path_to_top) 100 101 if not os.path.exists(os.path.join(path_to_top, 'build/envsetup.sh')): 102 raise AssertionError("env.py must be located inside an android source tree") 103 104 return path_to_top 105 106ANDROID_BUILD_TOP = _get_android_build_top() 107 108# Compiling with jack? Possible values in (True, False, 'default') 109ANDROID_COMPILE_WITH_JACK = _get_build_var_boolean('ANDROID_COMPILE_WITH_JACK', 'default') 110 111# Follow the build system's D8 usage. 112USE_D8_BY_DEFAULT = _get_build_var_boolean('USE_D8_BY_DEFAULT', False) 113 114# Directory used for temporary test files on the host. 115ART_HOST_TEST_DIR = tempfile.mkdtemp(prefix = 'test-art-') 116 117# Keep going after encountering a test failure? 118ART_TEST_KEEP_GOING = _getEnvBoolean('ART_TEST_KEEP_GOING', True) 119 120# Do you want failed tests to have their artifacts cleaned up? 121ART_TEST_RUN_TEST_ALWAYS_CLEAN = _getEnvBoolean('ART_TEST_RUN_TEST_ALWAYS_CLEAN', True) 122 123ART_TEST_BISECTION = _getEnvBoolean('ART_TEST_BISECTION', False) 124 125DEX2OAT_HOST_INSTRUCTION_SET_FEATURES = _env.get('DEX2OAT_HOST_INSTRUCTION_SET_FEATURES') 126 127# Do you want run-tests with the host/target's second arch? 128ART_TEST_RUN_TEST_2ND_ARCH = _getEnvBoolean('ART_TEST_RUN_TEST_2ND_ARCH', True) 129 130HOST_2ND_ARCH_PREFIX = _get_build_var('HOST_2ND_ARCH_PREFIX') 131HOST_2ND_ARCH_PREFIX_DEX2OAT_HOST_INSTRUCTION_SET_FEATURES = _env.get( 132 HOST_2ND_ARCH_PREFIX + 'DEX2OAT_HOST_INSTRUCTION_SET_FEATURES') 133 134ART_TEST_ANDROID_ROOT = _env.get('ART_TEST_ANDROID_ROOT') 135 136ART_TEST_WITH_STRACE = _getEnvBoolean('ART_TEST_DEBUG_GC', False) 137 138EXTRA_DISABLED_TESTS = set(_env.get("ART_TEST_RUN_TEST_SKIP", "").split()) 139 140ART_TEST_RUN_TEST_BUILD = _getEnvBoolean('ART_TEST_RUN_TEST_BUILD', False) 141 142TARGET_2ND_ARCH = _get_build_var('TARGET_2ND_ARCH') 143TARGET_ARCH = _get_build_var('TARGET_ARCH') 144 145# Note: ART_2ND_PHONY_TEST_TARGET_SUFFIX is 2ND_ART_PHONY_TEST_TARGET_SUFFIX in .mk files 146# Note: ART_2ND_PHONY_TEST_HOST_SUFFIX is 2ND_ART_PHONY_HOST_TARGET_SUFFIX in .mk files 147# Python does not let us have variable names starting with a digit, so it has differ. 148 149if TARGET_2ND_ARCH: 150 if "64" in TARGET_ARCH: 151 ART_PHONY_TEST_TARGET_SUFFIX = "64" 152 ART_2ND_PHONY_TEST_TARGET_SUFFIX = "32" 153 else: 154 ART_PHONY_TEST_TARGET_SUFFIX = "32" 155 ART_2ND_PHONY_TEST_TARGET_SUFFIX = "" 156else: 157 if "64" in TARGET_ARCH: 158 ART_PHONY_TEST_TARGET_SUFFIX = "64" 159 ART_2ND_PHONY_TEST_TARGET_SUFFIX = "" 160 else: 161 ART_PHONY_TEST_TARGET_SUFFIX = "32" 162 ART_2ND_PHONY_TEST_TARGET_SUFFIX = "" 163 164HOST_PREFER_32_BIT = _get_build_var('HOST_PREFER_32_BIT') 165if HOST_PREFER_32_BIT == "true": 166 ART_PHONY_TEST_HOST_SUFFIX = "32" 167 ART_2ND_PHONY_TEST_HOST_SUFFIX = "" 168else: 169 ART_PHONY_TEST_HOST_SUFFIX = "64" 170 ART_2ND_PHONY_TEST_HOST_SUFFIX = "32" 171 172HOST_OUT_EXECUTABLES = os.path.join(ANDROID_BUILD_TOP, 173 _get_build_var("HOST_OUT_EXECUTABLES")) 174 175# Set up default values for $JACK, $DX, $SMALI, etc to the $HOST_OUT_EXECUTABLES/$name path. 176for tool in ['jack', 'dx', 'smali', 'jasmin', 'dxmerger']: 177 binary = tool if tool != 'dxmerger' else 'dexmerger' 178 os.environ.setdefault(tool.upper(), HOST_OUT_EXECUTABLES + '/' + binary) 179 180ANDROID_JAVA_TOOLCHAIN = os.path.join(ANDROID_BUILD_TOP, 181 _get_build_var('ANDROID_JAVA_TOOLCHAIN')) 182 183# include platform prebuilt java, javac, etc in $PATH. 184os.environ['PATH'] = ANDROID_JAVA_TOOLCHAIN + ':' + os.environ['PATH'] 185