#!/usr/bin/env python3 # 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/. from __future__ import absolute_import, print_function, unicode_literals import os import platform import sys from textwrap import dedent def load_mach(dir_path, mach_path): # Defer import of "importlib.util" until after Python version check has happened # so that Python 2 usages fail gracefully. import importlib.util 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) def check_and_get_mach(dir_path): initialize_paths = ( # Run Thunderbird's mach_initialize.py if it exists 'comm/build/mach_initialize.py', 'build/mach_initialize.py', # test package initialize 'tools/mach_initialize.py', ) for initialize_path in initialize_paths: mach_path = os.path.join(dir_path, initialize_path) if os.path.isfile(mach_path): return load_mach(dir_path, mach_path) return None def main(args): # Ensure we are running Python 3.6+. We run this check as soon as # possible to avoid a cryptic import/usage error. if sys.version_info < (3, 6): print("Python 3.6+ is required to run mach.") print("You are running Python", platform.python_version()) 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()) elif "MOZILLABUILD" in os.environ and os.environ.get("TERM"): 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()) 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()) 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) if sys.version_info >= (3, 10) and sys.platform.startswith("darwin"): version = f"{sys.version_info[0]}.{sys.version_info[1]}" if f"python@{version}" in sys.executable: print(dedent(f""" You are using python {version} from homebrew. There is a bug in virtualenv that prevents us from starting up mach in that situation. Please uninstall it with the following and try again: brew unlink python@{version} If you need python {version} later, you can re-link it with: brew link python@{version} """).strip()) sys.exit(1) # 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) mach = check_and_get_mach(os.path.dirname(os.path.realpath(__file__))) if not mach: print('Could not run mach: No mach source directory found.') sys.exit(1) sys.exit(mach.run(args)) if __name__ == '__main__': main(sys.argv[1:])