forked from denoland/deno
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsetup.py
executable file
·185 lines (144 loc) · 5.62 KB
/
setup.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
#!/usr/bin/env python
# Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import os
import re
import sys
from distutils.spawn import find_executable
import argparse
import third_party
from util import build_mode, build_path, enable_ansi_colors, libdeno_path
from util import shell_quote, root_path, run, third_party_path
parser = argparse.ArgumentParser()
parser.add_argument(
"--no-binary-download",
help="Do not download binaries, must use depot_tools manually",
action="store_true")
def main():
enable_ansi_colors()
os.chdir(root_path)
args = parser.parse_args()
if args.no_binary_download:
print "no binary download"
else:
print "binary download"
third_party.download_gn()
third_party.download_clang_format()
third_party.download_clang()
third_party.download_sccache()
third_party.maybe_download_sysroot()
write_lastchange()
mode = build_mode(default=None)
if mode is not None:
gn_gen(mode)
else:
gn_gen("release")
gn_gen("debug")
def write_if_not_exists(filename, contents):
if not os.path.exists(filename):
with open(filename, "w+") as f:
f.write(contents)
def write_lastchange():
lastchange_file = os.path.join(libdeno_path, "build", "util", "LASTCHANGE")
committime_file = lastchange_file + ".committime"
write_if_not_exists(
lastchange_file,
"LASTCHANGE=c42e4ddbb7973bfb0c57a49ab6bf6dc432baad7e-\n")
write_if_not_exists(committime_file, "1535518087")
# TODO Properly we should call the following script, but it seems to cause
# a rebuild on every commit.
# run([
# sys.executable, "build/util/lastchange.py", "-o", lastchange_file,
# "--source-dir", root_path, "--filter="
# ])
# If this text is found in args.gn, we assume it hasn't been hand edited.
gn_args_header = [
"# This file is automatically generated by tools/setup.py.",
"# REMOVE THIS LINE to preserve any changes you make.", ""
]
def gn_string(s):
# In gn, strings are enclosed in double-quotes and use backslash as the
# escape character. The only escape sequences supported are:
# \" (for literal quote)
# \$ (for literal dollars sign)
# \\ (for literal backslash)
# Any other use of a backslash is treated as a literal backslash.
s = re.sub(r'("|\$|\\(?=["$\\]))', r'\\\1', s)
s = '"' + s + '"'
return s
def gn_args_are_generated(lines):
for line in lines:
if re.match("^\s*#.*REMOVE THIS LINE", line):
return True
return False
def read_gn_args(args_filename):
if not os.path.exists(args_filename):
return (None, False) # No content, not hand edited.
with open(args_filename) as f:
lines = f.read().splitlines()
args = [l.strip() for l in lines if not re.match("^\s*(#|$)", l)]
hand_edited = not gn_args_are_generated(lines)
return (args, hand_edited)
def write_gn_args(args_filename, args):
assert not gn_args_are_generated(args) # No header -> hand crafted.
lines = gn_args_header + args
assert gn_args_are_generated(lines) # With header -> generated.
# Ensure the directory where args.gn goes exists.
d = os.path.dirname(args_filename)
if not os.path.isdir(d):
os.makedirs(d)
with open(args_filename, "w") as f:
f.write("\n".join(lines) + "\n")
def generate_gn_args(mode):
out = []
if mode == "release":
out += ["is_official_build=true", "symbol_level=0"]
elif mode == "debug":
out += ["is_debug=true"]
else:
print "Bad mode {}. Use 'release' or 'debug' (default)" % mode
sys.exit(1)
if "DENO_BUILD_ARGS" in os.environ:
out += os.environ["DENO_BUILD_ARGS"].split()
# Check if sccache is in the path, and if so we set cc_wrapper.
cc_wrapper = find_executable("sccache")
if not cc_wrapper:
cc_wrapper = third_party.get_prebuilt_tool_path("sccache")
if os.path.exists(cc_wrapper):
# The gn toolchain does not shell escape cc_wrapper, so do it here.
out += ['cc_wrapper=%s' % gn_string(shell_quote(cc_wrapper))]
if os.name == "nt":
# Disable treat_warnings_as_errors until this sccache bug is fixed:
# https://github.com/mozilla/sccache/issues/264
out += ["treat_warnings_as_errors=false"]
return out
def gn_exe():
if "DENO_GN_PATH" in os.environ:
return os.environ["DENO_GN_PATH"]
else:
return third_party.get_buildtools_tool_path("gn")
# gn gen.
def gn_gen(mode):
os.environ["DENO_BUILD_MODE"] = mode
# Rather than using gn gen --args we write directly to the args.gn file.
# This is to avoid quoting/escaping complications when passing overrides as
# command-line arguments.
args_filename = os.path.join(build_path(), "args.gn")
# Check if args.gn exists, and if it was auto-generated or handcrafted.
existing_gn_args, hand_edited = read_gn_args(args_filename)
# If args.gn wasn't handcrafted, regenerate it.
if hand_edited:
print "%s: Using gn options from hand edited '%s'." % (mode,
args_filename)
gn_args = existing_gn_args
else:
print "%s: Writing gn options to '%s'." % (mode, args_filename)
gn_args = generate_gn_args(mode)
if gn_args != existing_gn_args:
write_gn_args(args_filename, gn_args)
for line in gn_args:
print " " + line
run([gn_exe(), "gen", build_path()],
cwd=libdeno_path,
env=third_party.google_env())
if __name__ == '__main__':
sys.exit(main())