2022-01-06 03:32:48 +03:00
|
|
|
#!/usr/bin/env python3
|
2013-04-04 18:42:28 +04:00
|
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
|
|
|
import os
|
2022-01-06 03:32:49 +03:00
|
|
|
import platform
|
2013-04-04 18:42:28 +04:00
|
|
|
import sys
|
2023-03-09 13:53:16 +03:00
|
|
|
import subprocess
|
2022-01-06 03:32:49 +03:00
|
|
|
from textwrap import dedent
|
2013-04-04 18:42:28 +04:00
|
|
|
|
2023-03-09 13:53:16 +03:00
|
|
|
MIN_PYTHON_VERSION = (3, 7)
|
|
|
|
MAX_PYTHON_VERSION_TO_CONSIDER = (3, 11)
|
|
|
|
|
2019-08-27 06:08:08 +03:00
|
|
|
|
2021-09-03 23:46:21 +03:00
|
|
|
def load_mach(dir_path, mach_path):
|
2022-01-06 03:32:49 +03:00
|
|
|
# Defer import of "importlib.util" until after Python version check has happened
|
|
|
|
# so that Python 2 usages fail gracefully.
|
2021-09-03 23:46:21 +03:00
|
|
|
import importlib.util
|
2021-09-03 23:46:22 +03:00
|
|
|
spec = importlib.util.spec_from_file_location('mach_initialize', mach_path)
|
|
|
|
mach_initialize = importlib.util.module_from_spec(spec)
|
|
|
|
spec.loader.exec_module(mach_initialize)
|
|
|
|
return mach_initialize.initialize(dir_path)
|
2013-04-04 18:42:28 +04:00
|
|
|
|
2014-07-03 02:15:31 +04:00
|
|
|
|
2015-04-24 22:12:50 +03:00
|
|
|
def check_and_get_mach(dir_path):
|
2021-09-03 23:46:22 +03:00
|
|
|
initialize_paths = (
|
2021-11-29 21:34:58 +03:00
|
|
|
# Run Thunderbird's mach_initialize.py if it exists
|
|
|
|
'comm/build/mach_initialize.py',
|
2021-09-03 23:46:22 +03:00
|
|
|
'build/mach_initialize.py',
|
|
|
|
# test package initialize
|
|
|
|
'tools/mach_initialize.py',
|
2015-05-01 19:20:55 +03:00
|
|
|
)
|
2021-09-03 23:46:22 +03:00
|
|
|
for initialize_path in initialize_paths:
|
|
|
|
mach_path = os.path.join(dir_path, initialize_path)
|
2015-05-01 19:20:55 +03:00
|
|
|
if os.path.isfile(mach_path):
|
|
|
|
return load_mach(dir_path, mach_path)
|
2015-04-24 22:12:50 +03:00
|
|
|
return None
|
2014-07-03 02:15:31 +04:00
|
|
|
|
2015-05-01 19:20:55 +03:00
|
|
|
|
2023-03-09 13:53:16 +03:00
|
|
|
def try_alternate_python3_executables(args):
|
|
|
|
for i in range(MIN_PYTHON_VERSION[1], MAX_PYTHON_VERSION_TO_CONSIDER[1] + 1):
|
|
|
|
try:
|
|
|
|
potential_python_binary = f"python3.{i}"
|
|
|
|
if os.name == 'nt':
|
|
|
|
potential_python_binary += ".exe"
|
|
|
|
|
|
|
|
out = subprocess.run(
|
|
|
|
[potential_python_binary, "--version"],
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE,
|
|
|
|
encoding="UTF-8")
|
|
|
|
|
|
|
|
binary_minor_version = int(out.stdout[9:11].strip("."))
|
|
|
|
|
|
|
|
if binary_minor_version >= MIN_PYTHON_VERSION[1]:
|
|
|
|
print(f"We found '{potential_python_binary}' and will attempt to re-run Mach with it.")
|
|
|
|
os.execvp(potential_python_binary, [potential_python_binary] + ["mach"] + args)
|
|
|
|
|
|
|
|
except Exception:
|
|
|
|
# We don't really care what goes wrong, just don't let it bubble up
|
|
|
|
# If we can't successfully launch with a different python3 binary
|
|
|
|
# we will just print the normal help messages.
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2015-04-24 22:12:50 +03:00
|
|
|
def main(args):
|
2023-03-04 04:21:57 +03:00
|
|
|
# Ensure we are running Python 3.7+. We run this check as soon as
|
2022-01-06 03:32:49 +03:00
|
|
|
# possible to avoid a cryptic import/usage error.
|
2023-03-09 13:53:16 +03:00
|
|
|
if sys.version_info < MIN_PYTHON_VERSION:
|
|
|
|
print(f"Python {MIN_PYTHON_VERSION[0]}.{MIN_PYTHON_VERSION[1]}+ is required to run mach.")
|
|
|
|
print("You are running Mach with Python {0}".format(platform.python_version()))
|
|
|
|
try_alternate_python3_executables(args)
|
2022-01-06 03:32:49 +03:00
|
|
|
if sys.platform.startswith("linux"):
|
|
|
|
print(dedent("""
|
|
|
|
See https://firefox-source-docs.mozilla.org/setup/linux_build.html#installingpython
|
|
|
|
for guidance on how to install Python on your system.
|
|
|
|
""").strip())
|
|
|
|
elif sys.platform.startswith("darwin"):
|
|
|
|
print(dedent("""
|
|
|
|
See https://firefox-source-docs.mozilla.org/setup/macos_build.html
|
|
|
|
for guidance on how to prepare your system to build Firefox. Perhaps
|
|
|
|
you need to update Xcode, or install Python using brew?
|
|
|
|
""").strip())
|
2022-01-06 09:49:47 +03:00
|
|
|
elif "MOZILLABUILD" in os.environ and os.environ.get("TERM"):
|
2022-01-06 03:32:49 +03:00
|
|
|
print(dedent("""
|
|
|
|
Python is provided by MozillaBuild; ensure your MozillaBuild installation is
|
|
|
|
up to date. See https://firefox-source-docs.mozilla.org/setup/windows_build.html#install-mozillabuild
|
|
|
|
for details.
|
|
|
|
""").strip())
|
2022-01-06 09:49:47 +03:00
|
|
|
elif sys.platform.startswith("win"):
|
|
|
|
print(dedent("""
|
|
|
|
You probably want to be interacting with Mach from within MozillaBuild, see
|
|
|
|
https://firefox-source-docs.mozilla.org/setup/windows_build.html for details.
|
|
|
|
|
|
|
|
If you are deliberately using Mach from outside MozillaBuild, then see
|
|
|
|
https://firefox-source-docs.mozilla.org/mach/windows-usage-outside-mozillabuild.html#install-python
|
|
|
|
for guidance on installing native Python on your system.
|
|
|
|
""").strip())
|
2022-01-06 03:32:49 +03:00
|
|
|
else:
|
|
|
|
print(dedent("""
|
|
|
|
We do not have specific instructions for your platform on how to
|
|
|
|
install Python. You may find Pyenv (https://github.com/pyenv/pyenv)
|
|
|
|
helpful, if your system package manager does not provide a way to
|
|
|
|
install a recent enough Python 3.
|
|
|
|
""").strip())
|
|
|
|
sys.exit(1)
|
|
|
|
|
2021-01-20 19:27:09 +03:00
|
|
|
# XCode python sets __PYVENV_LAUNCHER__, which overrides the executable
|
|
|
|
# used when a python subprocess is created. This is an issue when we want
|
|
|
|
# to run using our virtualenv python executables.
|
|
|
|
# In future Python relases, __PYVENV_LAUNCHER__ will be cleared before
|
|
|
|
# application code (mach) is started.
|
|
|
|
# https://github.com/python/cpython/pull/9516
|
|
|
|
os.environ.pop("__PYVENV_LAUNCHER__", None)
|
|
|
|
|
2021-01-21 04:39:56 +03:00
|
|
|
mach = check_and_get_mach(os.path.dirname(os.path.realpath(__file__)))
|
2015-04-24 22:12:50 +03:00
|
|
|
if not mach:
|
|
|
|
print('Could not run mach: No mach source directory found.')
|
|
|
|
sys.exit(1)
|
|
|
|
sys.exit(mach.run(args))
|
2013-10-11 23:44:15 +04:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2014-07-03 02:15:31 +04:00
|
|
|
main(sys.argv[1:])
|