mirror of
https://github.com/denoland/deno.git
synced 2024-12-28 18:19:08 -05:00
860be9f0de
This fixes an issue on Windows that causes build to fails when fix_symlinks() is called concurrently with another build step. It is also no longer necessary, since recent versions of git know how to properly create symbolic links on checkout.
168 lines
5.1 KiB
Python
Executable file
168 lines
5.1 KiB
Python
Executable file
#!/usr/bin/env python
|
|
# Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
|
import third_party
|
|
from util import build_mode, build_path, enable_ansi_colors, root_path, run
|
|
from util import shell_quote, run_output
|
|
import os
|
|
import re
|
|
import sys
|
|
from distutils.spawn import find_executable
|
|
import prebuilt
|
|
|
|
|
|
def main():
|
|
enable_ansi_colors()
|
|
|
|
os.chdir(root_path)
|
|
|
|
third_party.download_gn()
|
|
third_party.download_clang_format()
|
|
third_party.download_clang()
|
|
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():
|
|
write_if_not_exists(
|
|
"build/util/LASTCHANGE",
|
|
"LASTCHANGE=c42e4ddbb7973bfb0c57a49ab6bf6dc432baad7e-\n")
|
|
write_if_not_exists("build/util/LASTCHANGE.committime", "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",
|
|
# "build/util/LASTCHANGE", "--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"]
|
|
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()
|
|
|
|
cacher = prebuilt.load_sccache()
|
|
if not os.path.exists(cacher):
|
|
cacher = find_executable("sccache") or find_executable("ccache")
|
|
|
|
# Check if ccache or sccache are in the path, and if so we set cc_wrapper.
|
|
cc_wrapper = cacher
|
|
if 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"]
|
|
|
|
# Look for sccache; if found, set rustc_wrapper.
|
|
rustc_wrapper = cacher
|
|
if rustc_wrapper:
|
|
out += ['rustc_wrapper=%s' % gn_string(rustc_wrapper)]
|
|
|
|
return out
|
|
|
|
|
|
# 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([third_party.gn_path, "gen", build_path()],
|
|
env=third_party.google_env())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|