Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@
['build_v8_with_gn == "true"', {
'conditions': [
['GENERATOR == "ninja"', {
'v8_base': '<(PRODUCT_DIR)/obj/deps/v8/gypfiles/v8_monolith.gen/gn/obj/libv8_monolith.a',
'v8_base': '<(PRODUCT_DIR)/obj/deps/v8/gypfiles/v8_monolith.gen/gn/obj/<(STATIC_LIB_PREFIX)v8_monolith<(STATIC_LIB_SUFFIX)',
}, {
'v8_base': '<(PRODUCT_DIR)/obj.target/v8_monolith/geni/gn/obj/libv8_monolith.a',
'v8_base': '<(PRODUCT_DIR)/obj.target/v8_monolith/geni/gn/obj/<(STATIC_LIB_PREFIX)v8_monolith<(STATIC_LIB_SUFFIX)',
}],
],
}],
Expand Down
56 changes: 53 additions & 3 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,28 @@ parser.add_option('--build-v8-with-gn',
dest='build_v8_with_gn',
default=False,
help='build V8 using GN instead of gyp')
parser.add_option('--build-v8-with-gn-max-jobs',
dest='build_v8_with_gn_max_jobs',
default='',
help='Value for the -j parameter for the ninja invocation.')
parser.add_option('--build-v8-with-gn-max-load',
dest='build_v8_with_gn_max_load',
default='',
help='Value for the -l parameter for the ninja invocation.')
parser.add_option('--build-v8-with-gn-extra-gn-args',
dest='build_v8_with_gn_extra_gn_args',
default='',
help='Extra gn args to pass add to the "gn gen --args "..." invocation')
parser.add_option('--use-clang-cl',
action='store_true',
dest='use_clang_cl',
default=False,
help='On Windows, build using clang-cl. By default, uses the copy of '
'clang-cl that is bundled with V8. Requires --ninja.')
parser.add_option('--clang-cl-base-path',
dest='clang_cl_base_path',
help='Absolute path to a directory containing a bin\\clang-cl.exe '
'(requires --use-clang-cl).')

