123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- # Copyright 2019 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- # This file is imported by various thin wrappers (around gn, clang-format, ...),
- # so it's meant to import very quickly. To keep it that way don't add more
- # code, and even more importantly don't add more toplevel import statements,
- # particularly for modules that are not builtin (see sys.builtin_modules_names,
- # os isn't built in, but it's essential to this file).
- from __future__ import print_function
- import gclient_utils
- import logging
- import os
- import subprocess2
- import sys
- def FindGclientRoot(from_dir, filename='.gclient'):
- """Tries to find the gclient root."""
- real_from_dir = os.path.realpath(from_dir)
- path = real_from_dir
- while not os.path.exists(os.path.join(path, filename)):
- split_path = os.path.split(path)
- if not split_path[1]:
- return None
- path = split_path[0]
- logging.info('Found gclient root at ' + path)
- if path == real_from_dir:
- return path
- # If we did not find the file in the current directory, make sure we are in a
- # sub directory that is controlled by this configuration.
- entries_filename = os.path.join(path, filename + '_entries')
- if not os.path.exists(entries_filename):
- # If .gclient_entries does not exist, a previous call to gclient sync
- # might have failed. In that case, we cannot verify that the .gclient
- # is the one we want to use. In order to not to cause too much trouble,
- # just issue a warning and return the path anyway.
- print(
- "%s missing, %s file in parent directory %s might not be the file "
- "you want to use." % (entries_filename, filename, path),
- file=sys.stderr)
- return path
- entries_content = gclient_utils.FileRead(entries_filename)
- scope = {}
- try:
- exec(entries_content, scope)
- except (SyntaxError, Exception) as e:
- gclient_utils.SyntaxErrorToError(filename, e)
- all_directories = scope['entries'].keys()
- path_to_check = os.path.relpath(real_from_dir, path)
- while path_to_check:
- if path_to_check in all_directories:
- return path
- path_to_check = os.path.dirname(path_to_check)
- return None
- def GetPrimarySolutionPath():
- """Returns the full path to the primary solution. (gclient_root + src)"""
- gclient_root = FindGclientRoot(os.getcwd())
- if gclient_root:
- # Some projects' top directory is not named 'src'.
- source_dir_name = GetGClientPrimarySolutionName(gclient_root) or 'src'
- return os.path.join(gclient_root, source_dir_name)
- # Some projects might not use .gclient. Try to see whether we're in a git
- # checkout that contains a 'buildtools' subdir.
- top_dir = os.getcwd()
- try:
- top_dir = subprocess2.check_output(
- ['git', 'rev-parse', '--show-toplevel'])
- if sys.version_info.major == 3:
- top_dir = top_dir.decode('utf-8', 'replace')
- top_dir = os.path.normpath(top_dir.strip())
- except subprocess2.CalledProcessError:
- pass
- if os.path.exists(os.path.join(top_dir, 'buildtools')):
- return top_dir
- return None
- def GetBuildtoolsPath():
- """Returns the full path to the buildtools directory.
- This is based on the root of the checkout containing the current directory."""
- # Overriding the build tools path by environment is highly unsupported and may
- # break without warning. Do not rely on this for anything important.
- override = os.environ.get('CHROMIUM_BUILDTOOLS_PATH')
- if override is not None:
- return override
- primary_solution = GetPrimarySolutionPath()
- if not primary_solution:
- return None
- buildtools_path = os.path.join(primary_solution, 'buildtools')
- if os.path.exists(buildtools_path):
- return buildtools_path
- # buildtools may be in the gclient root.
- gclient_root = FindGclientRoot(os.getcwd())
- buildtools_path = os.path.join(gclient_root, 'buildtools')
- if os.path.exists(buildtools_path):
- return buildtools_path
- return None
- def GetBuildtoolsPlatformBinaryPath():
- """Returns the full path to the binary directory for the current platform."""
- buildtools_path = GetBuildtoolsPath()
- if not buildtools_path:
- return None
- if sys.platform.startswith(('cygwin', 'win')):
- subdir = 'win'
- elif sys.platform == 'darwin':
- subdir = 'mac'
- elif sys.platform.startswith('linux'):
- subdir = 'linux64'
- else:
- raise gclient_utils.Error('Unknown platform: ' + sys.platform)
- return os.path.join(buildtools_path, subdir)
- def GetExeSuffix():
- """Returns '' or '.exe' depending on how executables work on this platform."""
- if sys.platform.startswith(('cygwin', 'win')):
- return '.exe'
- return ''
- def GetGClientPrimarySolutionName(gclient_root_dir_path):
- """Returns the name of the primary solution in the .gclient file specified."""
- gclient_config_file = os.path.join(gclient_root_dir_path, '.gclient')
- gclient_config_contents = gclient_utils.FileRead(gclient_config_file)
- env = {}
- exec(gclient_config_contents, env)
- solutions = env.get('solutions', [])
- if solutions:
- return solutions[0].get('name')
- return None
|