2018-07-25 04:17:44 -04:00
|
|
|
#!/usr/bin/env python
|
2019-01-21 14:03:30 -05:00
|
|
|
# Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
2018-07-25 04:17:44 -04:00
|
|
|
# This script contains helper functions to work with the third_party subrepo.
|
|
|
|
|
|
|
|
import os
|
2019-09-11 18:22:23 -04:00
|
|
|
import re
|
2018-10-21 21:47:34 -04:00
|
|
|
import site
|
2018-07-25 04:17:44 -04:00
|
|
|
import sys
|
2018-10-21 21:47:34 -04:00
|
|
|
from tempfile import mkdtemp
|
2019-09-12 15:07:21 -04:00
|
|
|
from util import add_env_path, executable_suffix, libdeno_path, make_env, rmtree
|
|
|
|
from util import root_path, run, third_party_path
|
2018-07-25 04:17:44 -04:00
|
|
|
|
2019-09-14 09:01:27 -04:00
|
|
|
depot_tools_path = os.path.join(third_party_path, "depot_tools")
|
|
|
|
prebuilt_path = os.path.join(root_path, "prebuilt")
|
|
|
|
python_packages_path = os.path.join(third_party_path, "python_packages")
|
2018-07-25 04:17:44 -04:00
|
|
|
|
2018-10-21 21:47:34 -04:00
|
|
|
python_site_env = None
|
|
|
|
|
|
|
|
|
|
|
|
# Creates/modifies an environment so python can find packages that are bundled
|
|
|
|
# in the 'third_party' directory.
|
2018-11-30 03:27:41 -05:00
|
|
|
def python_env(env=None, merge_env=None):
|
|
|
|
if merge_env is None:
|
|
|
|
merge_env = {}
|
2018-10-21 21:47:34 -04:00
|
|
|
global python_site_env
|
|
|
|
|
|
|
|
# Use site.addsitedir() to determine which search paths would be considered
|
|
|
|
# if 'third_party/python_packages' was a site-packages directory.
|
|
|
|
# PATH is also updated, so windows can find the DLLs that ship with pywin32.
|
|
|
|
if python_site_env is None:
|
|
|
|
python_site_env = {}
|
|
|
|
temp = os.environ["PATH"], sys.path
|
|
|
|
os.environ["PATH"], sys.path = "", []
|
2019-09-12 15:07:21 -04:00
|
|
|
site.addsitedir(os.path.join(libdeno_path,
|
|
|
|
"build")) # Modifies PATH and sys.path.
|
2018-10-21 21:47:34 -04:00
|
|
|
site.addsitedir(python_packages_path) # Modifies PATH and sys.path.
|
|
|
|
python_site_env = {"PATH": os.environ["PATH"], "PYTHONPATH": sys.path}
|
|
|
|
os.environ["PATH"], sys.path = temp
|
|
|
|
|
|
|
|
# Make a new environment object.
|
|
|
|
env = make_env(env=env, merge_env=merge_env)
|
|
|
|
# Apply PATH and PYTHONPATH from the site-packages environment.
|
|
|
|
add_env_path(python_site_env["PATH"], env=env, key="PATH")
|
|
|
|
add_env_path(python_site_env["PYTHONPATH"], env=env, key="PYTHONPATH")
|
|
|
|
|
|
|
|
return env
|
|
|
|
|
2018-07-25 04:17:44 -04:00
|
|
|
|
|
|
|
# This function creates or modifies an environment so that it matches the
|
|
|
|
# expectations of various google tools (gn, gclient, etc).
|
2018-11-30 03:27:41 -05:00
|
|
|
def google_env(env=None, merge_env=None, depot_tools_path_=depot_tools_path):
|
|
|
|
if merge_env is None:
|
|
|
|
merge_env = {}
|
2018-10-21 21:47:34 -04:00
|
|
|
# Google tools need the python env too.
|
|
|
|
env = python_env(env=env, merge_env=merge_env)
|
|
|
|
|
2018-07-25 04:17:44 -04:00
|
|
|
# Depot_tools to be in the PATH, before Python.
|
2018-11-30 03:27:41 -05:00
|
|
|
add_env_path(depot_tools_path_, env=env, prepend=True)
|
2018-09-09 22:27:58 -04:00
|
|
|
|
|
|
|
if os.name == "nt": # Windows-only enviroment tweaks.
|
|
|
|
# We're not using Google's internal infrastructure.
|
|
|
|
if os.name == "nt" and not "DEPOT_TOOLS_WIN_TOOLCHAIN" in env:
|
|
|
|
env["DEPOT_TOOLS_WIN_TOOLCHAIN"] = "0"
|
|
|
|
|
|
|
|
# The 'setup_toolchain.py' script does a good job finding the Windows
|
|
|
|
# SDK. Unfortunately, if any of the environment variables below are set
|
|
|
|
# (as vcvarsall.bat typically would), setup_toolchain absorbs them too,
|
|
|
|
# adding multiple identical -imsvc<path> items to CFLAGS.
|
|
|
|
# This small variation has no effect on compiler output, but it
|
|
|
|
# makes ninja rebuild everything, and causes sccache cache misses.
|
|
|
|
# TODO(piscisaureus): fix this upstream.
|
|
|
|
env["INCLUDE"] = ""
|
|
|
|
env["LIB"] = ""
|
|
|
|
env["LIBPATH"] = ""
|
|
|
|
|
2018-07-25 04:17:44 -04:00
|
|
|
return env
|
|
|
|
|
|
|
|
|
|
|
|
# Run Yarn to install JavaScript dependencies.
|
|
|
|
def run_yarn():
|
2018-08-15 11:57:07 -04:00
|
|
|
run(["yarn", "install"], cwd=third_party_path)
|
2018-07-25 04:17:44 -04:00
|
|
|
|
|
|
|
|
2018-10-21 21:47:34 -04:00
|
|
|
# Install python packages with pip.
|
|
|
|
def run_pip():
|
|
|
|
# Install an recent version of pip into a temporary directory. The version
|
|
|
|
# that is bundled with python is too old to support the next step.
|
|
|
|
temp_python_home = mkdtemp()
|
|
|
|
pip_env = {"PYTHONUSERBASE": temp_python_home}
|
|
|
|
run([sys.executable, "-m", "pip", "install", "--upgrade", "--user", "pip"],
|
|
|
|
cwd=third_party_path,
|
|
|
|
merge_env=pip_env)
|
|
|
|
|
|
|
|
# Install pywin32.
|
|
|
|
run([
|
|
|
|
sys.executable, "-m", "pip", "install", "--upgrade", "--target",
|
|
|
|
python_packages_path, "--platform=win_amd64", "--only-binary=:all:",
|
|
|
|
"pypiwin32"
|
|
|
|
],
|
|
|
|
cwd=third_party_path,
|
|
|
|
merge_env=pip_env)
|
|
|
|
|
2018-10-23 10:51:54 -04:00
|
|
|
# Get yapf.
|
|
|
|
run([
|
|
|
|
sys.executable, "-m", "pip", "install", "--upgrade", "--target",
|
|
|
|
python_packages_path, "yapf"
|
|
|
|
],
|
|
|
|
cwd=third_party_path,
|
|
|
|
merge_env=pip_env)
|
2019-09-11 16:47:42 -04:00
|
|
|
|
|
|
|
run([
|
|
|
|
sys.executable, "-m", "pip", "install", "--upgrade", "--target",
|
|
|
|
python_packages_path, "pylint==1.5.6"
|
|
|
|
],
|
|
|
|
cwd=third_party_path,
|
|
|
|
merge_env=pip_env)
|
2019-09-14 09:01:27 -04:00
|
|
|
|
2018-10-21 21:47:34 -04:00
|
|
|
# Remove the temporary pip installation.
|
|
|
|
rmtree(temp_python_home)
|
|
|
|
|
|
|
|
|
2018-07-25 04:17:44 -04:00
|
|
|
# Run gclient to install other dependencies.
|
|
|
|
def run_gclient_sync():
|
|
|
|
# Depot_tools will normally try to self-update, which will fail because
|
|
|
|
# it's not checked out from it's own git repository; gclient will then try
|
|
|
|
# to fix things up and not succeed, and and we'll end up with a huge mess.
|
|
|
|
# To work around this, we rename the `depot_tools` directory to
|
|
|
|
# `{root_path}/depot_tools_temp` first, and we set DEPOT_TOOLS_UPDATE=0 in
|
|
|
|
# the environment so depot_tools doesn't attempt to self-update.
|
|
|
|
# Since depot_tools is listed in .gclient_entries, gclient will install a
|
|
|
|
# fresh copy in `third_party/depot_tools`.
|
|
|
|
# If it all works out, we remove the depot_tools_temp directory afterwards.
|
2019-09-14 09:01:27 -04:00
|
|
|
depot_tools_temp_path = os.path.join(root_path, "depot_tools_temp")
|
2018-07-25 04:17:44 -04:00
|
|
|
|
|
|
|
# Rename depot_tools to depot_tools_temp.
|
|
|
|
try:
|
|
|
|
os.rename(depot_tools_path, depot_tools_temp_path)
|
2018-11-30 03:27:41 -05:00
|
|
|
except OSError:
|
2018-07-25 04:17:44 -04:00
|
|
|
# If renaming failed, and the depot_tools_temp directory already exists,
|
|
|
|
# assume that it's still there because a prior run_gclient_sync() call
|
|
|
|
# failed half-way, before we got the chance to remove the temp dir.
|
|
|
|
# We'll use whatever is in the temp dir that was already there.
|
|
|
|
# If not, the user can recover by removing the temp directory manually.
|
2019-09-14 09:01:27 -04:00
|
|
|
if os.path.isdir(depot_tools_temp_path):
|
2018-07-25 04:17:44 -04:00
|
|
|
pass
|
|
|
|
else:
|
|
|
|
raise
|
|
|
|
|
|
|
|
args = [
|
|
|
|
"gclient", "sync", "--reset", "--shallow", "--no-history", "--nohooks"
|
|
|
|
]
|
|
|
|
envs = {
|
2019-09-14 09:01:27 -04:00
|
|
|
"DEPOT_TOOLS_UPDATE": "0",
|
|
|
|
"GCLIENT_FILE": os.path.join(root_path, "gclient_config.py")
|
2018-07-25 04:17:44 -04:00
|
|
|
}
|
2018-11-30 03:27:41 -05:00
|
|
|
env = google_env(depot_tools_path_=depot_tools_temp_path, merge_env=envs)
|
2018-07-25 04:17:44 -04:00
|
|
|
run(args, cwd=third_party_path, env=env)
|
|
|
|
|
|
|
|
# Delete the depot_tools_temp directory, but not before verifying that
|
|
|
|
# gclient did indeed install a fresh copy.
|
|
|
|
# Also check that `{depot_tools_temp_path}/gclient.py` exists, so a typo in
|
|
|
|
# this script won't accidentally blow out someone's home dir.
|
2019-09-14 09:01:27 -04:00
|
|
|
if (os.path.isdir(os.path.join(depot_tools_path, ".git"))
|
|
|
|
and os.path.isfile(os.path.join(depot_tools_path, "gclient.py"))
|
|
|
|
and os.path.isfile(
|
|
|
|
os.path.join(depot_tools_temp_path, "gclient.py"))):
|
2018-07-25 04:17:44 -04:00
|
|
|
rmtree(depot_tools_temp_path)
|
|
|
|
|
|
|
|
|
2019-09-14 09:01:27 -04:00
|
|
|
def get_platform_dir_name():
|
|
|
|
if sys.platform == "win32":
|
|
|
|
return "win"
|
|
|
|
elif sys.platform == "darwin":
|
|
|
|
return "mac"
|
|
|
|
elif sys.platform.startswith("linux"):
|
|
|
|
return "linux64"
|
|
|
|
|
2018-07-25 04:17:44 -04:00
|
|
|
|
2019-09-14 09:01:27 -04:00
|
|
|
def get_prebuilt_tool_path(tool):
|
|
|
|
return os.path.join(prebuilt_path, get_platform_dir_name(),
|
|
|
|
tool + executable_suffix)
|
|
|
|
|
|
|
|
|
2019-09-12 15:07:21 -04:00
|
|
|
def get_buildtools_tool_path(tool):
|
|
|
|
return os.path.join(libdeno_path, "buildtools", get_platform_dir_name(),
|
|
|
|
tool + executable_suffix)
|
|
|
|
|
|
|
|
|
2019-09-14 09:01:27 -04:00
|
|
|
# Download the given item from Google storage.
|
|
|
|
def download_from_google_storage(item, bucket, base_dir):
|
|
|
|
download_script = os.path.join(depot_tools_path,
|
|
|
|
"download_from_google_storage.py")
|
|
|
|
sha1_file = os.path.join(base_dir, get_platform_dir_name(),
|
|
|
|
item + executable_suffix + ".sha1")
|
2018-07-25 04:17:44 -04:00
|
|
|
run([
|
2019-09-14 09:01:28 -04:00
|
|
|
sys.executable,
|
2019-09-14 09:01:27 -04:00
|
|
|
download_script,
|
|
|
|
"--platform=" + sys.platform,
|
|
|
|
"--no_auth",
|
|
|
|
"--bucket=%s" % bucket,
|
|
|
|
"--sha1_file",
|
|
|
|
sha1_file,
|
2018-07-25 04:17:44 -04:00
|
|
|
],
|
|
|
|
env=google_env())
|
|
|
|
|
|
|
|
|
2019-09-11 18:22:23 -04:00
|
|
|
# Download the given item from Chrome Infrastructure Package Deployment.
|
|
|
|
def download_from_cipd(item, version):
|
2019-09-14 09:01:27 -04:00
|
|
|
cipd_exe = os.path.join(depot_tools_path, "cipd")
|
2019-09-12 15:07:21 -04:00
|
|
|
download_dir = os.path.join(libdeno_path, "buildtools",
|
2019-09-14 09:01:27 -04:00
|
|
|
get_platform_dir_name())
|
|
|
|
|
|
|
|
if sys.platform == "win32":
|
2019-09-11 18:22:23 -04:00
|
|
|
item += "windows-amd64"
|
2019-09-14 09:01:27 -04:00
|
|
|
elif sys.platform == "darwin":
|
2019-09-11 18:22:23 -04:00
|
|
|
item += "mac-amd64"
|
2019-09-14 09:01:27 -04:00
|
|
|
elif sys.platform.startswith("linux"):
|
2019-09-11 18:22:23 -04:00
|
|
|
item += "linux-amd64"
|
|
|
|
|
2019-09-14 09:01:27 -04:00
|
|
|
# Init cipd if necessary.
|
|
|
|
if not os.path.exists(os.path.join(download_dir, ".cipd")):
|
2019-09-11 18:22:23 -04:00
|
|
|
run([
|
2019-09-14 09:01:27 -04:00
|
|
|
cipd_exe,
|
|
|
|
"init",
|
|
|
|
download_dir,
|
|
|
|
"-force",
|
|
|
|
], env=google_env())
|
2019-09-11 18:22:23 -04:00
|
|
|
|
|
|
|
run([
|
2019-09-14 09:01:27 -04:00
|
|
|
cipd_exe,
|
|
|
|
"install",
|
2019-09-11 18:22:23 -04:00
|
|
|
item,
|
2019-09-14 09:01:27 -04:00
|
|
|
"git_revision:" + version,
|
|
|
|
"-root",
|
|
|
|
download_dir,
|
2019-09-11 18:22:23 -04:00
|
|
|
],
|
|
|
|
env=google_env())
|
|
|
|
|
|
|
|
|
2018-08-16 23:44:55 -04:00
|
|
|
# Download gn from Google storage.
|
|
|
|
def download_gn():
|
2019-09-14 09:01:27 -04:00
|
|
|
download_from_cipd("gn/gn/", "152c5144ceed9592c20f0c8fd55769646077569b")
|
2018-08-16 23:44:55 -04:00
|
|
|
|
|
|
|
|
|
|
|
# Download clang-format from Google storage.
|
|
|
|
def download_clang_format():
|
2019-09-12 15:07:21 -04:00
|
|
|
download_from_google_storage("clang-format", "chromium-clang-format",
|
|
|
|
os.path.join(libdeno_path, "buildtools"))
|
2019-09-14 09:01:27 -04:00
|
|
|
|
|
|
|
|
|
|
|
def download_sccache():
|
|
|
|
download_from_google_storage("sccache", "denoland", prebuilt_path)
|
|
|
|
|
|
|
|
|
|
|
|
def download_hyperfine():
|
|
|
|
download_from_google_storage("hyperfine", "denoland", prebuilt_path)
|
2018-08-16 23:44:55 -04:00
|
|
|
|
|
|
|
|
2018-07-25 04:17:44 -04:00
|
|
|
# Download clang by calling the clang update script.
|
|
|
|
def download_clang():
|
2019-09-12 15:07:21 -04:00
|
|
|
update_script = os.path.join(libdeno_path, "v8", "tools", "clang",
|
2019-09-14 09:01:27 -04:00
|
|
|
"scripts", "update.py")
|
|
|
|
run([sys.executable, update_script], env=google_env())
|
2018-07-27 12:06:23 -04:00
|
|
|
|
|
|
|
|
|
|
|
def maybe_download_sysroot():
|
2019-09-14 09:01:27 -04:00
|
|
|
if sys.platform.startswith("linux"):
|
2019-09-12 15:07:21 -04:00
|
|
|
install_script = os.path.join(libdeno_path, "build", "linux",
|
2019-09-14 09:01:27 -04:00
|
|
|
"sysroot_scripts", "install-sysroot.py")
|
|
|
|
run([sys.executable, install_script, "--arch=amd64"], env=google_env())
|