forked from denoland/deno
-
Notifications
You must be signed in to change notification settings - Fork 0
/
third_party.py
190 lines (153 loc) · 7.11 KB
/
third_party.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#!/usr/bin/env python
# This script contains helper functions to work with the third_party subrepo.
import os
import sys
from os import path
from util import find_exts, make_env, remove_and_symlink, rmtree, root_path, run
# Helper function that returns the full path to a subpath of the repo root.
def root(*subpath_parts):
return path.normpath(path.join(root_path, *subpath_parts))
# Helper function that returns the full path to a file/dir in third_party.
def tp(*subpath_parts):
return root("third_party", *subpath_parts)
third_party_path = tp()
depot_tools_path = tp("depot_tools")
rust_crates_path = tp("rust_crates")
gn_path = tp(depot_tools_path, "gn")
clang_format_path = tp(depot_tools_path, "clang-format")
ninja_path = tp(depot_tools_path, "ninja")
# This function creates or modifies an environment so that it matches the
# expectations of various google tools (gn, gclient, etc).
def google_env(env=None, merge_env={}, depot_tools_path=depot_tools_path):
env = make_env(env=env, merge_env=merge_env)
# Depot_tools to be in the PATH, before Python.
path_prefix = depot_tools_path + os.path.pathsep
if not env['PATH'].startswith(path_prefix):
env['PATH'] = path_prefix + env['PATH']
# 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"
return env
def fix_symlinks():
# Ensure the third_party directory exists.
try:
os.makedirs(third_party_path)
except:
pass
# Make symlinks to Yarn metadata living in the root repo.
remove_and_symlink("../package.json", tp("package.json"))
# TODO(ry) Is it possible to remove these symlinks?
remove_and_symlink("v8/third_party/googletest", tp("googletest"), True)
remove_and_symlink("v8/third_party/jinja2", tp("jinja2"), True)
remove_and_symlink("v8/third_party/llvm-build", tp("llvm-build"), True)
remove_and_symlink("v8/third_party/markupsafe", tp("markupsafe"), True)
# On Windows, git doesn't create the right type of symlink if the symlink
# and it's target are in different repos. Here we fix the symlinks that exist
# in the root repo while their target is in the third_party repo.
remove_and_symlink("third_party/node_modules", root("node_modules"), True)
remove_and_symlink("third_party/v8/build", root("build"), True)
remove_and_symlink("third_party/v8/buildtools", root("buildtools"), True)
remove_and_symlink("third_party/v8/build_overrides",
root("build_overrides"), True)
remove_and_symlink("third_party/v8/testing", root("testing"), True)
remove_and_symlink("../third_party/v8/tools/clang", root("tools/clang"),
True)
# Run Yarn to install JavaScript dependencies.
def run_yarn():
run(["yarn", "install"], cwd=third_party_path)
# Run Cargo to install Rust dependencies.
def run_cargo():
# Deletes the cargo index lockfile; it appears that cargo itself doesn't do it.
# If the lockfile ends up in the git repo, it'll make cargo hang for everyone
# else who tries to run sync_third_party.
def delete_lockfile():
lockfiles = find_exts(
path.join(rust_crates_path, "registry/index"), '.cargo-index-lock')
for lockfile in lockfiles:
os.remove(lockfile)
# Delete the index lockfile in case someone accidentally checked it in.
delete_lockfile()
run(["cargo", "fetch", "--manifest-path=" + root("Cargo.toml")],
cwd=third_party_path,
merge_env={'CARGO_HOME': rust_crates_path})
# Delete the lockfile again so it doesn't end up in the git repo.
delete_lockfile()
# 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.
depot_tools_temp_path = root("depot_tools_temp")
# Rename depot_tools to depot_tools_temp.
try:
os.rename(depot_tools_path, depot_tools_temp_path)
except:
# 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.
if path.isdir(depot_tools_temp_path):
pass
else:
raise
args = [
"gclient", "sync", "--reset", "--shallow", "--no-history", "--nohooks"
]
envs = {
'DEPOT_TOOLS_UPDATE': "0",
'GCLIENT_FILE': root("gclient_config.py")
}
env = google_env(depot_tools_path=depot_tools_temp_path, merge_env=envs)
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.
if (path.isdir(path.join(depot_tools_path, ".git"))
and path.isfile(path.join(depot_tools_path, "gclient.py"))
and path.isfile(path.join(depot_tools_temp_path, "gclient.py"))):
rmtree(depot_tools_temp_path)
# Download the given item from Google storage.
def download_from_google_storage(item, bucket):
if sys.platform == 'win32':
sha1_file = "v8/buildtools/win/%s.exe.sha1" % item
elif sys.platform == 'darwin':
sha1_file = "v8/buildtools/mac/%s.sha1" % item
elif sys.platform.startswith('linux'):
sha1_file = "v8/buildtools/linux64/%s.sha1" % item
run([
"python",
tp('depot_tools/download_from_google_storage.py'),
'--platform=' + sys.platform,
'--no_auth',
'--bucket=%s' % bucket,
'--sha1_file',
tp(sha1_file),
],
env=google_env())
# Download gn from Google storage.
def download_gn():
download_from_google_storage('gn', 'chromium-gn')
# Download clang-format from Google storage.
def download_clang_format():
download_from_google_storage('clang-format', 'chromium-clang-format')
# Download clang by calling the clang update script.
def download_clang():
run(['python',
tp('v8/tools/clang/scripts/update.py'), '--if-needed'],
env=google_env())
def maybe_download_sysroot():
if sys.platform.startswith('linux'):
run([
'python',
tp('v8/build/linux/sysroot_scripts/install-sysroot.py'),
'--arch=amd64'
],
env=google_env())