• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright 2017 the V8 project authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""
7Use this script to build libv8_monolith.a as dependency for Node.js
8Required dependencies can be fetched with fetch_deps.py.
9
10Usage: build_gn.py <Debug/Release> <v8-path> <build-path> [<build-flags>]...
11
12Build flags are passed either as "strings" or numeric value. True/false
13are represented as 1/0. E.g.
14
15  v8_promise_internal_field_count=2
16  target_cpu="x64"
17  v8_enable_disassembler=0
18"""
19
20import argparse
21import os
22import subprocess
23import sys
24
25import node_common
26
27GN_ARGS = [
28  "v8_monolithic=true",
29  "is_component_build=false",
30  "v8_use_external_startup_data=false",
31  "use_custom_libcxx=false",
32]
33
34BUILD_TARGET = "v8_monolith"
35
36def FindTargetOs(flags):
37  for flag in flags:
38    if flag.startswith("target_os="):
39      return flag[len("target_os="):].strip('"')
40  raise Exception('No target_os was set.')
41
42def FindGn(options):
43  if options.host_os == "linux":
44    os_path = "linux64"
45  elif options.host_os == "mac":
46    os_path = "mac"
47  elif options.host_os == "win":
48    os_path = "win"
49  else:
50    raise "Operating system not supported by GN"
51  return os.path.join(options.v8_path, "buildtools", os_path, "gn")
52
53def GenerateBuildFiles(options):
54  gn = FindGn(options)
55  gn_args = list(GN_ARGS)
56  target_os = FindTargetOs(options.flag)
57  if target_os != "win":
58    gn_args.append("use_sysroot=false")
59
60  for flag in options.flag:
61    flag = flag.replace("=1", "=true")
62    flag = flag.replace("=0", "=false")
63    flag = flag.replace("target_cpu=ia32", "target_cpu=\"x86\"")
64    gn_args.append(flag)
65  if options.mode == "Debug":
66    gn_args.append("is_debug=true")
67  else:
68    gn_args.append("is_debug=false")
69
70  flattened_args = ' '.join(gn_args)
71  if options.extra_gn_args:
72    flattened_args += ' ' + options.extra_gn_args
73
74  args = [gn, "gen", options.build_path, "-q", "--args=" + flattened_args]
75  subprocess.check_call(args)
76
77def Build(options):
78  depot_tools = node_common.EnsureDepotTools(options.v8_path, False)
79  ninja = os.path.join(depot_tools, "ninja")
80  if sys.platform == 'win32':
81    # Required because there is an extension-less file called "ninja".
82    ninja += ".exe"
83  args = [ninja, "-C", options.build_path, BUILD_TARGET]
84  if options.max_load:
85    args += ["-l" + options.max_load]
86  if options.max_jobs:
87    args += ["-j" + options.max_jobs]
88  else:
89    with open(os.path.join(options.build_path, "args.gn")) as f:
90      if "use_goma = true" in f.read():
91        args += ["-j500"]
92  subprocess.check_call(args)
93
94def ParseOptions(args):
95  parser = argparse.ArgumentParser(
96      description="Build %s with GN" % BUILD_TARGET)
97  parser.add_argument("--mode", help="Build mode (Release/Debug)")
98  parser.add_argument("--v8_path", help="Path to V8", required=True)
99  parser.add_argument("--build_path", help="Path to build result",
100                      required=True)
101  parser.add_argument("--flag", help="Translate GYP flag to GN",
102                      action="append")
103  parser.add_argument("--host_os", help="Current operating system")
104  parser.add_argument("--bundled-win-toolchain",
105                      help="Value for DEPOT_TOOLS_WIN_TOOLCHAIN")
106  parser.add_argument("--bundled-win-toolchain-root",
107                      help="Value for DEPOT_TOOLS_WIN_TOOLCHAIN_ROOT")
108  parser.add_argument("--depot-tools", help="Absolute path to depot_tools")
109  parser.add_argument("--extra-gn-args", help="Additional GN args")
110  parser.add_argument("--build", help="Run ninja as opposed to gn gen.",
111                      action="store_true")
112  parser.add_argument("--max-jobs", help="ninja's -j parameter")
113  parser.add_argument("--max-load", help="ninja's -l parameter")
114  options = parser.parse_args(args)
115
116  options.build_path = os.path.abspath(options.build_path)
117
118  if not options.build:
119    assert options.host_os
120    assert options.mode == "Debug" or options.mode == "Release"
121
122    options.v8_path = os.path.abspath(options.v8_path)
123    assert os.path.isdir(options.v8_path)
124
125  return options
126
127
128if __name__ == "__main__":
129  options = ParseOptions(sys.argv[1:])
130  # Build can result in running gn gen, so need to set environment variables
131  # for build as well as generate.
132  if options.bundled_win_toolchain:
133    os.environ['DEPOT_TOOLS_WIN_TOOLCHAIN'] = options.bundled_win_toolchain
134  if options.bundled_win_toolchain_root:
135    os.environ['DEPOT_TOOLS_WIN_TOOLCHAIN_ROOT'] = (
136        options.bundled_win_toolchain_root)
137  if options.depot_tools:
138    os.environ['PATH'] = (
139        options.depot_tools + os.path.pathsep + os.environ['PATH'])
140  if not options.build:
141    GenerateBuildFiles(options)
142  else:
143    Build(options)
144