blob: cd418691f3ab243020b6416fd3318386634709c2 [file] [log] [blame]
#!/usr/bin/env python3
"""Runs the bazel executable for the platform, passing args along."""
import os
import os.path
import platform as plat
import re
import subprocess
import sys
import multiprocessing
def main():
workspace = find_workspace(os.path.dirname(os.path.realpath(__file__)))
if not workspace:
sys.exit('Must run %s within a workspace.' % os.path.basename(sys.argv[0]))
print_bazelrc_deprecation_warning(workspace)
if sys.platform.startswith('linux'):
platform = 'linux-x86_64'
elif sys.platform == 'darwin':
platform = 'darwin-arm64' if plat.machine() == 'arm64' else 'darwin-x86_64'
elif sys.platform == 'win32':
platform = 'windows-x86_64'
else:
sys.exit('Platform %s is not yet supported.' % sys.platform)
env = {}
env['USE_BAZEL_VERSION'] = os.environ.get('USE_BAZEL_VERSION', '5.1.1')
bazel = os.path.join(workspace, 'prebuilts', 'tools', platform, 'bazel',
'bazelisk')
args = sys.argv[1:]
command = bazel_command(args)
env['TERM'] = os.environ.get('TERM', '')
env['MAVEN_FETCH'] = os.environ.get('MAVEN_FETCH', '')
env['SHELL'] = os.environ.get('SHELL', '')
env['HOME'] = os.environ.get('HOME', '')
env['DISPLAY'] = os.environ.get('DISPLAY', '')
env['GOOGLE_APPLICATION_CREDENTIALS'] = os.environ.get('GOOGLE_APPLICATION_CREDENTIALS', '')
env['PATH'] = os.environ.get('PATH','')
if 'QA_ANDROID_SDK_ROOT' in os.environ:
env['QA_ANDROID_SDK_ROOT'] = os.environ['QA_ANDROID_SDK_ROOT']
if sys.platform == 'darwin':
if not os.path.exists('/Library/Developer/CommandLineTools'):
print('/Library/Developer/CommandLineTools does not exist. Please install it with '
'xcode-select --install')
sys.exit(1)
# This is needed for bazel to set itself up, even though we aren't using gcc.
env['CC'] = os.environ.get('GCC', '/usr/bin/gcc')
elif sys.platform == 'win32':
# We don't need the tools to be installed locally if you're building remotely.
# This isn't really the correct check, since --config=remote is just an alias for a bunch of other
# settings. But in practice that's how you get into remote mode, so it should be good enough for now
# at least.
if (command in ['build', 'test'] and
(not '--config=remote' in args and not '--config=dynamic' in args and not '--config=ci' in args)):
if (not os.path.exists('C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.26.28801') or
not os.path.exists('C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.18362.0')):
print('You must have MSVC Buildtools version 14.26.28801 and Windows SDK 10.0.18362.0 installed.\n'
'An installer for these is available at go/studio-msvc-tools.')
sys.exit(1)
define_env(env, 'BAZEL_SH', 'C:\\tools\\msys64\\usr\\bin\\bash.exe',
'***NOTE***: Bazel for Windows currently hardcodes "C:\\tools\\msys64", but we\n' +
'could not find an installation of msys at this path on your machine.\n' +
'Move your installation there if you already have it or\n' +
'install it there from http://www.msys2.org.\n' +
'Make sure to change the path to C:\\tools\\msys64\n' +
'\n' +
'See also: https://github.com/bazelbuild/bazel/issues/2447')
# Bazel for windows requires a couple of extra env vars be set
# SYSTEMROOT must be defined to run a win .exe; otherwise, subprocess.call
# will hang.
env['SYSTEMROOT'] = 'C:\\Windows'
env['TMP'] = os.environ.get('TMP','')
env['USERPROFILE'] = os.environ.get('USERPROFILE', '')
env['APPDATA'] = os.environ.get('APPDATA', '')
env['LOCALAPPDATA'] = os.environ.get('LOCALAPPDATA', '')
else: # Linux
env['CC'] = os.environ.get('GCC', '/usr/bin/gcc')
bazelrc_arg = '--bazelrc=%s' % os.path.join(workspace, 'tools',
'base', 'bazel',
'toplevel.bazelrc')
sys.exit(subprocess.call([bazel, bazelrc_arg] + args, env=env))
def print_bazelrc_deprecation_warning(workspace):
bazelrc = os.path.join(workspace, '.bazelrc')
user_bazelrc = os.path.join(workspace, 'user.bazelrc')
if os.path.exists(bazelrc):
print('''WARNING: You have a .bazelrc file located at: %s
This file will soon be overwritten by an update to the repo manifest!
To continue using a user-specific .bazelrc, please move the .bazelrc
file to user.bazelrc with the following command:
mv %s %s
''' % (bazelrc, bazelrc, user_bazelrc))
sys.exit(1)
def define_env(env, var, value, msg=None):
prev = os.environ.get(var)
if prev:
if not os.path.exists(value):
print('{} is set to {}, but it does not exist'.format(var, value))
sys.exit(1)
env[var] = prev
elif os.path.exists(value):
env[var] = value
else:
print('Cannot find {} while trying to set "{}"'.format(value, var))
if msg:
print(msg)
else:
print('Make sure {} exists, or set "{}" manually to the correct value.'.format(value, var))
sys.exit(1)
def find_workspace(path):
if os.path.isfile(os.path.join(path, 'WORKSPACE')):
return path
else:
parent = os.path.dirname(path)
return None if parent == path else find_workspace(parent)
"""
Returns the command index, which is the first non-option argument.
https://bazel.build/versions/master/docs/command-line-reference.html
"""
def bazel_command_index(args):
for i in range(len(args)):
if not args[i].startswith('-'):
return i
return None
"""
Returns the command itself, or None if not defined.
"""
def bazel_command(args):
index = bazel_command_index(args)
if index is None:
return None
return args[index]
if __name__ == '__main__':
main()