|
|
|
#!/usr/bin/env python3
|
|
|
|
# Copyright 2022 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 ninja binary that is pulled to
|
|
|
|
third_party as part of gclient sync. It will automatically find the ninja
|
|
|
|
binary when run inside a gclient source tree, so users can just type
|
|
|
|
"ninja" on the command line."""
|
|
|
|
|
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
|
|
|
|
import gclient_paths
|
|
|
|
|
|
|
|
DEPOT_TOOLS_ROOT = os.path.abspath(os.path.dirname(__file__))
|
|
|
|
|
|
|
|
|
|
|
|
def fallbackToLegacyNinja(ninja_args):
|
|
|
|
print(
|
|
|
|
'depot_tools/ninja.py: Fallback to a deprecated legacy ninja binary. '
|
|
|
|
'Note that this ninja binary will be removed soon.\n'
|
|
|
|
'Please install ninja to your project using DEPS. '
|
|
|
|
'If your project does not have DEPS, Please install ninja in your PATH.\n'
|
|
|
|
'See also https://crbug.com/1340825',
|
|
|
|
file=sys.stderr)
|
|
|
|
|
|
|
|
exe_name = ''
|
|
|
|
if sys.platform == 'linux':
|
|
|
|
exe_name = 'ninja-linux64'
|
|
|
|
elif sys.platform == 'darwin':
|
|
|
|
exe_name = 'ninja-mac'
|
|
|
|
elif sys.platform in ['win32', 'cygwin']:
|
|
|
|
exe_name = 'ninja.exe'
|
|
|
|
else:
|
|
|
|
print('depot_tools/ninja.py: %s is not supported platform' % sys.platform)
|
|
|
|
return 1
|
|
|
|
|
|
|
|
ninja_path = os.path.join(DEPOT_TOOLS_ROOT, exe_name)
|
|
|
|
return subprocess.call([ninja_path] + ninja_args)
|
|
|
|
|
|
|
|
|
|
|
|
def findNinjaInPath():
|
|
|
|
env_path = os.getenv('PATH')
|
|
|
|
if not env_path:
|
|
|
|
return
|
|
|
|
exe = 'ninja'
|
|
|
|
if sys.platform in ['win32', 'cygwin']:
|
|
|
|
exe += '.exe'
|
|
|
|
for bin_dir in env_path.split(os.pathsep):
|
|
|
|
if bin_dir.rstrip(os.sep).endswith('depot_tools'):
|
|
|
|
# skip depot_tools to avoid calling ninja.py infitely.
|
|
|
|
continue
|
|
|
|
ninja_path = os.path.join(bin_dir, exe)
|
|
|
|
if os.path.isfile(ninja_path):
|
|
|
|
return ninja_path
|
|
|
|
|
|
|
|
|
|
|
|
def fallback(ninja_args):
|
|
|
|
# Try to find ninja in PATH.
|
|
|
|
ninja_path = findNinjaInPath()
|
|
|
|
if ninja_path:
|
|
|
|
return subprocess.call([ninja_path] + ninja_args)
|
|
|
|
|
|
|
|
# TODO(crbug.com/1340825): remove raw binaries from depot_tools.
|
|
|
|
return fallbackToLegacyNinja(ninja_args)
|
|
|
|
|
|
|
|
|
|
|
|
def main(args):
|
|
|
|
# On Windows the ninja.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 ninja.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 thoese 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)
|
|
|
|
|
|
|
|
# Get gclient root + src.
|
|
|
|
primary_solution_path = gclient_paths.GetPrimarySolutionPath()
|
|
|
|
gclient_root_path = gclient_paths.FindGclientRoot(os.getcwd())
|
|
|
|
for base_path in [primary_solution_path, gclient_root_path]:
|
|
|
|
if not base_path:
|
|
|
|
continue
|
|
|
|
ninja_path = os.path.join(base_path, 'third_party', 'ninja',
|
|
|
|
'ninja' + gclient_paths.GetExeSuffix())
|
|
|
|
if os.path.isfile(ninja_path):
|
|
|
|
return subprocess.call([ninja_path] + args[1:])
|
|
|
|
|
|
|
|
return fallback(args[1:])
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
Do not show python stack trace in ninja.py when KeyboardInterrupt happens
Before
```
❯ ninja -C out/Default
ninja: Entering directory `out/Default'
Traceback (most recent call last):
File "/Users/jwata/depot_tools/ninja.py", line 85, in <module>
sys.exit(main(sys.argv))
File "/Users/jwata/depot_tools/ninja.py", line 79, in main
return subprocess.call([ninja_path] + args[1:])
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 351, in call
return p.wait(timeout=timeout)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 1189, in wait
return self._wait(timeout=timeout)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 1917, in _wait
(pid, sts) = self._try_wait(0)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 1875, in _try_wait
(pid, sts) = os.waitpid(self.pid, wait_flags)
KeyboardInterrupt
```
After
```
❯ ninja -C out/Default
ninja: Entering directory `out/Default'
interrupted
```
Fixed: 1398687
Change-Id: I7cbc80f2214d46b492c6e9ade7b0d78766a8a6f7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/4085366
Reviewed-by: Nico Weber <thakis@chromium.org>
Auto-Submit: Junji Watanabe <jwata@google.com>
Commit-Queue: Junji Watanabe <jwata@google.com>
2 years ago
|
|
|
try:
|
|
|
|
sys.exit(main(sys.argv))
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
sys.exit(1)
|