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 15 import os 16 import re 17 import tempfile 18 import subprocess 19 20 _env = dict(os.environ) 21 22 def _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. 41 def _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 78 def _get_build_var(var_name): 79 return _dump_many_vars(var_name) 80 81 def _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 90 def get_env(key): 91 return _env.get(key) 92 93 def _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 106 ANDROID_BUILD_TOP = _get_android_build_top() 107 108 # Compiling with jack? Possible values in (True, False, 'default') 109 ANDROID_COMPILE_WITH_JACK = _get_build_var_boolean('ANDROID_COMPILE_WITH_JACK', 'default') 110 111 # Follow the build system's D8 usage. 112 USE_D8_BY_DEFAULT = _get_build_var_boolean('USE_D8_BY_DEFAULT', False) 113 114 # Directory used for temporary test files on the host. 115 ART_HOST_TEST_DIR = tempfile.mkdtemp(prefix = 'test-art-') 116 117 # Keep going after encountering a test failure? 118 ART_TEST_KEEP_GOING = _getEnvBoolean('ART_TEST_KEEP_GOING', True) 119 120 # Do you want failed tests to have their artifacts cleaned up? 121 ART_TEST_RUN_TEST_ALWAYS_CLEAN = _getEnvBoolean('ART_TEST_RUN_TEST_ALWAYS_CLEAN', True) 122 123 ART_TEST_BISECTION = _getEnvBoolean('ART_TEST_BISECTION', False) 124 125 DEX2OAT_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? 128 ART_TEST_RUN_TEST_2ND_ARCH = _getEnvBoolean('ART_TEST_RUN_TEST_2ND_ARCH', True) 129 130 HOST_2ND_ARCH_PREFIX = _get_build_var('HOST_2ND_ARCH_PREFIX') 131 HOST_2ND_ARCH_PREFIX_DEX2OAT_HOST_INSTRUCTION_SET_FEATURES = _env.get( 132 HOST_2ND_ARCH_PREFIX + 'DEX2OAT_HOST_INSTRUCTION_SET_FEATURES') 133 134 ART_TEST_ANDROID_ROOT = _env.get('ART_TEST_ANDROID_ROOT') 135 136 ART_TEST_WITH_STRACE = _getEnvBoolean('ART_TEST_DEBUG_GC', False) 137 138 EXTRA_DISABLED_TESTS = set(_env.get("ART_TEST_RUN_TEST_SKIP", "").split()) 139 140 ART_TEST_RUN_TEST_BUILD = _getEnvBoolean('ART_TEST_RUN_TEST_BUILD', False) 141 142 TARGET_2ND_ARCH = _get_build_var('TARGET_2ND_ARCH') 143 TARGET_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 149 if 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 = "" 156 else: 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 164 HOST_PREFER_32_BIT = _get_build_var('HOST_PREFER_32_BIT') 165 if HOST_PREFER_32_BIT == "true": 166 ART_PHONY_TEST_HOST_SUFFIX = "32" 167 ART_2ND_PHONY_TEST_HOST_SUFFIX = "" 168 else: 169 ART_PHONY_TEST_HOST_SUFFIX = "64" 170 ART_2ND_PHONY_TEST_HOST_SUFFIX = "32" 171 172 HOST_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. 176 for 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 180 ANDROID_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. 184 os.environ['PATH'] = ANDROID_JAVA_TOOLCHAIN + ':' + os.environ['PATH'] 185