# Create compile_commands.json in out/Debug and out/Release.
parser.add_option('-C',
Expand All @@ -572,7 +594,6 @@ options.prefix = os.path.expanduser(options.prefix or '')
# set up auto-download list
auto_downloads = nodedownload.parse(options.download_list)


def warn(msg):
warn.warned = True
prefix = '\033[1m\033[93mWARNING\033[0m' if os.isatty(1) else 'WARNING'
Expand All @@ -581,6 +602,22 @@ def warn(msg):
# track if warnings occurred
warn.warned = False

if options.use_clang_cl:
if not options.use_ninja:
warn('--use-clang-cl requires --ninja')
if options.clang_cl_base_path:
clang_base_path = options.clang_cl_base_path
else:
clang_base_path = os.path.abspath(os.path.join(
'deps', 'v8', 'third_party', 'llvm-build', 'Release+Asserts'))
# CC sets the path for GYP-compiled files.
os.environ['CC'] = os.path.join(clang_base_path, 'bin', 'clang-cl.exe')
# GN arg sets the path for --build-v8-using-gn.
if options.build_v8_with_gn_extra_gn_args:
options.build_v8_with_gn_extra_gn_args += ' '
options.build_v8_with_gn_extra_gn_args += 'clang_base_path="{}"'.format(
clang_base_path)

def b(value):
"""Returns the string 'true' if value is truthy, 'false' otherwise."""
if value:
Expand Down Expand Up @@ -1049,11 +1086,24 @@ def configure_v8(o):
if options.without_bundled_v8 and options.build_v8_with_gn:
raise Exception(
'--build-v8-with-gn is incompatible with --without-bundled-v8.')
o['variables']['build_v8_with_gn'] = b(options.build_v8_with_gn)
if options.build_v8_with_gn:
v8_path = os.path.join('deps', 'v8')
print('Fetching dependencies to build V8 with GN')
options.build_v8_with_gn = FetchDeps(v8_path)
o['variables']['build_v8_with_gn'] = b(options.build_v8_with_gn)
# Default to non-Googler configuration.
if 'DEPOT_TOOLS_WIN_TOOLCHAIN' not in os.environ:
os.environ['DEPOT_TOOLS_WIN_TOOLCHAIN'] = '0'
depot_tools = FetchDeps(v8_path)

o['variables']['build_v8_with_gn_extra_gn_args'] = (
options.build_v8_with_gn_extra_gn_args)
o['variables']['build_v8_with_gn_max_jobs'] = (
options.build_v8_with_gn_max_jobs)
o['variables']['build_v8_with_gn_max_load'] = (
options.build_v8_with_gn_max_load)
o['variables']['build_v8_with_gn_bundled_win_toolchain'] = (
os.environ['DEPOT_TOOLS_WIN_TOOLCHAIN'])
o['variables']['build_v8_with_gn_depot_tools'] = depot_tools


def configure_openssl(o):
Expand Down
69 changes: 64 additions & 5 deletions deps/v8/gypfiles/v8-monolithic.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,32 @@
'include_dirs': [
'../include/',
],
'link_settings': {
'conditions': [
['OS=="win"', {
'libraries': ['-ldbghelp.lib', '-lshlwapi.lib', '-lwinmm.lib', '-lws2_32.lib'],
}],
['OS=="linux"', {
'libraries': ['-ldl', '-lrt'],
}],
],
},
},
'actions': [
{
'action_name': 'build_with_gn',
'action_name': 'build_with_gn_generate_build_files',
# No need to list full set of inputs because after the initial
# generation, ninja (run by the next action), will check to see
# if build.ninja is stale.
'inputs': [
'../tools//node/build_gn.py',
'../tools/node/build_gn.py',
],
'outputs': [
'<(INTERMEDIATE_DIR)/gn/obj/libv8_monolith.a',
'<(INTERMEDIATE_DIR)/gn/args.gn',
'<(INTERMEDIATE_DIR)/gn/build.ninja',
],
'action': [
'../tools//node/build_gn.py',
'python',
'../tools/node/build_gn.py',
'--mode', '<(CONFIGURATION_NAME)',
'--v8_path', '../',
'--build_path', '<(INTERMEDIATE_DIR)/gn',
Expand All @@ -49,7 +62,53 @@
'--flag', 'v8_optimized_debug=<(v8_optimized_debug)',
'--flag', 'v8_enable_disassembler=<(v8_enable_disassembler)',
'--flag', 'v8_postmortem_support=<(v8_postmortem_support)',
'--bundled-win-toolchain', '<(build_v8_with_gn_bundled_win_toolchain)',
'--depot-tools', '<(build_v8_with_gn_depot_tools)',
],
'conditions': [
['build_v8_with_gn_extra_gn_args != ""', {
'action': [
'--extra-gn-args', '<(build_v8_with_gn_extra_gn_args)',
],
}],
],
},
{
'action_name': 'build_with_gn',
'inputs': [
'../tools/node/build_gn.py',
'<(INTERMEDIATE_DIR)/gn/build.ninja',
],
# Specify a non-existent output to make the target permanently dirty.
# Alternatively, a depfile could be used, but then two dirty checks
# would run: one by the outer build tool, and one by build_gn.py.
'outputs': [
'<(v8_base)',
'does-not-exist',
],
'action': [
'python',
'../tools/node/build_gn.py',
'--build_path', '<(INTERMEDIATE_DIR)/gn',
'--v8_path', '../',
'--bundled-win-toolchain', '<(build_v8_with_gn_bundled_win_toolchain)',
'--depot-tools', '<(build_v8_with_gn_depot_tools)',
'--build',
],
'conditions': [
['build_v8_with_gn_max_jobs!=""', {
'action': [
'--max-jobs', '<(build_v8_with_gn_max_jobs)',
],
}],
['build_v8_with_gn_max_load!=""', {
'action': [
'--max-load', '<(build_v8_with_gn_max_load)',
],
}],
],
# Allows sub-ninja's build progress to be printed.
'ninja_use_console': 1,
},
],
},
Expand Down
93 changes: 63 additions & 30 deletions deps/v8/tools/node/build_gn.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@
import node_common

