blob: 7dd0dbd6910a2d9cd718e4975218c71424f212b5 [file] [log] [blame]
Junji Watanabe1f67d552022-11-18 00:53:50 +00001#!/usr/bin/env python3
2# Copyright 2022 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5"""This script is a wrapper around the ninja binary that is pulled to
6third_party as part of gclient sync. It will automatically find the ninja
7binary when run inside a gclient source tree, so users can just type
8"ninja" on the command line."""
9
10import os
11import subprocess
12import sys
13
14import gclient_paths
15
Junji Watanabe1f67d552022-11-18 00:53:50 +000016
17def findNinjaInPath():
Takuto Ikutadf3e5772023-11-16 07:14:49 +000018 env_path = os.getenv("PATH")
Mike Frysinger124bb8e2023-09-06 05:48:55 +000019 if not env_path:
20 return
Takuto Ikutadf3e5772023-11-16 07:14:49 +000021 exe = "ninja"
22 if sys.platform in ("win32", "cygwin"):
23 exe += ".exe"
Mike Frysinger124bb8e2023-09-06 05:48:55 +000024 for bin_dir in env_path.split(os.pathsep):
Takuto Ikutadf3e5772023-11-16 07:14:49 +000025 if bin_dir.rstrip(os.sep).endswith("depot_tools"):
Junji Watanabec5505882023-09-25 01:32:45 +000026 # skip depot_tools to avoid calling ninja.py infinitely.
Mike Frysinger124bb8e2023-09-06 05:48:55 +000027 continue
28 ninja_path = os.path.join(bin_dir, exe)
29 if os.path.isfile(ninja_path):
30 return ninja_path
Junji Watanabe1f67d552022-11-18 00:53:50 +000031
32
33def fallback(ninja_args):
Mike Frysinger124bb8e2023-09-06 05:48:55 +000034 # Try to find ninja in PATH.
35 ninja_path = findNinjaInPath()
36 if ninja_path:
37 return subprocess.call([ninja_path] + ninja_args)
Junji Watanabe1f67d552022-11-18 00:53:50 +000038
Mike Frysinger124bb8e2023-09-06 05:48:55 +000039 print(
Takuto Ikutadf3e5772023-11-16 07:14:49 +000040 "depot_tools/ninja.py: Could not find Ninja in the third_party of "
41 "the current project, nor in your PATH.\n"
42 "Please take one of the following actions to install Ninja:\n"
43 "- If your project has DEPS, add a CIPD Ninja dependency to DEPS.\n"
44 "- Otherwise, add Ninja to your PATH *after* depot_tools.",
45 file=sys.stderr,
46 )
Mike Frysinger124bb8e2023-09-06 05:48:55 +000047 return 1
Junji Watanabe1f67d552022-11-18 00:53:50 +000048
49
50def main(args):
Mike Frysinger124bb8e2023-09-06 05:48:55 +000051 # On Windows the ninja.bat script passes along the arguments enclosed in
52 # double quotes. This prevents multiple levels of parsing of the special '^'
53 # characters needed when compiling a single file. When this case is
54 # detected, we need to split the argument. This means that arguments
55 # containing actual spaces are not supported by ninja.bat, but that is not a
56 # real limitation.
Takuto Ikutadf3e5772023-11-16 07:14:49 +000057 if sys.platform.startswith("win") and len(args) == 2:
Mike Frysinger124bb8e2023-09-06 05:48:55 +000058 args = args[:1] + args[1].split()
Junji Watanabe2b1aa8d2023-01-10 02:20:13 +000059
Mike Frysinger124bb8e2023-09-06 05:48:55 +000060 # macOS's python sets CPATH, LIBRARY_PATH, SDKROOT implicitly.
61 # https://openradar.appspot.com/radar?id=5608755232243712
62 #
63 # Removing those environment variables to avoid affecting clang's behaviors.
Takuto Ikutadf3e5772023-11-16 07:14:49 +000064 if sys.platform == "darwin":
Mike Frysinger124bb8e2023-09-06 05:48:55 +000065 os.environ.pop("CPATH", None)
66 os.environ.pop("LIBRARY_PATH", None)
67 os.environ.pop("SDKROOT", None)
Junji Watanabe3e7206f2023-01-11 02:33:26 +000068
Mike Frysinger124bb8e2023-09-06 05:48:55 +000069 # Get gclient root + src.
70 primary_solution_path = gclient_paths.GetPrimarySolutionPath()
71 gclient_root_path = gclient_paths.FindGclientRoot(os.getcwd())
72 gclient_src_root_path = None
73 if gclient_root_path:
Takuto Ikutadf3e5772023-11-16 07:14:49 +000074 gclient_src_root_path = os.path.join(gclient_root_path, "src")
Shelley Vohr106754b2023-02-01 11:59:40 +000075
Mike Frysinger124bb8e2023-09-06 05:48:55 +000076 for base_path in set(
77 [primary_solution_path, gclient_root_path, gclient_src_root_path]):
78 if not base_path:
79 continue
Takuto Ikutadf3e5772023-11-16 07:14:49 +000080 ninja_path = os.path.join(
81 base_path,
82 "third_party",
83 "ninja",
84 "ninja" + gclient_paths.GetExeSuffix(),
85 )
Mike Frysinger124bb8e2023-09-06 05:48:55 +000086 if os.path.isfile(ninja_path):
87 return subprocess.call([ninja_path] + args[1:])
Junji Watanabe1f67d552022-11-18 00:53:50 +000088
Mike Frysinger124bb8e2023-09-06 05:48:55 +000089 return fallback(args[1:])
Junji Watanabe1f67d552022-11-18 00:53:50 +000090
91
Takuto Ikutadf3e5772023-11-16 07:14:49 +000092if __name__ == "__main__":
Mike Frysinger124bb8e2023-09-06 05:48:55 +000093 try:
94 sys.exit(main(sys.argv))
95 except KeyboardInterrupt:
96 sys.exit(1)