1# Copyright 2015 the V8 project authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5from __future__ import print_function 6 7import sys 8import os 9import itertools 10import re 11 12try: 13 from exceptions import RuntimeError 14except ImportError: 15 pass 16 17 18def GetNinjaOutputDirectory(v8_root, configuration=None): 19 """Returns <v8_root>/<output_dir>/(Release|Debug|<other>). 20 21 The configuration chosen is the one most recently generated/built, but can be 22 overriden via the <configuration> parameter. Detects a custom output_dir 23 specified by GYP_GENERATOR_FLAGS.""" 24 25 output_dirs = [] 26 27 generator_flags = os.getenv('GYP_GENERATOR_FLAGS', '').split(' ') 28 for flag in generator_flags: 29 name_value = flag.split('=', 1) 30 if (len(name_value) == 2 and name_value[0] == 'output_dir' and 31 os.path.isdir(os.path.join(v8_root, name_value[1]))): 32 output_dirs = [name_value[1]] 33 34 if configuration: 35 output_dir = 'out' if len(output_dirs) == 0 else output_dirs[-1] 36 return os.path.join(os.path.join(v8_root, output_dir), configuration) 37 38 if not output_dirs: 39 for f in os.listdir(v8_root): 40 if re.match(r'out(\b|_)', f): 41 if os.path.isdir(os.path.join(v8_root, f)): 42 output_dirs.append(f) 43 44 def generate_paths(): 45 for out_dir in output_dirs: 46 out_path = os.path.join(v8_root, out_dir) 47 for config in os.listdir(out_path): 48 path = os.path.join(out_path, config) 49 if os.path.exists(os.path.join(path, 'build.ninja')): 50 yield path 51 52 def approx_directory_mtime(path): 53 # This is a heuristic; don't recurse into subdirectories. 54 paths = [path] + [os.path.join(path, f) for f in os.listdir(path)] 55 return max(filter(None, [safe_mtime(p) for p in paths])) 56 57 def safe_mtime(path): 58 try: 59 return os.path.getmtime(path) 60 except OSError: 61 return None 62 63 try: 64 return max(generate_paths(), key=approx_directory_mtime) 65 except ValueError: 66 raise RuntimeError('Unable to find a valid ninja output directory.') 67 68 69if __name__ == '__main__': 70 if len(sys.argv) != 2: 71 raise RuntimeError('Expected a single path argument.') 72 print(GetNinjaOutputDirectory(sys.argv[1])) 73