blob: d4b7ea2d6262228ada18a5465c33582ac737ed98 [file] [log] [blame]
# -*- coding: utf-8 -*-
# Copyright 2016 WebAssembly Community Group participants
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import os
import sys
import proc
import work_dirs
force_host_clang = True
use_sysroot = True
def SetupToolchain():
return [
sys.executable,
os.path.join(work_dirs.GetV8(), 'build', 'toolchain', 'win',
'setup_toolchain.py')
]
def VSToolchainPy():
return [
sys.executable,
os.path.join(work_dirs.GetV8(), 'build', 'vs_toolchain.py')
]
def WinToolchainJson():
return os.path.join(work_dirs.GetV8(), 'build', 'win_toolchain.json')
def GetPrebuiltClang(binary):
return os.path.join(work_dirs.GetV8(), 'third_party', 'llvm-build',
'Release+Asserts', 'bin', binary)
def SyncPrebuiltClang(src_dir):
"""Update the prebuilt clang toolchain used by chromium bots"""
tools_clang = os.path.join(src_dir, 'tools', 'clang')
assert os.path.isdir(tools_clang)
proc.check_call([os.path.join(tools_clang, 'scripts', 'update.py')])
def SyncWinToolchain():
"""Update the VS toolchain used by Chromium bots"""
proc.check_call(VSToolchainPy() + ['update'])
def GetVSEnv(dir):
"""Return the configured VS build environment block as a python dict."""
# The format is a list of nul-terminated strings of the form var=val
# where 'var' is the environment variable name, and 'val' is its value
env = os.environ.copy()
with open(os.path.join(dir, 'environment.x64'), 'rb') as f:
entries = f.read().decode().split('\0')
for e in entries:
if not e:
continue
var, val = e.split('=', 1)
env[var] = val
print('ENV: %s = %s' % (var, val))
return env
def SetUpVSEnv(outdir):
"""Set up the VS build environment used by Chromium bots"""
# Get the chromium-packaged toolchain directory info in a JSON file
proc.check_call(VSToolchainPy() + ['get_toolchain_dir'])
with open(WinToolchainJson()) as f:
paths = json.load(f)
# Write path information (usable by a non-chromium build) into an
# environment block
runtime_dirs = os.pathsep.join(paths['runtime_dirs'])
proc.check_call(SetupToolchain() +
[paths['path'], paths['win_sdk'], runtime_dirs, 'win',
'x64', 'environment.x64'],
cwd=outdir)
# Recent versions of CMake use lib.exe to create archives. We need LLVM's
# lib to use LTO, but it's not included in Chrome's packaging. lld-link
# can be used as lib.exe (via the /lib flag) but CMake can't be forced to
# inject the extra flag into every invocation. So we create a wrapper script
# to replace lib.exe and redirect to lld-link with the extra flag.
lld = GetPrebuiltClang('lld-link.exe')
batch = f'''
@echo off
{lld} /lib %*
'''
with open(GetPrebuiltClang('lib.bat'), 'w') as f:
f.write(batch)
return GetVSEnv(outdir)
def UsingGoma():
return 'GOMA_DIR' in os.environ
def UsingReclient():
return 'USE_RECLIENT' in os.environ and not sys.platform == 'darwin'
def ReclientDir():
return os.path.join(work_dirs.GetV8(), 'buildtools', 'reclient')
def RewrapperCfg(platform):
return os.path.join(work_dirs.GetV8(),
'buildtools',
'reclient_cfgs',
'chromium-browser-clang',
f'rewrapper_{platform}.cfg')
def ParseConfigLine(line):
line = line.strip()
if not len(line) or line.startswith('#'):
return None
parts = line.split('=', 1)
parts[0].lstrip('-')
return (parts[0], True if len(parts) == 1 else parts[1])
def SetReclientEnv(host_platform):
exec_root = work_dirs.GetExecRoot()
os.environ['RBE_exec_root'] = exec_root
# Reclient's canonicalize working_dir feature doesn't work with CMake's absolute paths.
os.environ['RBE_canonicalize_working_dir'] = 'False'
os.environ['RBE_env_var_allowlist'] = 'INCLUDE,LIB,LIBPATH'
rewrapper_cfg = RewrapperCfg(host_platform)
if not os.path.exists(rewrapper_cfg):
return
rbe_platform = ''
with open(rewrapper_cfg) as f:
for line in f.readlines():
flag = ParseConfigLine(line)
if flag and flag[0] == 'platform':
rbe_platform = flag[1]
break
if not rbe_platform or 'InputRootAbsolutePath' in rbe_platform:
return
os.environ[
'RBE_platform'] = f'{rbe_platform},InputRootAbsolutePath={exec_root}'
def GomaDir():
return os.environ['GOMA_DIR']
def CMakeLauncherFlags(host_platform):
flags = []
if UsingReclient():
compiler_launcher = ';'.join([
os.path.join(ReclientDir(), 'rewrapper'),
f'-cfg={RewrapperCfg(host_platform)}'])
elif UsingGoma():
compiler_launcher = os.path.join(GomaDir(), 'gomacc')
else:
try:
compiler_launcher = proc.Which('ccache')
except: # noqa
return flags
if ShouldForceHostClang():
# This flag is only present in clang.
flags.extend([
'-DCMAKE_%s_FLAGS=-Qunused-arguments' % c
for c in ['C', 'CXX']
])
flags.extend([
'-DCMAKE_%s_COMPILER_LAUNCHER=%s' % (c, compiler_launcher)
for c in ['C', 'CXX']
])
return flags
def NinjaJobs():
if force_host_clang:
if UsingGoma():
return ['-j', '50']
elif UsingReclient():
return ['-j', '150']
return []
def SetForceHostClang(force):
global force_host_clang
force_host_clang = force
def ShouldForceHostClang():
return force_host_clang
def SetUseSysroot(use):
global use_sysroot
use_sysroot = use
def ShouldUseSysroot():
return use_sysroot