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