1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/mach_bootstrap.py Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,199 @@ 1.4 +# This Source Code Form is subject to the terms of the Mozilla Public 1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.7 + 1.8 +from __future__ import print_function, unicode_literals 1.9 + 1.10 +import os 1.11 +import platform 1.12 +import sys 1.13 +import time 1.14 + 1.15 + 1.16 +STATE_DIR_FIRST_RUN = ''' 1.17 +mach and the build system store shared state in a common directory on the 1.18 +filesystem. The following directory will be created: 1.19 + 1.20 + {userdir} 1.21 + 1.22 +If you would like to use a different directory, hit CTRL+c and set the 1.23 +MOZBUILD_STATE_PATH environment variable to the directory you would like to 1.24 +use and re-run mach. For this change to take effect forever, you'll likely 1.25 +want to export this environment variable from your shell's init scripts. 1.26 +'''.lstrip() 1.27 + 1.28 + 1.29 +# TODO Bug 794506 Integrate with the in-tree virtualenv configuration. 1.30 +SEARCH_PATHS = [ 1.31 + 'python/mach', 1.32 + 'python/mozboot', 1.33 + 'python/mozbuild', 1.34 + 'python/mozversioncontrol', 1.35 + 'python/blessings', 1.36 + 'python/configobj', 1.37 + 'python/jsmin', 1.38 + 'python/psutil', 1.39 + 'python/which', 1.40 + 'build/pymake', 1.41 + 'config', 1.42 + 'dom/bindings', 1.43 + 'dom/bindings/parser', 1.44 + 'other-licenses/ply', 1.45 + 'xpcom/idl-parser', 1.46 + 'testing', 1.47 + 'testing/xpcshell', 1.48 + 'testing/marionette/client', 1.49 + 'testing/marionette/client/marionette', 1.50 + 'testing/marionette/transport', 1.51 + 'testing/mozbase/mozcrash', 1.52 + 'testing/mozbase/mozdevice', 1.53 + 'testing/mozbase/mozfile', 1.54 + 'testing/mozbase/mozhttpd', 1.55 + 'testing/mozbase/mozlog', 1.56 + 'testing/mozbase/moznetwork', 1.57 + 'testing/mozbase/mozprocess', 1.58 + 'testing/mozbase/mozprofile', 1.59 + 'testing/mozbase/mozrunner', 1.60 + 'testing/mozbase/mozsystemmonitor', 1.61 + 'testing/mozbase/mozinfo', 1.62 + 'testing/mozbase/moztest', 1.63 + 'testing/mozbase/mozversion', 1.64 + 'testing/mozbase/manifestdestiny', 1.65 + 'xpcom/idl-parser', 1.66 +] 1.67 + 1.68 +# Individual files providing mach commands. 1.69 +MACH_MODULES = [ 1.70 + 'addon-sdk/mach_commands.py', 1.71 + 'build/valgrind/mach_commands.py', 1.72 + 'dom/bindings/mach_commands.py', 1.73 + 'layout/tools/reftest/mach_commands.py', 1.74 + 'python/mach_commands.py', 1.75 + 'python/mach/mach/commands/commandinfo.py', 1.76 + 'python/mozboot/mozboot/mach_commands.py', 1.77 + 'python/mozbuild/mozbuild/mach_commands.py', 1.78 + 'python/mozbuild/mozbuild/frontend/mach_commands.py', 1.79 + 'testing/mach_commands.py', 1.80 + 'testing/marionette/mach_commands.py', 1.81 + 'testing/mochitest/mach_commands.py', 1.82 + 'testing/xpcshell/mach_commands.py', 1.83 + 'testing/talos/mach_commands.py', 1.84 + 'testing/xpcshell/mach_commands.py', 1.85 + 'tools/docs/mach_commands.py', 1.86 + 'tools/mercurial/mach_commands.py', 1.87 + 'tools/mach_commands.py', 1.88 +] 1.89 + 1.90 + 1.91 +CATEGORIES = { 1.92 + 'build': { 1.93 + 'short': 'Build Commands', 1.94 + 'long': 'Interact with the build system', 1.95 + 'priority': 80, 1.96 + }, 1.97 + 'post-build': { 1.98 + 'short': 'Post-build Commands', 1.99 + 'long': 'Common actions performed after completing a build.', 1.100 + 'priority': 70, 1.101 + }, 1.102 + 'testing': { 1.103 + 'short': 'Testing', 1.104 + 'long': 'Run tests.', 1.105 + 'priority': 60, 1.106 + }, 1.107 + 'devenv': { 1.108 + 'short': 'Development Environment', 1.109 + 'long': 'Set up and configure your development environment.', 1.110 + 'priority': 50, 1.111 + }, 1.112 + 'build-dev': { 1.113 + 'short': 'Low-level Build System Interaction', 1.114 + 'long': 'Interact with specific parts of the build system.', 1.115 + 'priority': 20, 1.116 + }, 1.117 + 'misc': { 1.118 + 'short': 'Potpourri', 1.119 + 'long': 'Potent potables and assorted snacks.', 1.120 + 'priority': 10, 1.121 + }, 1.122 + 'disabled': { 1.123 + 'short': 'Disabled', 1.124 + 'long': 'These commands are unavailable for your current context, run "mach <command>" to see why.', 1.125 + 'priority': 0, 1.126 + } 1.127 +} 1.128 + 1.129 + 1.130 +def bootstrap(topsrcdir, mozilla_dir=None): 1.131 + if mozilla_dir is None: 1.132 + mozilla_dir = topsrcdir 1.133 + 1.134 + # Ensure we are running Python 2.7+. We put this check here so we generate a 1.135 + # user-friendly error message rather than a cryptic stack trace on module 1.136 + # import. 1.137 + if sys.version_info[0] != 2 or sys.version_info[1] < 7: 1.138 + print('Python 2.7 or above (but not Python 3) is required to run mach.') 1.139 + print('You are running Python', platform.python_version()) 1.140 + sys.exit(1) 1.141 + 1.142 + # Global build system and mach state is stored in a central directory. By 1.143 + # default, this is ~/.mozbuild. However, it can be defined via an 1.144 + # environment variable. We detect first run (by lack of this directory 1.145 + # existing) and notify the user that it will be created. The logic for 1.146 + # creation is much simpler for the "advanced" environment variable use 1.147 + # case. For default behavior, we educate users and give them an opportunity 1.148 + # to react. We always exit after creating the directory because users don't 1.149 + # like surprises. 1.150 + try: 1.151 + import mach.main 1.152 + except ImportError: 1.153 + sys.path[0:0] = [os.path.join(mozilla_dir, path) for path in SEARCH_PATHS] 1.154 + import mach.main 1.155 + 1.156 + def populate_context(context, key=None): 1.157 + if key is None: 1.158 + return 1.159 + if key == 'state_dir': 1.160 + state_user_dir = os.path.expanduser('~/.mozbuild') 1.161 + state_env_dir = os.environ.get('MOZBUILD_STATE_PATH', None) 1.162 + if state_env_dir: 1.163 + if not os.path.exists(state_env_dir): 1.164 + print('Creating global state directory from environment variable: %s' 1.165 + % state_env_dir) 1.166 + os.makedirs(state_env_dir, mode=0o770) 1.167 + print('Please re-run mach.') 1.168 + sys.exit(1) 1.169 + state_dir = state_env_dir 1.170 + else: 1.171 + if not os.path.exists(state_user_dir): 1.172 + print(STATE_DIR_FIRST_RUN.format(userdir=state_user_dir)) 1.173 + try: 1.174 + for i in range(20, -1, -1): 1.175 + time.sleep(1) 1.176 + sys.stdout.write('%d ' % i) 1.177 + sys.stdout.flush() 1.178 + except KeyboardInterrupt: 1.179 + sys.exit(1) 1.180 + 1.181 + print('\nCreating default state directory: %s' % state_user_dir) 1.182 + os.mkdir(state_user_dir) 1.183 + print('Please re-run mach.') 1.184 + sys.exit(1) 1.185 + state_dir = state_user_dir 1.186 + 1.187 + return state_dir 1.188 + if key == 'topdir': 1.189 + return topsrcdir 1.190 + raise AttributeError(key) 1.191 + 1.192 + mach = mach.main.Mach(os.getcwd()) 1.193 + mach.populate_context_handler = populate_context 1.194 + 1.195 + for category, meta in CATEGORIES.items(): 1.196 + mach.define_category(category, meta['short'], meta['long'], 1.197 + meta['priority']) 1.198 + 1.199 + for path in MACH_MODULES: 1.200 + mach.load_commands_from_file(os.path.join(mozilla_dir, path)) 1.201 + 1.202 + return mach