ninja_output.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. # Copyright 2014 The Chromium 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. from __future__ import print_function
  5. import sys
  6. import os
  7. import itertools
  8. import re
  9. try:
  10. from exceptions import RuntimeError
  11. except ImportError:
  12. pass
  13. def GetNinjaOutputDirectory(chrome_root):
  14. """Returns <chrome_root>/<output_dir>/(Release|Debug|<other>).
  15. If either of the following environment variables are set, their
  16. value is used to determine the output directory:
  17. 1. CHROMIUM_OUT_DIR environment variable.
  18. 2. GYP_GENERATOR_FLAGS environment variable output_dir property.
  19. Otherwise, all directories starting with the word out are examined.
  20. The configuration chosen is the one most recently generated/built.
  21. """
  22. output_dirs = []
  23. if ('CHROMIUM_OUT_DIR' in os.environ and
  24. os.path.isdir(os.path.join(chrome_root, os.environ['CHROMIUM_OUT_DIR']))):
  25. output_dirs = [os.environ['CHROMIUM_OUT_DIR']]
  26. if not output_dirs:
  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(chrome_root, name_value[1]))):
  32. output_dirs = [name_value[1]]
  33. if not output_dirs:
  34. for f in os.listdir(chrome_root):
  35. if re.match(r'out(\b|_)', f):
  36. if os.path.isdir(os.path.join(chrome_root, f)):
  37. output_dirs.append(f)
  38. def generate_paths():
  39. for out_dir in output_dirs:
  40. out_path = os.path.join(chrome_root, out_dir)
  41. for config in os.listdir(out_path):
  42. path = os.path.join(out_path, config)
  43. if os.path.exists(os.path.join(path, 'build.ninja')):
  44. yield path
  45. def approx_directory_mtime(path):
  46. # This is a heuristic; don't recurse into subdirectories.
  47. paths = [path] + [os.path.join(path, f) for f in os.listdir(path)]
  48. return max(filter(None, [safe_mtime(p) for p in paths]))
  49. def safe_mtime(path):
  50. try:
  51. return os.path.getmtime(path)
  52. except OSError:
  53. return None
  54. try:
  55. return max(generate_paths(), key=approx_directory_mtime)
  56. except ValueError:
  57. raise RuntimeError('Unable to find a valid ninja output directory.')
  58. if __name__ == '__main__':
  59. if len(sys.argv) != 2:
  60. raise RuntimeError('Expected a single path argument.')
  61. print(GetNinjaOutputDirectory(sys.argv[1]))