GN_ARGS = [
"v8_monolithic = true",
"is_component_build = false",
"v8_use_external_startup_data = false",
"use_custom_libcxx = false",
"use_sysroot = false",
"v8_monolithic=true",
"is_component_build=false",
"v8_use_external_startup_data=false",
"use_custom_libcxx=false",
]

BUILD_TARGET = "v8_monolith"

def FindTargetOs(flags):
for flag in flags:
if flag.startswith("target_os="):
return flag[len("target_os="):].strip('"')
raise Exception('No target_os was set.')

def FindGn(options):
if options.host_os == "linux":
os_path = "linux64"
Expand All @@ -46,57 +51,85 @@ def FindGn(options):
return os.path.join(options.v8_path, "buildtools", os_path, "gn")

def GenerateBuildFiles(options):
print "Setting GN args."
gn = FindGn(options)
gn_args = []
gn_args.extend(GN_ARGS)
gn_args = list(GN_ARGS)
target_os = FindTargetOs(options.flag)
if target_os != "win":
gn_args.append("use_sysroot=false")

for flag in options.flag:
flag = flag.replace("=1", "=true")
flag = flag.replace("=0", "=false")
flag = flag.replace("target_cpu=ia32", "target_cpu=\"x86\"")
gn_args.append(flag)
if options.mode == "DEBUG":
gn_args.append("is_debug = true")
gn_args.append("is_debug=true")
else:
gn_args.append("is_debug = false")
gn_args.append("is_debug=false")

flattened_args = ' '.join(gn_args)
if options.extra_gn_args:
flattened_args += ' ' + options.extra_gn_args

if not os.path.isdir(options.build_path):
os.makedirs(options.build_path)
with open(os.path.join(options.build_path, "args.gn"), "w") as args_file:
args_file.write("\n".join(gn_args))
subprocess.check_call([gn, "gen", "-C", options.build_path],
cwd=options.v8_path)
args = [gn, "gen", options.build_path, "-q", "--args=" + flattened_args]
subprocess.check_call(args)

def Build(options):
print "Building."
depot_tools = node_common.EnsureDepotTools(options.v8_path, False)
ninja = os.path.join(depot_tools, "ninja")
subprocess.check_call([ninja, "-v", "-C", options.build_path, BUILD_TARGET],
cwd=options.v8_path)
if sys.platform == 'win32':
# Required because there is an extension-less file called "ninja".
ninja += ".exe"
args = [ninja, "-C", options.build_path, BUILD_TARGET]
if options.max_load:
args += ["-l" + options.max_load]
if options.max_jobs:
args += ["-j" + options.max_jobs]
else:
with open(os.path.join(options.build_path, "args.gn")) as f:
if "use_goma = true" in f.read():
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe make this more robust to spaces? Above all gn args are passed now without spaces. Also goma might be passed as:
use_goma=true

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script now uses gn gen --args=, which means GN will format the file to always have one spaces on each side of the "="

args += ["-j500"]
subprocess.check_call(args)

