123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- #!/usr/bin/env python3
- # Copyright 2023 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 script is a wrapper around the siso binary that is pulled to
- third_party as part of gclient sync. It will automatically find the siso
- binary when run inside a gclient source tree, so users can just type
- "siso" on the command line."""
- import os
- import signal
- import shutil
- import subprocess
- import sys
- import gclient_paths
- def checkOutdir(args):
- subcmd = ''
- out_dir = "."
- for i, arg in enumerate(args):
- if not arg.startswith("-") and not subcmd:
- subcmd = arg
- continue
- if arg == "-C":
- out_dir = args[i + 1]
- elif arg.startswith("-C"):
- out_dir = arg[2:]
- if subcmd != "ninja":
- return
- ninja_marker = os.path.join(out_dir, ".ninja_deps")
- if os.path.exists(ninja_marker):
- print("depot_tools/siso.py: %s contains Ninja state file.\n"
- "Use `autoninja` to use reclient,\n"
- "or run `gn clean %s` to switch from ninja to siso\n" %
- (out_dir, out_dir),
- file=sys.stderr)
- sys.exit(1)
- def _is_google_corp_machine():
- """This assumes that corp machine has gcert binary in known location."""
- return shutil.which("gcert") is not None
- def main(args):
- # Do not raise KeyboardInterrupt on SIGINT so as to give siso time to run
- # cleanup tasks. Siso will be terminated immediately after the second
- # Ctrl-C.
- original_sigint_handler = signal.getsignal(signal.SIGINT)
- def _ignore(signum, frame):
- try:
- # Call the original signal handler.
- original_sigint_handler(signum, frame)
- except KeyboardInterrupt:
- # Do not reraise KeyboardInterrupt so as to not kill siso too early.
- pass
- signal.signal(signal.SIGINT, _ignore)
- if not sys.platform.startswith('win'):
- signal.signal(signal.SIGTERM, lambda signum, frame: None)
- # On Windows the siso.bat script passes along the arguments enclosed in
- # double quotes. This prevents multiple levels of parsing of the special '^'
- # characters needed when compiling a single file. When this case is
- # detected, we need to split the argument. This means that arguments
- # containing actual spaces are not supported by siso.bat, but that is not a
- # real limitation.
- if sys.platform.startswith('win') and len(args) == 2:
- args = args[:1] + args[1].split()
- # macOS's python sets CPATH, LIBRARY_PATH, SDKROOT implicitly.
- # https://openradar.appspot.com/radar?id=5608755232243712
- #
- # Removing those environment variables to avoid affecting clang's behaviors.
- if sys.platform == 'darwin':
- os.environ.pop("CPATH", None)
- os.environ.pop("LIBRARY_PATH", None)
- os.environ.pop("SDKROOT", None)
- # if user doesn't set PYTHONPYCACHEPREFIX and PYTHONDONTWRITEBYTECODE
- # set PYTHONDONTWRITEBYTECODE=1 not to create many *.pyc in workspace
- # and keep workspace clean.
- if not os.environ.get("PYTHONPYCACHEPREFIX"):
- os.environ.setdefault("PYTHONDONTWRITEBYTECODE", "1")
- environ = os.environ.copy()
- # Get gclient root + src.
- primary_solution_path = gclient_paths.GetPrimarySolutionPath()
- gclient_root_path = gclient_paths.FindGclientRoot(os.getcwd())
- gclient_src_root_path = None
- if gclient_root_path:
- gclient_src_root_path = os.path.join(gclient_root_path, 'src')
- siso_override_path = os.environ.get('SISO_PATH')
- if siso_override_path:
- print('depot_tools/siso.py: Using Siso binary from SISO_PATH: %s.' %
- siso_override_path,
- file=sys.stderr)
- if not os.path.isfile(siso_override_path):
- print(
- 'depot_tools/siso.py: Could not find Siso at provided '
- 'SISO_PATH.',
- file=sys.stderr)
- return 1
- for base_path in set(
- [primary_solution_path, gclient_root_path, gclient_src_root_path]):
- if not base_path:
- continue
- env = environ.copy()
- sisoenv_path = os.path.join(base_path, 'build', 'config', 'siso',
- '.sisoenv')
- if not os.path.exists(sisoenv_path):
- continue
- with open(sisoenv_path) as f:
- for line in f.readlines():
- k, v = line.rstrip().split('=', 1)
- env[k] = v
- backend_config_dir = os.path.join(base_path, 'build', 'config', 'siso',
- 'backend_config')
- if os.path.exists(backend_config_dir) and not os.path.exists(
- os.path.join(backend_config_dir, 'backend.star')):
- if _is_google_corp_machine():
- print(
- 'build/config/siso/backend_config/backend.star does not '
- 'exist.\n'
- 'backend.star is configured by gclient hook '
- 'build/config/siso/configure_siso.py.\n'
- 'Make sure `rbe_instance` gclient custom vars is correct.\n'
- 'Did you run `gclient runhooks` ?',
- file=sys.stderr)
- else:
- print(
- 'build/config/siso/backend_config/backend.star does not '
- 'exist.\n'
- 'See build/config/siso/backend_config/README.md',
- file=sys.stderr)
- return 1
- siso_paths = [
- siso_override_path,
- os.path.join(base_path, 'third_party', 'siso', 'cipd',
- 'siso' + gclient_paths.GetExeSuffix()),
- os.path.join(base_path, 'third_party', 'siso',
- 'siso' + gclient_paths.GetExeSuffix()),
- ]
- for siso_path in siso_paths:
- if siso_path and os.path.isfile(siso_path):
- checkOutdir(args[1:])
- return subprocess.call([siso_path] + args[1:], env=env)
- print(
- 'depot_tools/siso.py: Could not find siso in third_party/siso '
- 'of the current project. Did you run gclient sync?',
- file=sys.stderr)
- return 1
- if siso_override_path:
- return subprocess.call([siso_override_path] + args[1:])
- print(
- 'depot_tools/siso.py: Could not find .sisoenv under build/config/siso '
- 'of the current project. Did you run gclient sync?',
- file=sys.stderr)
- return 1
- if __name__ == '__main__':
- sys.exit(main(sys.argv))
|