| #!/usr/bin/env python3 |
| # Copyright 2016 The Dart project authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import argparse |
| import os |
| import platform |
| import subprocess |
| import socket |
| import sys |
| import time |
| import utils |
| |
| HOST_OS = utils.GuessOS() |
| HOST_ARCH = utils.GuessArchitecture() |
| SCRIPT_DIR = os.path.dirname(sys.argv[0]) |
| DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..')) |
| AVAILABLE_ARCHS = utils.ARCH_FAMILY.keys() |
| |
| # Environment variables for default settings. |
| DART_USE_TOOLCHAIN = "DART_USE_TOOLCHAIN" # Use instead of --toolchain-prefix |
| DART_USE_SYSROOT = "DART_USE_SYSROOT" # Use instead of --target-sysroot |
| DART_USE_CRASHPAD = "DART_USE_CRASHPAD" # Use instead of --use-crashpad |
| # use instead of --platform-sdk |
| DART_MAKE_PLATFORM_SDK = "DART_MAKE_PLATFORM_SDK" |
| |
| DART_GN_ARGS = "DART_GN_ARGS" |
| |
| |
| def ToolchainPrefix(args): |
| if args.toolchain_prefix: |
| return args.toolchain_prefix |
| return os.environ.get(DART_USE_TOOLCHAIN) |
| |
| |
| def TargetSysroot(args): |
| if args.target_sysroot: |
| return args.target_sysroot |
| return os.environ.get(DART_USE_SYSROOT) |
| |
| |
| def MakePlatformSDK(): |
| return DART_MAKE_PLATFORM_SDK in os.environ |
| |
| |
| def GetGNArgs(args): |
| if args.gn_args != None: |
| return args.gn_args |
| args = os.environ.get(DART_GN_ARGS) or "" |
| return args.split() |
| |
| |
| def GetOutDir(mode, arch, target_os, sanitizer): |
| return utils.GetBuildRoot(HOST_OS, mode, arch, target_os, sanitizer) |
| |
| |
| def ToCommandLine(gn_args): |
| |
| def merge(key, value): |
| if type(value) is bool: |
| return '%s=%s' % (key, 'true' if value else 'false') |
| elif type(value) is int: |
| return '%s=%d' % (key, value) |
| return '%s="%s"' % (key, value) |
| |
| return [merge(x, y) for x, y in gn_args.items()] |
| |
| |
| # The C compiler's target under the host toolchain (DART_HOST_ARCH_***). |
| def HostCpuForArch(arch): |
| arch = arch.split("_")[-1] |
| |
| # For each target architecture, we prefer in descending order |
| # - using the same architecture for the host (supports all architectures) |
| # - using a host architecture with the same word size (supports arm and riscv, which have simulators) |
| # - using a host architecture with a different word size (supports only AOT and only 32-bit target on 64-bit host) |
| if arch in ['ia32']: |
| candidates = ['x86'] |
| elif arch in ['x64', 'x64c', 'simx64', 'simx64c']: |
| candidates = ['x64', 'arm64'] |
| elif arch in ['arm', 'simarm']: |
| candidates = ['arm', 'x86', 'riscv32', 'arm64', 'x64', 'riscv64'] |
| elif arch in ['arm64', 'arm64c', 'simarm64', 'simarm64c']: |
| candidates = ['arm64', 'x64', 'riscv64'] |
| elif arch in ['riscv32', 'simriscv32']: |
| candidates = ['riscv32', 'arm', 'x86', 'riscv64', 'arm64', 'x64'] |
| elif arch in ['riscv64', 'simriscv64']: |
| candidates = ['riscv64', 'arm64', 'x64'] |
| else: |
| raise Exception("Unknown Dart architecture: %s" % arch) |
| |
| available = utils.HostArchitectures() |
| for candidate in candidates: |
| if candidate in available: |
| return candidate |
| |
| raise Exception( |
| "Failed to find a C host architecture for %s. Need one of %s but only %s are available." |
| % (arch, candidates, available)) |
| |
| |
| # The C compiler's target under the target toolchain (DART_HOST_ARCH_***). |
| def TargetCpuForArch(arch): |
| # Real target architectures |
| if arch.startswith('ia32'): |
| return 'x86' |
| elif arch.startswith('x64'): |
| return 'x64' |
| elif arch.startswith('arm64'): |
| return 'arm64' |
| elif arch.startswith('arm'): |
| return 'arm' |
| elif arch.startswith('riscv32'): |
| return 'riscv32' |
| elif arch.startswith('riscv64'): |
| return 'riscv64' |
| |
| # Simulators |
| if arch.endswith('_x64'): |
| return 'x64' |
| elif arch.endswith('_arm64'): |
| return 'arm64' |
| elif arch.endswith('_riscv64'): |
| return 'riscv64' |
| elif arch in ['simarm', 'simriscv32']: |
| candidates = ['arm', 'riscv32', 'x86'] |
| elif arch in ['simx64', 'simx64c', 'simarm64', 'simarm64c', 'simriscv64']: |
| candidates = ['arm64', 'riscv64', 'x64'] |
| else: |
| raise Exception("Unknown Dart architecture: %s" % arch) |
| |
| available = utils.HostArchitectures() |
| for candidate in candidates: |
| if candidate in available: |
| return candidate |
| |
| raise Exception( |
| "Failed to find a C target architecture for %s. Need one of %s but only %s are available." |
| % (arch, candidates, available)) |
| |
| |
| # The Dart compiler's target (DART_TARGET_ARCH_***) |
| def DartTargetCpuForArch(arch): |
| arch = arch.split("_")[0] |
| if arch.startswith("sim"): |
| arch = arch[3:] |
| if arch.endswith("c"): |
| arch = arch[:-1] |
| return arch |
| |
| |
| def IsCompressedPointerArch(arch): |
| return "64c" in arch |
| |
| |
| def HostOsForGn(host_os): |
| if host_os.startswith('macos'): |
| return 'mac' |
| if host_os.startswith('win'): |
| return 'win' |
| return host_os |
| |
| |
| # Where string_map is formatted as X1=Y1,X2=Y2 etc. |
| # If key is X1, returns Y1. |
| def ParseStringMap(key, string_map): |
| for m in string_map.split(','): |
| l = m.split('=') |
| if l[0] == key: |
| return l[1] |
| return None |
| |
| |
| def UseSysroot(args, gn_args): |
| # Don't try to use a Linux sysroot if we aren't on Linux. |
| if gn_args['target_os'] != 'linux' and HOST_OS != 'linux': |
| return False |
| # Don't use the sysroot if we're given another sysroot. |
| if TargetSysroot(args): |
| return False |
| # Don't use the sysroot if we're given another toolchain. |
| if not gn_args['is_clang']: |
| return False |
| # Fuchsia's Linux sysroot doesn't support RISCV32 |
| if gn_args['target_cpu'] in ['riscv32']: |
| return False |
| # Otherwise use the sysroot. |
| return True |
| |
| |
| def ToGnArgs(args, mode, arch, target_os, sanitizer, verify_sdk_hash, |
| git_version): |
| gn_args = {} |
| |
| host_os = HostOsForGn(HOST_OS) |
| if target_os == 'host': |
| gn_args['target_os'] = host_os |
| elif target_os == 'ios_simulator': |
| gn_args['target_os'] = 'ios' |
| gn_args['use_ios_simulator'] = True |
| else: |
| gn_args['target_os'] = target_os |
| |
| gn_args['host_cpu'] = HostCpuForArch(arch) |
| gn_args['target_cpu'] = TargetCpuForArch(arch) |
| gn_args['dart_target_arch'] = DartTargetCpuForArch(arch) |
| gn_args['dart_use_compressed_pointers'] = IsCompressedPointerArch(arch) |
| |
| # Configure Crashpad library if it is used. |
| gn_args['dart_use_crashpad'] = ((args.use_crashpad or |
| DART_USE_CRASHPAD in os.environ) and |
| gn_args['target_cpu'] in ['x86', 'x64']) |
| if gn_args['dart_use_crashpad']: |
| # Tell Crashpad's BUILD files which checkout layout to use. |
| gn_args['crashpad_dependencies'] = 'dart' |
| |
| if DartTargetCpuForArch(arch) != HostCpuForArch(arch): |
| # Training an app-jit snapshot under a simulator is slow. Use script |
| # snapshots instead. |
| gn_args['dart_snapshot_kind'] = 'kernel' |
| else: |
| gn_args['dart_snapshot_kind'] = 'app-jit' |
| |
| # We only want the fallback root certs in the standalone VM on |
| # Linux and Windows. |
| if gn_args['target_os'] in ['linux', 'win']: |
| gn_args['dart_use_fallback_root_certificates'] = True |
| |
| gn_args['bssl_use_clang_integrated_as'] = True |
| |
| if gn_args['target_os'] == 'linux': |
| if gn_args['target_cpu'] == 'arm': |
| # Default to -mfloat-abi=hard and -mfpu=neon for arm on Linux as we're |
| # specifying a gnueabihf compiler in //build/toolchain/linux/BUILD.gn. |
| floatabi = 'hard' if args.arm_float_abi == '' else args.arm_float_abi |
| gn_args['arm_version'] = 7 |
| gn_args['arm_float_abi'] = floatabi |
| gn_args['arm_use_neon'] = True |
| if gn_args['target_os'] == 'fuchsia': |
| gn_args['fuchsia_target_api_level'] = 22 |
| |
| gn_args['is_debug'] = mode == 'debug' |
| gn_args['is_release'] = mode == 'release' |
| gn_args['is_product'] = mode == 'product' |
| gn_args['dart_debug'] = mode == 'debug' |
| |
| # This setting is only meaningful for Flutter. Standalone builds of the VM |
| # should leave this set to 'develop', which causes the build to defer to |
| # 'is_debug', 'is_release' and 'is_product'. |
| if mode == 'product': |
| gn_args['dart_runtime_mode'] = 'release' |
| else: |
| gn_args['dart_runtime_mode'] = 'develop' |
| |
| gn_args['exclude_kernel_service'] = args.exclude_kernel_service |
| |
| gn_args['is_clang'] = args.clang |
| |
| enable_code_coverage = args.code_coverage and gn_args['is_clang'] |
| gn_args['dart_vm_code_coverage'] = enable_code_coverage |
| |
| gn_args['dart_dynamic_modules'] = args.dart_dynamic_modules |
| |
| gn_args['is_asan'] = sanitizer == 'asan' |
| gn_args['is_lsan'] = sanitizer == 'lsan' |
| gn_args['is_msan'] = sanitizer == 'msan' |
| gn_args['is_tsan'] = sanitizer == 'tsan' |
| gn_args['is_ubsan'] = sanitizer == 'ubsan' |
| gn_args['is_qemu'] = args.use_qemu |
| |
| if not args.platform_sdk: |
| gn_args['dart_platform_sdk'] = args.platform_sdk |
| |
| # We don't support stripping on Windows |
| if host_os != 'win': |
| gn_args['dart_stripped_binary'] = 'exe.stripped/dart' |
| gn_args['dart_precompiled_runtime_stripped_binary'] = ( |
| 'exe.stripped/dart_precompiled_runtime_product') |
| gn_args['gen_snapshot_stripped_binary'] = ( |
| 'exe.stripped/gen_snapshot_product') |
| gn_args['analyze_snapshot_binary'] = ('exe.stripped/analyze_snapshot') |
| gn_args['wasm_opt_stripped_binary'] = 'exe.stripped/wasm-opt' |
| |
| # Setup the user-defined sysroot. |
| if UseSysroot(args, gn_args): |
| gn_args['dart_sysroot'] = 'debian' |
| else: |
| sysroot = TargetSysroot(args) |
| if sysroot: |
| gn_args['target_sysroot'] = ParseStringMap(arch, sysroot) |
| |
| toolchain = ToolchainPrefix(args) |
| if toolchain: |
| for arch in ['ia32', 'x64', 'arm', 'arm64', 'riscv32', 'riscv64']: |
| prefix = ParseStringMap(arch, toolchain) |
| if prefix != None: |
| gn_args[arch + '_toolchain_prefix'] = prefix |
| |
| gn_args['use_rbe'] = args.rbe |
| |
| if args.rbe_expensive_exec_strategy: |
| gn_args[ |
| 'rbe_expensive_exec_strategy'] = args.rbe_expensive_exec_strategy |
| |
| # Code coverage requires -O0 to be set. |
| if enable_code_coverage: |
| gn_args['dart_debug_optimization_level'] = 0 |
| gn_args['debug_optimization_level'] = 0 |
| elif args.debug_opt_level: |
| gn_args['dart_debug_optimization_level'] = args.debug_opt_level |
| gn_args['debug_optimization_level'] = args.debug_opt_level |
| |
| gn_args['verify_sdk_hash'] = verify_sdk_hash |
| gn_args['dart_version_git_info'] = git_version |
| |
| if args.codesigning_identity != '': |
| gn_args['codesigning_identity'] = args.codesigning_identity |
| |
| return gn_args |
| |
| |
| def ProcessOsOption(os_name): |
| if os_name == 'host': |
| return HOST_OS |
| return os_name |
| |
| |
| def ProcessOptions(args): |
| if args.verify_sdk_hash == None: |
| args.verify_sdk_hash = not args.rbe |
| if args.git_version == None: |
| args.git_version = not args.rbe |
| if args.arch == 'all': |
| if platform.system() == 'Darwin': |
| # Targeting 32 bits not supported on MacOS. |
| # See HostArchitectures in utils.py. |
| args.arch = 'x64,simarm64,x64c,simarm64c,simriscv64' |
| else: |
| args.arch = 'ia32,x64,simarm,simarm64,x64c,simarm64c,simriscv32,simriscv64' |
| if args.mode == 'all': |
| args.mode = 'debug,release,product' |
| if args.os == 'all': |
| args.os = 'host,android,fuchsia' |
| if args.sanitizer == 'all': |
| args.sanitizer = 'none,asan,lsan,msan,tsan,ubsan' |
| args.mode = args.mode.split(',') |
| args.arch = args.arch.split(',') |
| args.os = args.os.split(',') |
| args.sanitizer = args.sanitizer.split(',') |
| for mode in args.mode: |
| if not mode in ['debug', 'release', 'product']: |
| print("Unknown mode %s" % mode) |
| return False |
| for i, arch in enumerate(args.arch): |
| args.arch[i] = arch.lower() |
| oses = [ProcessOsOption(os_name) for os_name in args.os] |
| for os_name in oses: |
| if not os_name in [ |
| 'android', 'freebsd', 'linux', 'macos', 'win32', 'fuchsia', |
| 'ios', 'ios_simulator' |
| ]: |
| print("Unknown os %s" % os_name) |
| return False |
| if os_name == 'android': |
| if not HOST_OS in ['linux', 'macos']: |
| print( |
| "Cross-compilation to %s is not supported on host os %s." % |
| (os_name, HOST_OS)) |
| return False |
| if not arch in [ |
| 'ia32', |
| 'x64', |
| 'arm', |
| 'arm_x64', |
| 'arm64', |
| 'x64c', |
| 'arm64c', |
| 'riscv64', |
| ]: |
| print( |
| "Cross-compilation to %s is not supported for architecture %s." |
| % (os_name, arch)) |
| return False |
| elif os_name == 'fuchsia': |
| if not HOST_OS in ['linux', 'macos']: |
| print( |
| "Cross-compilation to %s is not supported on host os %s." % |
| (os_name, HOST_OS)) |
| return False |
| if not arch in ['x64', 'arm64', 'x64c', 'arm64c', 'riscv64']: |
| print( |
| "Cross-compilation to %s is not supported for architecture %s." |
| % (os_name, arch)) |
| return False |
| elif os_name == 'ios' or os_name == 'ios_simulator': |
| if not HOST_OS in ['macos']: |
| print(f'Target os {os_name} is only supported on macOS') |
| return False |
| elif os_name != HOST_OS: |
| print("Unsupported target os %s" % os_name) |
| return False |
| if HOST_OS != 'win' and args.use_crashpad: |
| print("Crashpad is only supported on Windows") |
| return False |
| if not args.rbe and \ |
| (socket.getfqdn().endswith('.corp.google.com') or |
| socket.getfqdn().endswith('.c.googlers.com')): |
| print('You can speed up your build by following: go/dart-rbe') |
| old_rbe_cfg = 'win-intel.cfg' if HOST_OS == 'win32' else 'linux-intel.cfg' |
| new_rbe_cfg = 'windows.cfg' if HOST_OS == 'win32' else 'unix.cfg' |
| if os.environ.get('RBE_cfg') == os.path.join(os.getcwd(), 'build', 'rbe', |
| old_rbe_cfg): |
| print(f'warning: {old_rbe_cfg} is deprecated, please update your ' |
| f'RBE_cfg variable to {new_rbe_cfg} use RBE=1 instead per ' |
| 'go/dart-rbe') |
| return True |
| |
| |
| def os_has_ide(host_os): |
| return host_os.startswith('win') or host_os.startswith('mac') |
| |
| |
| def ide_switch(host_os): |
| if host_os.startswith('win'): |
| return '--ide=vs' |
| elif host_os.startswith('mac'): |
| return '--ide=xcode' |
| else: |
| return '--ide=json' |
| |
| |
| def AddCommonGnOptionArgs(parser): |
| """Adds arguments that will change the default GN arguments.""" |
| |
| parser.add_argument('--rbe', help='Use rbe', action='store_true') |
| parser.add_argument('--no-rbe', |
| help='Disable rbe', |
| dest='rbe', |
| action='store_false') |
| parser.set_defaults(rbe=os.environ.get('RBE') == '1' or \ |
| os.environ.get('DART_RBE') == '1' or \ |
| os.environ.get('RBE_cfg') != None) |
| parser.add_argument('--rbe-expensive-exec-strategy', |
| default=os.environ.get('RBE_exec_strategy'), |
| help='Strategy for expensive RBE compilations', |
| type=str) |
| |
| # Disable git hashes when remote compiling to ensure cache hits of the final |
| # output artifacts when nothing has changed. |
| parser.add_argument('--verify-sdk-hash', |
| help='Enable SDK hash checks', |
| dest='verify_sdk_hash', |
| action='store_true') |
| parser.add_argument('-nvh', |
| '--no-verify-sdk-hash', |
| help='Disable SDK hash checks', |
| dest='verify_sdk_hash', |
| action='store_false') |
| parser.set_defaults(verify_sdk_hash=None) |
| |
| parser.add_argument('--git-version', |
| help='Enable git commit in version', |
| dest='git_version', |
| action='store_true') |
| parser.add_argument('-ngv', |
| '--no-git-version', |
| help='Disable git commit in version', |
| dest='git_version', |
| action='store_false') |
| parser.set_defaults(git_version=None) |
| |
| parser.add_argument('--clang', help='Use Clang', action='store_true') |
| parser.add_argument('--no-clang', |
| help='Disable Clang', |
| dest='clang', |
| action='store_false') |
| parser.set_defaults(clang=True) |
| |
| parser.add_argument( |
| '--platform-sdk', |
| help='Directs the create_sdk target to create a smaller "Platform" SDK', |
| default=MakePlatformSDK(), |
| action='store_true') |
| parser.add_argument('--use-crashpad', |
| default=False, |
| dest='use_crashpad', |
| action='store_true') |
| parser.add_argument('--use-qemu', |
| default=False, |
| dest='use_qemu', |
| action='store_true') |
| parser.add_argument('--exclude-kernel-service', |
| help='Exclude the kernel service.', |
| default=False, |
| dest='exclude_kernel_service', |
| action='store_true') |
| parser.add_argument('--arm-float-abi', |
| type=str, |
| help='The ARM float ABI (soft, softfp, hard)', |
| metavar='[soft,softfp,hard]', |
| default='') |
| |
| parser.add_argument('--code-coverage', |
| help='Enable code coverage for the standalone VM', |
| default=False, |
| dest="code_coverage", |
| action='store_true') |
| parser.add_argument('--dart-dynamic-modules', |
| help='Enable Dart dynamic modules.', |
| default=False, |
| dest='dart_dynamic_modules', |
| action='store_true') |
| parser.add_argument('--debug-opt-level', |
| '-d', |
| help='The optimization level to use for debug builds', |
| type=str) |
| parser.add_argument('--gn-args', |
| help='Set extra GN args', |
| dest='gn_args', |
| action='append') |
| parser.add_argument( |
| '--toolchain-prefix', |
| '-t', |
| type=str, |
| help='Comma-separated list of arch=/path/to/toolchain-prefix mappings') |
| parser.add_argument('--ide', |
| help='Generate an IDE file.', |
| default=os_has_ide(HOST_OS), |
| action='store_true') |
| parser.add_argument('--export-compile-commands', |
| help='Export compile_commands.json database file.', |
| default=False, |
| action='store_true') |
| parser.add_argument( |
| '--target-sysroot', |
| '-s', |
| type=str, |
| help='Comma-separated list of arch=/path/to/sysroot mappings') |
| parser.add_argument('--use-mallinfo2', |
| help='Use mallinfo2 to collect malloc stats.', |
| default=False, |
| dest='use_mallinfo2', |
| action='store_true') |
| parser.add_argument('--codesigning-identity', |
| help='Sign executables using the given identity.', |
| default='', |
| type=str) |
| |
| |
| def AddCommonConfigurationArgs(parser): |
| """Adds arguments that influence which configuration will be built.""" |
| parser.add_argument("-a", |
| "--arch", |
| type=str, |
| help='Target architectures (comma-separated).', |
| metavar='[all,' + ','.join(AVAILABLE_ARCHS) + ']', |
| default=utils.GuessArchitecture()) |
| parser.add_argument('--mode', |
| '-m', |
| type=str, |
| help='Build variants (comma-separated).', |
| metavar='[all,debug,release,product]', |
| default='debug') |
| parser.add_argument('--os', |
| type=str, |
| help='Target OSs (comma-separated).', |
| metavar='[all,host,android,fuchsia,ios,ios_simulator]', |
| default='host') |
| parser.add_argument('--sanitizer', |
| type=str, |
| help='Build variants (comma-separated).', |
| metavar='[all,none,asan,lsan,msan,tsan,ubsan]', |
| default='none') |
| |
| |
| def AddOtherArgs(parser): |
| """Adds miscellaneous arguments to the parser.""" |
| parser.add_argument("-v", |
| "--verbose", |
| help='Verbose output.', |
| default=False, |
| action="store_true") |
| parser.add_argument("--test", |
| help='Test this script.', |
| default=False, |
| action="store_true") |
| |
| |
| def parse_args(args): |
| args = args[1:] |
| parser = argparse.ArgumentParser( |
| description='A script to run `gn gen`.', |
| formatter_class=argparse.ArgumentDefaultsHelpFormatter) |
| |
| config_group = parser.add_argument_group('Configuration Related Arguments') |
| AddCommonConfigurationArgs(config_group) |
| |
| gn_group = parser.add_argument_group('GN Related Arguments') |
| AddCommonGnOptionArgs(gn_group) |
| |
| other_group = parser.add_argument_group('Other Arguments') |
| AddOtherArgs(other_group) |
| |
| options = parser.parse_args(args) |
| if not ProcessOptions(options): |
| parser.print_help() |
| return None |
| return options |
| |
| |
| def InitializeRBE(out_dir, env): |
| RBE_cfg = 'RBE_CFG' if HOST_OS == 'win32' else 'RBE_cfg' |
| RBE_server_address = ('RBE_SERVER_ADDRESS' |
| if HOST_OS == 'win32' else 'RBE_server_address') |
| # Default RBE_cfg to the appropriate configuration file. |
| if not RBE_cfg in env: |
| env[RBE_cfg] = os.path.join( |
| os.getcwd(), 'build', 'rbe', |
| 'windows.cfg' if HOST_OS == 'win32' else 'unix.cfg') |
| # Default RBE_server_address to inside the build directory. |
| if not RBE_server_address in env: |
| with open(env[RBE_cfg], 'r') as f: |
| if not any([l.startswith('server_address') for l in f.readlines()]): |
| schema = 'pipe' if HOST_OS == 'win32' else 'unix' |
| socket = os.path.join(os.getcwd(), out_dir, 'reproxy.sock') |
| if HOST_OS == 'win32': |
| socket = socket.replace('\\', '_').replace(':', '_') |
| env[RBE_server_address] = f'{schema}://{socket}' |
| |
| |
| def ExecutableName(basename): |
| if utils.IsWindows(): |
| return f'{basename}.exe' |
| return basename |
| |
| |
| def BuildGnCommand(args, mode, arch, target_os, sanitizer, out_dir): |
| if utils.IsWindows(): |
| gn = os.path.join(DART_ROOT, 'buildtools', 'win', 'gn.exe') |
| else: |
| gn = os.path.join(DART_ROOT, 'buildtools', 'gn') |
| if not os.path.isfile(gn): |
| raise Exception("Couldn't find the gn binary at path: " + gn) |
| |
| # TODO(infra): Re-enable --check. Many targets fail to use |
| # public_deps to re-expose header files to their dependents. |
| # See dartbug.com/32364 |
| command = [gn, 'gen', out_dir] |
| gn_args = ToCommandLine( |
| ToGnArgs(args, mode, arch, target_os, sanitizer, args.verify_sdk_hash, |
| args.git_version)) |
| gn_args += GetGNArgs(args) |
| if args.ide: |
| command.append(ide_switch(HOST_OS)) |
| if args.export_compile_commands: |
| command.append('--export-compile-commands') |
| command.append('--args=%s' % ' '.join(gn_args)) |
| |
| return command |
| |
| |
| def RunGnOnConfiguredConfigurations(args, env={}): |
| initialized_rbe = False |
| commands = [] |
| for target_os in args.os: |
| for mode in args.mode: |
| for arch in args.arch: |
| for sanitizer in args.sanitizer: |
| out_dir = GetOutDir(mode, arch, target_os, sanitizer) |
| if args.rbe and not initialized_rbe: |
| InitializeRBE(out_dir, env) |
| initialized_rbe = True |
| commands.append( |
| BuildGnCommand(args, mode, arch, target_os, sanitizer, |
| out_dir)) |
| if args.verbose: |
| print("gn gen --check in %s" % out_dir) |
| |
| active_commands = [] |
| |
| def cleanup(command): |
| print("Command failed: " + ' '.join(command)) |
| for (_, process) in active_commands: |
| process.terminate() |
| |
| for command in commands: |
| try: |
| process = subprocess.Popen(command, cwd=DART_ROOT, env=env) |
| active_commands.append([command, process]) |
| except Exception as e: |
| print('Error: %s' % e) |
| cleanup(command) |
| return 1 |
| while active_commands: |
| time.sleep(0.1) |
| for active_command in active_commands: |
| (command, process) = active_command |
| if process.poll() is not None: |
| active_commands.remove(active_command) |
| if process.returncode != 0: |
| cleanup(command) |
| return 1 |
| return 0 |
| |
| |
| def ExpectEquals(actual, expected): |
| if actual != expected: |
| raise Exception(f"Actual: {actual} Expected: {expected}") |
| |
| |
| def RunTests(): |
| host_arch = utils.HostArchitectures()[0] |
| host_arch_or_x64 = host_arch |
| if 'x64' in utils.HostArchitectures(): |
| # Rosetta means 'x64' may be built directly. |
| host_arch_or_x64 = 'x64' |
| |
| ExpectEquals(HostCpuForArch("arm64"), host_arch) |
| ExpectEquals(HostCpuForArch("arm64c"), host_arch) |
| ExpectEquals(HostCpuForArch("simarm64"), host_arch) |
| ExpectEquals(HostCpuForArch("simarm64_x64"), host_arch_or_x64) |
| ExpectEquals(HostCpuForArch("simarm64_arm64"), host_arch) |
| ExpectEquals(HostCpuForArch("simarm64_riscv64"), host_arch) |
| ExpectEquals(HostCpuForArch("x64"), host_arch_or_x64) |
| ExpectEquals(HostCpuForArch("simx64"), host_arch_or_x64) |
| ExpectEquals(HostCpuForArch("simx64_x64"), host_arch_or_x64) |
| ExpectEquals(HostCpuForArch("simx64_arm64"), host_arch) |
| ExpectEquals(HostCpuForArch("simx64_riscv64"), host_arch) |
| |
| ExpectEquals(TargetCpuForArch("arm64"), "arm64") |
| ExpectEquals(TargetCpuForArch("arm64c"), "arm64") |
| ExpectEquals(TargetCpuForArch("simarm64"), host_arch) |
| ExpectEquals(TargetCpuForArch("simarm64_x64"), "x64") |
| ExpectEquals(TargetCpuForArch("simarm64_arm64"), "arm64") |
| ExpectEquals(TargetCpuForArch("simarm64_riscv64"), "riscv64") |
| ExpectEquals(TargetCpuForArch("x64"), "x64") |
| ExpectEquals(TargetCpuForArch("simx64"), host_arch) |
| ExpectEquals(TargetCpuForArch("simx64_x64"), "x64") |
| ExpectEquals(TargetCpuForArch("simx64_arm64"), "arm64") |
| ExpectEquals(TargetCpuForArch("simx64_riscv64"), "riscv64") |
| |
| ExpectEquals(DartTargetCpuForArch("arm64"), "arm64") |
| ExpectEquals(DartTargetCpuForArch("arm64c"), "arm64") |
| ExpectEquals(DartTargetCpuForArch("simarm64"), "arm64") |
| ExpectEquals(DartTargetCpuForArch("simarm64_x64"), "arm64") |
| ExpectEquals(DartTargetCpuForArch("simarm64_arm64"), "arm64") |
| ExpectEquals(DartTargetCpuForArch("simarm64_riscv64"), "arm64") |
| ExpectEquals(DartTargetCpuForArch("x64"), "x64") |
| ExpectEquals(DartTargetCpuForArch("simx64"), "x64") |
| ExpectEquals(DartTargetCpuForArch("simx64_x64"), "x64") |
| ExpectEquals(DartTargetCpuForArch("simx64_arm64"), "x64") |
| ExpectEquals(DartTargetCpuForArch("simx64_riscv64"), "x64") |
| |
| ExpectEquals(IsCompressedPointerArch("arm64c"), True) |
| ExpectEquals(IsCompressedPointerArch("simarm64c"), True) |
| ExpectEquals(IsCompressedPointerArch("simarm64c_x64"), True) |
| ExpectEquals(IsCompressedPointerArch("x64c"), True) |
| ExpectEquals(IsCompressedPointerArch("simx64c"), True) |
| ExpectEquals(IsCompressedPointerArch("simx64c_x64"), True) |
| ExpectEquals(IsCompressedPointerArch("arm64"), False) |
| ExpectEquals(IsCompressedPointerArch("simarm64"), False) |
| ExpectEquals(IsCompressedPointerArch("simarm64_x64"), False) |
| ExpectEquals(IsCompressedPointerArch("x64"), False) |
| ExpectEquals(IsCompressedPointerArch("simx64"), False) |
| ExpectEquals(IsCompressedPointerArch("simx64_x64"), False) |
| |
| # Our Android bots: |
| ExpectEquals(HostCpuForArch("arm64c"), host_arch) |
| ExpectEquals(TargetCpuForArch("arm64c"), 'arm64') |
| ExpectEquals(DartTargetCpuForArch("arm64c"), 'arm64') |
| ExpectEquals(HostCpuForArch("arm_x64"), host_arch_or_x64) |
| ExpectEquals(TargetCpuForArch("arm_x64"), 'arm') |
| ExpectEquals(DartTargetCpuForArch("arm_x64"), 'arm') |
| |
| |
| def Main(argv): |
| starttime = time.time() |
| |
| args = parse_args(argv) |
| if args is None: |
| return 1 |
| |
| if args.test: |
| RunTests() |
| print("Tests passed.") |
| return 0 |
| |
| result = RunGnOnConfiguredConfigurations(args) |
| |
| if args.verbose: |
| endtime = time.time() |
| print("GN Time: %.3f seconds" % (endtime - starttime)) |
| |
| return result |
| |
| |
| if __name__ == '__main__': |
| sys.exit(Main(sys.argv)) |