def ParseOptions(args):
parser = argparse.ArgumentParser(
description="Build %s with GN" % BUILD_TARGET)
parser.add_argument("--mode", help="Build mode (Release/Debug)")
parser.add_argument("--v8_path", help="Path to V8")
parser.add_argument("--build_path", help="Path to build result")
parser.add_argument("--v8_path", help="Path to V8", required=True)
parser.add_argument("--build_path", help="Path to build result",
required=True)
parser.add_argument("--flag", help="Translate GYP flag to GN",
action="append")
parser.add_argument("--host_os", help="Current operating system")
parser.add_argument("--bundled-win-toolchain",
help="Value for DEPOT_TOOLS_WIN_TOOLCHAIN")
parser.add_argument("--depot-tools", help="Absolute path to depot_tools")
parser.add_argument("--extra-gn-args", help="Additional GN args")
parser.add_argument("--build", help="Run ninja as opposed to gn gen.",
action="store_true")
parser.add_argument("--max-jobs", help="ninja's -j parameter")
parser.add_argument("--max-load", help="ninja's -l parameter")
options = parser.parse_args(args)

assert options.host_os
assert options.mode == "Debug" or options.mode == "Release"
options.build_path = os.path.abspath(options.build_path)

assert options.v8_path
options.v8_path = os.path.abspath(options.v8_path)
assert os.path.isdir(options.v8_path)
if not options.build:
assert options.host_os
assert options.mode == "Debug" or options.mode == "Release"

options.v8_path = os.path.abspath(options.v8_path)
assert os.path.isdir(options.v8_path)

assert options.build_path
options.build_path = os.path.abspath(options.build_path)
return options


if __name__ == "__main__":
options = ParseOptions(sys.argv[1:])
GenerateBuildFiles(options)
Build(options)
# Build can result in running gn gen, so need to set environment variables
# for build as well as generate.
os.environ['DEPOT_TOOLS_WIN_TOOLCHAIN'] = options.bundled_win_toolchain
os.environ['PATH'] += os.path.pathsep + options.depot_tools
if not options.build:
GenerateBuildFiles(options)
else:
Build(options)
21 changes: 12 additions & 9 deletions deps/v8/tools/node/fetch_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,21 @@
]

def EnsureGit(v8_path):
def git(args):
# shell=True needed on Windows to resolve git.bat.
return subprocess.check_output(
"git " + args, cwd=v8_path, shell=True).strip()

expected_git_dir = os.path.join(v8_path, ".git")
actual_git_dir = subprocess.check_output(
["git", "rev-parse", "--absolute-git-dir"], cwd=v8_path).strip()
actual_git_dir = git("rev-parse --absolute-git-dir")
if expected_git_dir == actual_git_dir:
print "V8 is tracked stand-alone by git."
return False
print "Initializing temporary git repository in v8."
subprocess.check_call(["git", "init"], cwd=v8_path)
subprocess.check_call(["git", "config", "user.name", "\"Ada Lovelace\""], cwd=v8_path)
subprocess.check_call(["git", "config", "user.email", "\"[email protected]\""], cwd=v8_path)
subprocess.check_call(["git", "commit", "--allow-empty", "-m", "init"],
cwd=v8_path)
git("init")
git("config user.name \"Ada Lovelace\"")
git("config user.email [email protected]")
git("commit --allow-empty -m init")
return True

def FetchDeps(v8_path):
Expand Down Expand Up @@ -86,8 +89,8 @@ def FetchDeps(v8_path):
os.path.join(v8_path, os.pardir, ".gclient_entries"))
if os.path.isfile(gclient_entries):
os.remove(gclient_entries)
# Enable building with GN for configure script.
return True

return depot_tools


if __name__ == "__main__":
Expand Down
6 changes: 5 additions & 1 deletion deps/v8/tools/node/node_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# found in the LICENSE file.

import os
import pipes
import shutil
import stat
import subprocess
Expand All @@ -22,7 +23,10 @@ def _Get(v8_path):
pass
if fetch_if_not_exist:
print "Checking out depot_tools."
subprocess.check_call(["git", "clone", DEPOT_TOOLS_URL, depot_tools])
# shell=True needed on Windows to resolve git.bat.
subprocess.check_call("git clone {} {}".format(
pipes.quote(DEPOT_TOOLS_URL),
pipes.quote(depot_tools)), shell=True)
return depot_tools
return None
depot_tools = _Get(v8_path)
Expand Down
Loading