xref: /aosp_15_r20/external/crosvm/tools/windows/build_test.py (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*bb4ee6a4SAndroid Build Coastguard Worker# Copyright 2017 The ChromiumOS Authors
3*bb4ee6a4SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
4*bb4ee6a4SAndroid Build Coastguard Worker# found in the LICENSE file.
5*bb4ee6a4SAndroid Build Coastguard Worker
6*bb4ee6a4SAndroid Build Coastguard Worker"""Builds crosvm in debug/release mode on all supported target architectures.
7*bb4ee6a4SAndroid Build Coastguard Worker
8*bb4ee6a4SAndroid Build Coastguard WorkerA sysroot for each target architectures is required. The defaults are all generic boards' sysroots,
9*bb4ee6a4SAndroid Build Coastguard Workerbut they can be changed with the command line arguments.
10*bb4ee6a4SAndroid Build Coastguard Worker
11*bb4ee6a4SAndroid Build Coastguard WorkerTo test changes more quickly, set the --noclean option. This prevents the target directories from
12*bb4ee6a4SAndroid Build Coastguard Workerbeing removed before building and testing.
13*bb4ee6a4SAndroid Build Coastguard Worker
14*bb4ee6a4SAndroid Build Coastguard WorkerFor easy binary size comparison, use the --size-only option to only do builds that will result in a
15*bb4ee6a4SAndroid Build Coastguard Workerbinary size output, which are non-test release builds.
16*bb4ee6a4SAndroid Build Coastguard Worker
17*bb4ee6a4SAndroid Build Coastguard WorkerThis script automatically determines which packages will need to be tested based on the directory
18*bb4ee6a4SAndroid Build Coastguard Workerstructure with Cargo.toml files. Only top-level crates are tested directly. To skip a top-level
19*bb4ee6a4SAndroid Build Coastguard Workerpackage, add an empty .build_test_skip file to the directory. Rarely, if a package needs to have its
20*bb4ee6a4SAndroid Build Coastguard Workertests run single-threaded, add an empty .build_test_serial file to the directory.
21*bb4ee6a4SAndroid Build Coastguard Worker"""
22*bb4ee6a4SAndroid Build Coastguard Worker
23*bb4ee6a4SAndroid Build Coastguard Workerfrom __future__ import print_function
24*bb4ee6a4SAndroid Build Coastguard Workerimport argparse
25*bb4ee6a4SAndroid Build Coastguard Workerimport functools
26*bb4ee6a4SAndroid Build Coastguard Workerimport multiprocessing.pool
27*bb4ee6a4SAndroid Build Coastguard Workerimport os
28*bb4ee6a4SAndroid Build Coastguard Workerimport shutil
29*bb4ee6a4SAndroid Build Coastguard Workerimport subprocess
30*bb4ee6a4SAndroid Build Coastguard Workerimport sys
31*bb4ee6a4SAndroid Build Coastguard Worker
32*bb4ee6a4SAndroid Build Coastguard Workersys.path.append(os.path.dirname(sys.path[0]))
33*bb4ee6a4SAndroid Build Coastguard Worker
34*bb4ee6a4SAndroid Build Coastguard Workerfrom enabled_features import ENABLED_FEATURES, BUILD_FEATURES
35*bb4ee6a4SAndroid Build Coastguard Workerfrom files_to_include import DLLS, BINARIES
36*bb4ee6a4SAndroid Build Coastguard Workerfrom prepare_dlls import build_dlls, copy_dlls
37*bb4ee6a4SAndroid Build Coastguard Worker
38*bb4ee6a4SAndroid Build Coastguard Worker# Is Windows
39*bb4ee6a4SAndroid Build Coastguard WorkerIS_WINDOWS = os.name == "nt"
40*bb4ee6a4SAndroid Build Coastguard Worker
41*bb4ee6a4SAndroid Build Coastguard WorkerARM_TRIPLE = os.getenv("ARM_TRIPLE", "armv7a-cros-linux-gnueabihf")
42*bb4ee6a4SAndroid Build Coastguard WorkerAARCH64_TRIPLE = os.getenv("AARCH64_TRIPLE", "aarch64-cros-linux-gnu")
43*bb4ee6a4SAndroid Build Coastguard WorkerX86_64_TRIPLE = os.getenv("X86_64_TRIPLE", "x86_64-unknown-linux-gnu")
44*bb4ee6a4SAndroid Build Coastguard WorkerX86_64_WIN_MSVC_TRIPLE = os.getenv("X86_64_WIN_MSVC_TRIPLE", "x86_64-pc-windows-msvc")
45*bb4ee6a4SAndroid Build Coastguard WorkerSYMBOL_EXPORTS = ["NvOptimusEnablement", "AmdPowerXpressRequestHighPerformance"]
46*bb4ee6a4SAndroid Build Coastguard Worker
47*bb4ee6a4SAndroid Build Coastguard WorkerLINUX_BUILD_ONLY_MODULES = [
48*bb4ee6a4SAndroid Build Coastguard Worker    "io_jail",
49*bb4ee6a4SAndroid Build Coastguard Worker    "poll_token_derive",
50*bb4ee6a4SAndroid Build Coastguard Worker    "wire_format_derive",
51*bb4ee6a4SAndroid Build Coastguard Worker    "bit_field_derive",
52*bb4ee6a4SAndroid Build Coastguard Worker    "linux_input_sys",
53*bb4ee6a4SAndroid Build Coastguard Worker    "vfio_sys",
54*bb4ee6a4SAndroid Build Coastguard Worker]
55*bb4ee6a4SAndroid Build Coastguard Worker
56*bb4ee6a4SAndroid Build Coastguard Worker# Bright green.
57*bb4ee6a4SAndroid Build Coastguard WorkerPASS_COLOR = "\033[1;32m"
58*bb4ee6a4SAndroid Build Coastguard Worker# Bright red.
59*bb4ee6a4SAndroid Build Coastguard WorkerFAIL_COLOR = "\033[1;31m"
60*bb4ee6a4SAndroid Build Coastguard Worker# Default color.
61*bb4ee6a4SAndroid Build Coastguard WorkerEND_COLOR = "\033[0m"
62*bb4ee6a4SAndroid Build Coastguard Worker
63*bb4ee6a4SAndroid Build Coastguard Worker
64*bb4ee6a4SAndroid Build Coastguard Workerdef crosvm_binary_name():
65*bb4ee6a4SAndroid Build Coastguard Worker    return "crosvm.exe" if IS_WINDOWS else "crosvm"
66*bb4ee6a4SAndroid Build Coastguard Worker
67*bb4ee6a4SAndroid Build Coastguard Worker
68*bb4ee6a4SAndroid Build Coastguard Workerdef get_target_path(triple, kind, test_it):
69*bb4ee6a4SAndroid Build Coastguard Worker    """Constructs a target path based on the configuration parameters.
70*bb4ee6a4SAndroid Build Coastguard Worker
71*bb4ee6a4SAndroid Build Coastguard Worker    Args:
72*bb4ee6a4SAndroid Build Coastguard Worker      triple: Target triple. Example: 'x86_64-unknown-linux-gnu'.
73*bb4ee6a4SAndroid Build Coastguard Worker      kind: 'debug' or 'release'.
74*bb4ee6a4SAndroid Build Coastguard Worker      test_it: If this target is tested.
75*bb4ee6a4SAndroid Build Coastguard Worker    """
76*bb4ee6a4SAndroid Build Coastguard Worker    target_path = os.path.abspath(os.path.join(os.sep, "tmp", "{}_{}".format(triple, kind)))
77*bb4ee6a4SAndroid Build Coastguard Worker    if test_it:
78*bb4ee6a4SAndroid Build Coastguard Worker        target_path += "_test"
79*bb4ee6a4SAndroid Build Coastguard Worker    return target_path
80*bb4ee6a4SAndroid Build Coastguard Worker
81*bb4ee6a4SAndroid Build Coastguard Worker
82*bb4ee6a4SAndroid Build Coastguard Workerdef validate_symbols(triple, is_release):
83*bb4ee6a4SAndroid Build Coastguard Worker    kind = "release" if is_release else "debug"
84*bb4ee6a4SAndroid Build Coastguard Worker    target_path = get_target_path(triple, kind, False)
85*bb4ee6a4SAndroid Build Coastguard Worker    binary_path = os.path.join(target_path, triple, kind, crosvm_binary_name())
86*bb4ee6a4SAndroid Build Coastguard Worker    with open(binary_path, mode="rb") as f:
87*bb4ee6a4SAndroid Build Coastguard Worker        contents = f.read().decode("ascii", errors="ignore")
88*bb4ee6a4SAndroid Build Coastguard Worker        return all(symbol in contents for symbol in SYMBOL_EXPORTS)
89*bb4ee6a4SAndroid Build Coastguard Worker
90*bb4ee6a4SAndroid Build Coastguard Worker
91*bb4ee6a4SAndroid Build Coastguard Workerdef build_target(
92*bb4ee6a4SAndroid Build Coastguard Worker    triple,
93*bb4ee6a4SAndroid Build Coastguard Worker    is_release,
94*bb4ee6a4SAndroid Build Coastguard Worker    env,
95*bb4ee6a4SAndroid Build Coastguard Worker    only_build_targets,
96*bb4ee6a4SAndroid Build Coastguard Worker    test_module_parallel,
97*bb4ee6a4SAndroid Build Coastguard Worker    test_module_serial,
98*bb4ee6a4SAndroid Build Coastguard Worker):
99*bb4ee6a4SAndroid Build Coastguard Worker    """Does a cargo build for the triple in release or debug mode.
100*bb4ee6a4SAndroid Build Coastguard Worker
101*bb4ee6a4SAndroid Build Coastguard Worker    Args:
102*bb4ee6a4SAndroid Build Coastguard Worker      triple: Target triple. Example: 'x86_64-unknown-linux-gnu'.
103*bb4ee6a4SAndroid Build Coastguard Worker      is_release: True to build a release version.
104*bb4ee6a4SAndroid Build Coastguard Worker      env: Enviroment variables to run cargo with.
105*bb4ee6a4SAndroid Build Coastguard Worker      only_build_targets: Only build packages that will be tested.
106*bb4ee6a4SAndroid Build Coastguard Worker    """
107*bb4ee6a4SAndroid Build Coastguard Worker    args = ["cargo", "build", "--target=%s" % triple]
108*bb4ee6a4SAndroid Build Coastguard Worker
109*bb4ee6a4SAndroid Build Coastguard Worker    if is_release:
110*bb4ee6a4SAndroid Build Coastguard Worker        args.append("--release")
111*bb4ee6a4SAndroid Build Coastguard Worker
112*bb4ee6a4SAndroid Build Coastguard Worker    if only_build_targets:
113*bb4ee6a4SAndroid Build Coastguard Worker        test_modules = test_module_parallel + test_module_serial
114*bb4ee6a4SAndroid Build Coastguard Worker        if not IS_WINDOWS:
115*bb4ee6a4SAndroid Build Coastguard Worker            test_modules += LINUX_BUILD_ONLY_MODULES
116*bb4ee6a4SAndroid Build Coastguard Worker        for mod in test_modules:
117*bb4ee6a4SAndroid Build Coastguard Worker            args.append("-p")
118*bb4ee6a4SAndroid Build Coastguard Worker            args.append(mod)
119*bb4ee6a4SAndroid Build Coastguard Worker
120*bb4ee6a4SAndroid Build Coastguard Worker    args.append("--features")
121*bb4ee6a4SAndroid Build Coastguard Worker    args.append(",".join(BUILD_FEATURES))
122*bb4ee6a4SAndroid Build Coastguard Worker
123*bb4ee6a4SAndroid Build Coastguard Worker    if subprocess.Popen(args, env=env).wait() != 0:
124*bb4ee6a4SAndroid Build Coastguard Worker        return False, "build error"
125*bb4ee6a4SAndroid Build Coastguard Worker    if IS_WINDOWS and not validate_symbols(triple, is_release):
126*bb4ee6a4SAndroid Build Coastguard Worker        return False, "error validating discrete gpu symbols"
127*bb4ee6a4SAndroid Build Coastguard Worker
128*bb4ee6a4SAndroid Build Coastguard Worker    return True, "pass"
129*bb4ee6a4SAndroid Build Coastguard Worker
130*bb4ee6a4SAndroid Build Coastguard Worker
131*bb4ee6a4SAndroid Build Coastguard Workerdef test_target_modules(triple, is_release, env, no_run, modules, parallel):
132*bb4ee6a4SAndroid Build Coastguard Worker    """Does a cargo test on given modules for the triple and configuration.
133*bb4ee6a4SAndroid Build Coastguard Worker
134*bb4ee6a4SAndroid Build Coastguard Worker    Args:
135*bb4ee6a4SAndroid Build Coastguard Worker      triple: Target triple. Example: 'x86_64-unknown-linux-gnu'.
136*bb4ee6a4SAndroid Build Coastguard Worker      is_release: True to build a release version.
137*bb4ee6a4SAndroid Build Coastguard Worker      env: Enviroment variables to run cargo with.
138*bb4ee6a4SAndroid Build Coastguard Worker      no_run: True to pass --no-run flag to cargo test.
139*bb4ee6a4SAndroid Build Coastguard Worker      modules: List of module strings to test.
140*bb4ee6a4SAndroid Build Coastguard Worker      parallel: True to run the tests in parallel threads.
141*bb4ee6a4SAndroid Build Coastguard Worker    """
142*bb4ee6a4SAndroid Build Coastguard Worker    args = ["cargo", "test", "--target=%s" % triple]
143*bb4ee6a4SAndroid Build Coastguard Worker
144*bb4ee6a4SAndroid Build Coastguard Worker    if is_release:
145*bb4ee6a4SAndroid Build Coastguard Worker        args.append("--release")
146*bb4ee6a4SAndroid Build Coastguard Worker
147*bb4ee6a4SAndroid Build Coastguard Worker    if no_run:
148*bb4ee6a4SAndroid Build Coastguard Worker        args.append("--no-run")
149*bb4ee6a4SAndroid Build Coastguard Worker
150*bb4ee6a4SAndroid Build Coastguard Worker    for mod in modules:
151*bb4ee6a4SAndroid Build Coastguard Worker        args.append("-p")
152*bb4ee6a4SAndroid Build Coastguard Worker        args.append(mod)
153*bb4ee6a4SAndroid Build Coastguard Worker
154*bb4ee6a4SAndroid Build Coastguard Worker    args.append("--features")
155*bb4ee6a4SAndroid Build Coastguard Worker    args.append(",".join(ENABLED_FEATURES))
156*bb4ee6a4SAndroid Build Coastguard Worker
157*bb4ee6a4SAndroid Build Coastguard Worker    if not parallel:
158*bb4ee6a4SAndroid Build Coastguard Worker        args.append("--")
159*bb4ee6a4SAndroid Build Coastguard Worker        args.append("--test-threads=1")
160*bb4ee6a4SAndroid Build Coastguard Worker    return subprocess.Popen(args, env=env).wait() == 0
161*bb4ee6a4SAndroid Build Coastguard Worker
162*bb4ee6a4SAndroid Build Coastguard Worker
163*bb4ee6a4SAndroid Build Coastguard Workerdef test_target(triple, is_release, env, no_run, test_modules_parallel, test_modules_serial):
164*bb4ee6a4SAndroid Build Coastguard Worker    """Does a cargo test for the given triple and configuration.
165*bb4ee6a4SAndroid Build Coastguard Worker
166*bb4ee6a4SAndroid Build Coastguard Worker    Args:
167*bb4ee6a4SAndroid Build Coastguard Worker      triple: Target triple. Example: 'x86_64-unknown-linux-gnu'.
168*bb4ee6a4SAndroid Build Coastguard Worker      is_release: True to build a release version.
169*bb4ee6a4SAndroid Build Coastguard Worker      env: Enviroment variables to run cargo with.
170*bb4ee6a4SAndroid Build Coastguard Worker      no_run: True to pass --no-run flag to cargo test.
171*bb4ee6a4SAndroid Build Coastguard Worker    """
172*bb4ee6a4SAndroid Build Coastguard Worker
173*bb4ee6a4SAndroid Build Coastguard Worker    parallel_result = test_target_modules(
174*bb4ee6a4SAndroid Build Coastguard Worker        triple, is_release, env, no_run, test_modules_parallel, True
175*bb4ee6a4SAndroid Build Coastguard Worker    )
176*bb4ee6a4SAndroid Build Coastguard Worker
177*bb4ee6a4SAndroid Build Coastguard Worker    serial_result = test_target_modules(triple, is_release, env, no_run, test_modules_serial, False)
178*bb4ee6a4SAndroid Build Coastguard Worker
179*bb4ee6a4SAndroid Build Coastguard Worker    return parallel_result and serial_result
180*bb4ee6a4SAndroid Build Coastguard Worker
181*bb4ee6a4SAndroid Build Coastguard Worker
182*bb4ee6a4SAndroid Build Coastguard Workerdef build_or_test(
183*bb4ee6a4SAndroid Build Coastguard Worker    sysroot,
184*bb4ee6a4SAndroid Build Coastguard Worker    triple,
185*bb4ee6a4SAndroid Build Coastguard Worker    kind,
186*bb4ee6a4SAndroid Build Coastguard Worker    skip_file_name,
187*bb4ee6a4SAndroid Build Coastguard Worker    test_it=False,
188*bb4ee6a4SAndroid Build Coastguard Worker    no_run=False,
189*bb4ee6a4SAndroid Build Coastguard Worker    clean=False,
190*bb4ee6a4SAndroid Build Coastguard Worker    copy_output=False,
191*bb4ee6a4SAndroid Build Coastguard Worker    copy_directory=None,
192*bb4ee6a4SAndroid Build Coastguard Worker    only_build_targets=False,
193*bb4ee6a4SAndroid Build Coastguard Worker):
194*bb4ee6a4SAndroid Build Coastguard Worker    """Runs relevant builds/tests for the given triple and configuration
195*bb4ee6a4SAndroid Build Coastguard Worker
196*bb4ee6a4SAndroid Build Coastguard Worker    Args:
197*bb4ee6a4SAndroid Build Coastguard Worker      sysroot: path to the target's sysroot directory.
198*bb4ee6a4SAndroid Build Coastguard Worker      triple: Target triple. Example: 'x86_64-unknown-linux-gnu'.
199*bb4ee6a4SAndroid Build Coastguard Worker      kind: 'debug' or 'release'.
200*bb4ee6a4SAndroid Build Coastguard Worker      skip_file_name: Skips building and testing a crate if this file is found in
201*bb4ee6a4SAndroid Build Coastguard Worker                      crate's root directory.
202*bb4ee6a4SAndroid Build Coastguard Worker      test_it: True to test this triple and kind.
203*bb4ee6a4SAndroid Build Coastguard Worker      no_run: True to just compile and not run tests (only if test_it=True)
204*bb4ee6a4SAndroid Build Coastguard Worker      clean: True to skip cleaning the target path.
205*bb4ee6a4SAndroid Build Coastguard Worker      copy_output: True to copy build artifacts to external directory.
206*bb4ee6a4SAndroid Build Coastguard Worker      output_directory: Destination of copy of build artifacts.
207*bb4ee6a4SAndroid Build Coastguard Worker      only_build_targets: Only build packages that will be tested.
208*bb4ee6a4SAndroid Build Coastguard Worker    """
209*bb4ee6a4SAndroid Build Coastguard Worker    if not os.path.isdir(sysroot) and not IS_WINDOWS:
210*bb4ee6a4SAndroid Build Coastguard Worker        return False, "sysroot missing"
211*bb4ee6a4SAndroid Build Coastguard Worker
212*bb4ee6a4SAndroid Build Coastguard Worker    target_path = get_target_path(triple, kind, test_it)
213*bb4ee6a4SAndroid Build Coastguard Worker
214*bb4ee6a4SAndroid Build Coastguard Worker    if clean:
215*bb4ee6a4SAndroid Build Coastguard Worker        shutil.rmtree(target_path, True)
216*bb4ee6a4SAndroid Build Coastguard Worker
217*bb4ee6a4SAndroid Build Coastguard Worker    is_release = kind == "release"
218*bb4ee6a4SAndroid Build Coastguard Worker
219*bb4ee6a4SAndroid Build Coastguard Worker    env = os.environ.copy()
220*bb4ee6a4SAndroid Build Coastguard Worker    env["TARGET_CC"] = "%s-clang" % triple
221*bb4ee6a4SAndroid Build Coastguard Worker    env["SYSROOT"] = sysroot
222*bb4ee6a4SAndroid Build Coastguard Worker    env["CARGO_TARGET_DIR"] = target_path
223*bb4ee6a4SAndroid Build Coastguard Worker
224*bb4ee6a4SAndroid Build Coastguard Worker    if not IS_WINDOWS:
225*bb4ee6a4SAndroid Build Coastguard Worker        # The lib dir could be in either lib or lib64 depending on the target. Rather than checking to see
226*bb4ee6a4SAndroid Build Coastguard Worker        # which one is valid, just add both and let the dynamic linker and pkg-config search.
227*bb4ee6a4SAndroid Build Coastguard Worker        libdir = os.path.join(sysroot, "usr", "lib")
228*bb4ee6a4SAndroid Build Coastguard Worker        lib64dir = os.path.join(sysroot, "usr", "lib64")
229*bb4ee6a4SAndroid Build Coastguard Worker        libdir_pc = os.path.join(libdir, "pkgconfig")
230*bb4ee6a4SAndroid Build Coastguard Worker        lib64dir_pc = os.path.join(lib64dir, "pkgconfig")
231*bb4ee6a4SAndroid Build Coastguard Worker
232*bb4ee6a4SAndroid Build Coastguard Worker        # This line that changes the dynamic library path is needed for upstream, but breaks
233*bb4ee6a4SAndroid Build Coastguard Worker        # downstream's crosvm linux kokoro presubmits.
234*bb4ee6a4SAndroid Build Coastguard Worker        # env['LD_LIBRARY_PATH'] = libdir + ':' + lib64dir
235*bb4ee6a4SAndroid Build Coastguard Worker        env["PKG_CONFIG_ALLOW_CROSS"] = "1"
236*bb4ee6a4SAndroid Build Coastguard Worker        env["PKG_CONFIG_LIBDIR"] = libdir_pc + ":" + lib64dir_pc
237*bb4ee6a4SAndroid Build Coastguard Worker        env["PKG_CONFIG_SYSROOT_DIR"] = sysroot
238*bb4ee6a4SAndroid Build Coastguard Worker        if "KOKORO_JOB_NAME" not in os.environ:
239*bb4ee6a4SAndroid Build Coastguard Worker            env["RUSTFLAGS"] = "-C linker=" + env["TARGET_CC"]
240*bb4ee6a4SAndroid Build Coastguard Worker            if is_release:
241*bb4ee6a4SAndroid Build Coastguard Worker                env["RUSTFLAGS"] += " -Cembed-bitcode=yes -Clto"
242*bb4ee6a4SAndroid Build Coastguard Worker
243*bb4ee6a4SAndroid Build Coastguard Worker    if IS_WINDOWS and not test_it:
244*bb4ee6a4SAndroid Build Coastguard Worker        for symbol in SYMBOL_EXPORTS:
245*bb4ee6a4SAndroid Build Coastguard Worker            env["RUSTFLAGS"] = env.get("RUSTFLAGS", "") + " -C link-args=/EXPORT:{}".format(symbol)
246*bb4ee6a4SAndroid Build Coastguard Worker
247*bb4ee6a4SAndroid Build Coastguard Worker    deps_dir = os.path.join(target_path, triple, kind, "deps")
248*bb4ee6a4SAndroid Build Coastguard Worker    if not os.path.exists(deps_dir):
249*bb4ee6a4SAndroid Build Coastguard Worker        os.makedirs(deps_dir)
250*bb4ee6a4SAndroid Build Coastguard Worker
251*bb4ee6a4SAndroid Build Coastguard Worker    target_dirs = [deps_dir]
252*bb4ee6a4SAndroid Build Coastguard Worker    if copy_output:
253*bb4ee6a4SAndroid Build Coastguard Worker        os.makedirs(os.path.join(copy_directory, kind), exist_ok=True)
254*bb4ee6a4SAndroid Build Coastguard Worker        if not test_it:
255*bb4ee6a4SAndroid Build Coastguard Worker            target_dirs.append(os.path.join(copy_directory, kind))
256*bb4ee6a4SAndroid Build Coastguard Worker
257*bb4ee6a4SAndroid Build Coastguard Worker    copy_dlls(os.getcwd(), target_dirs, kind)
258*bb4ee6a4SAndroid Build Coastguard Worker
259*bb4ee6a4SAndroid Build Coastguard Worker    (test_modules_parallel, test_modules_serial) = get_test_modules(skip_file_name)
260*bb4ee6a4SAndroid Build Coastguard Worker    print("modules to test in parallel:\n", test_modules_parallel)
261*bb4ee6a4SAndroid Build Coastguard Worker    print("modules to test serially:\n", test_modules_serial)
262*bb4ee6a4SAndroid Build Coastguard Worker
263*bb4ee6a4SAndroid Build Coastguard Worker    if not test_modules_parallel and not test_modules_serial:
264*bb4ee6a4SAndroid Build Coastguard Worker        print("All build and tests skipped.")
265*bb4ee6a4SAndroid Build Coastguard Worker        return True, "pass"
266*bb4ee6a4SAndroid Build Coastguard Worker
267*bb4ee6a4SAndroid Build Coastguard Worker    if test_it:
268*bb4ee6a4SAndroid Build Coastguard Worker        if not test_target(
269*bb4ee6a4SAndroid Build Coastguard Worker            triple, is_release, env, no_run, test_modules_parallel, test_modules_serial
270*bb4ee6a4SAndroid Build Coastguard Worker        ):
271*bb4ee6a4SAndroid Build Coastguard Worker            return False, "test error"
272*bb4ee6a4SAndroid Build Coastguard Worker    else:
273*bb4ee6a4SAndroid Build Coastguard Worker        res, err = build_target(
274*bb4ee6a4SAndroid Build Coastguard Worker            triple,
275*bb4ee6a4SAndroid Build Coastguard Worker            is_release,
276*bb4ee6a4SAndroid Build Coastguard Worker            env,
277*bb4ee6a4SAndroid Build Coastguard Worker            only_build_targets,
278*bb4ee6a4SAndroid Build Coastguard Worker            test_modules_parallel,
279*bb4ee6a4SAndroid Build Coastguard Worker            test_modules_serial,
280*bb4ee6a4SAndroid Build Coastguard Worker        )
281*bb4ee6a4SAndroid Build Coastguard Worker        if not res:
282*bb4ee6a4SAndroid Build Coastguard Worker            return res, err
283*bb4ee6a4SAndroid Build Coastguard Worker
284*bb4ee6a4SAndroid Build Coastguard Worker    # We only care about the non-test binaries, so only copy the output from cargo build.
285*bb4ee6a4SAndroid Build Coastguard Worker    if copy_output and not test_it:
286*bb4ee6a4SAndroid Build Coastguard Worker        binary_src = os.path.join(target_path, triple, kind, crosvm_binary_name())
287*bb4ee6a4SAndroid Build Coastguard Worker        pdb_src = binary_src.replace(".exe", "") + ".pdb"
288*bb4ee6a4SAndroid Build Coastguard Worker        binary_dst = os.path.join(copy_directory, kind)
289*bb4ee6a4SAndroid Build Coastguard Worker        shutil.copy(binary_src, binary_dst)
290*bb4ee6a4SAndroid Build Coastguard Worker        shutil.copy(pdb_src, binary_dst)
291*bb4ee6a4SAndroid Build Coastguard Worker
292*bb4ee6a4SAndroid Build Coastguard Worker    return True, "pass"
293*bb4ee6a4SAndroid Build Coastguard Worker
294*bb4ee6a4SAndroid Build Coastguard Worker
295*bb4ee6a4SAndroid Build Coastguard Workerdef get_test_modules(skip_file_name):
296*bb4ee6a4SAndroid Build Coastguard Worker    """Returns a list of modules to test.
297*bb4ee6a4SAndroid Build Coastguard Worker    Args:
298*bb4ee6a4SAndroid Build Coastguard Worker      skip_file_name: Skips building and testing a crate if this file is found in
299*bb4ee6a4SAndroid Build Coastguard Worker                      crate's root directory.
300*bb4ee6a4SAndroid Build Coastguard Worker    """
301*bb4ee6a4SAndroid Build Coastguard Worker    if IS_WINDOWS and not os.path.isfile(skip_file_name):
302*bb4ee6a4SAndroid Build Coastguard Worker        test_modules_parallel = ["crosvm"]
303*bb4ee6a4SAndroid Build Coastguard Worker    else:
304*bb4ee6a4SAndroid Build Coastguard Worker        test_modules_parallel = []
305*bb4ee6a4SAndroid Build Coastguard Worker    test_modules_serial = []
306*bb4ee6a4SAndroid Build Coastguard Worker
307*bb4ee6a4SAndroid Build Coastguard Worker    file_in_crate = lambda file_name: os.path.isfile(os.path.join(crate.path, file_name))
308*bb4ee6a4SAndroid Build Coastguard Worker    serial_file_name = "{}build_test_serial".format(".win_" if IS_WINDOWS else ".")
309*bb4ee6a4SAndroid Build Coastguard Worker    with os.scandir() as it:
310*bb4ee6a4SAndroid Build Coastguard Worker        for crate in it:
311*bb4ee6a4SAndroid Build Coastguard Worker            if file_in_crate("Cargo.toml"):
312*bb4ee6a4SAndroid Build Coastguard Worker                if file_in_crate(skip_file_name):
313*bb4ee6a4SAndroid Build Coastguard Worker                    continue
314*bb4ee6a4SAndroid Build Coastguard Worker                if file_in_crate(serial_file_name):
315*bb4ee6a4SAndroid Build Coastguard Worker                    test_modules_serial.append(crate.name)
316*bb4ee6a4SAndroid Build Coastguard Worker                else:
317*bb4ee6a4SAndroid Build Coastguard Worker                    test_modules_parallel.append(crate.name)
318*bb4ee6a4SAndroid Build Coastguard Worker
319*bb4ee6a4SAndroid Build Coastguard Worker    test_modules_parallel.sort()
320*bb4ee6a4SAndroid Build Coastguard Worker    test_modules_serial.sort()
321*bb4ee6a4SAndroid Build Coastguard Worker
322*bb4ee6a4SAndroid Build Coastguard Worker    return (test_modules_parallel, test_modules_serial)
323*bb4ee6a4SAndroid Build Coastguard Worker
324*bb4ee6a4SAndroid Build Coastguard Worker
325*bb4ee6a4SAndroid Build Coastguard Workerdef get_stripped_size(triple):
326*bb4ee6a4SAndroid Build Coastguard Worker    """Returns the formatted size of the given triple's release binary.
327*bb4ee6a4SAndroid Build Coastguard Worker
328*bb4ee6a4SAndroid Build Coastguard Worker    Args:
329*bb4ee6a4SAndroid Build Coastguard Worker      triple: Target triple. Example: 'x86_64-unknown-linux-gnu'.
330*bb4ee6a4SAndroid Build Coastguard Worker    """
331*bb4ee6a4SAndroid Build Coastguard Worker    target_path = get_target_path(triple, "release", False)
332*bb4ee6a4SAndroid Build Coastguard Worker    bin_path = os.path.join(target_path, triple, "release", crosvm_binary_name())
333*bb4ee6a4SAndroid Build Coastguard Worker    proc = subprocess.Popen(["%s-strip" % triple, bin_path])
334*bb4ee6a4SAndroid Build Coastguard Worker
335*bb4ee6a4SAndroid Build Coastguard Worker    if proc.wait() != 0:
336*bb4ee6a4SAndroid Build Coastguard Worker        return "failed"
337*bb4ee6a4SAndroid Build Coastguard Worker
338*bb4ee6a4SAndroid Build Coastguard Worker    return "%dKiB" % (os.path.getsize(bin_path) / 1024)
339*bb4ee6a4SAndroid Build Coastguard Worker
340*bb4ee6a4SAndroid Build Coastguard Worker
341*bb4ee6a4SAndroid Build Coastguard Workerdef get_parser():
342*bb4ee6a4SAndroid Build Coastguard Worker    """Gets the argument parser"""
343*bb4ee6a4SAndroid Build Coastguard Worker    parser = argparse.ArgumentParser(description=__doc__)
344*bb4ee6a4SAndroid Build Coastguard Worker    if IS_WINDOWS:
345*bb4ee6a4SAndroid Build Coastguard Worker        parser.add_argument(
346*bb4ee6a4SAndroid Build Coastguard Worker            "--x86_64-msvc-sysroot",
347*bb4ee6a4SAndroid Build Coastguard Worker            default="build/amd64-msvc",
348*bb4ee6a4SAndroid Build Coastguard Worker            help="x86_64 sysroot directory (default=%(default)s)",
349*bb4ee6a4SAndroid Build Coastguard Worker        )
350*bb4ee6a4SAndroid Build Coastguard Worker    else:
351*bb4ee6a4SAndroid Build Coastguard Worker        parser.add_argument(
352*bb4ee6a4SAndroid Build Coastguard Worker            "--arm-sysroot",
353*bb4ee6a4SAndroid Build Coastguard Worker            default="/build/arm-generic",
354*bb4ee6a4SAndroid Build Coastguard Worker            help="ARM sysroot directory (default=%(default)s)",
355*bb4ee6a4SAndroid Build Coastguard Worker        )
356*bb4ee6a4SAndroid Build Coastguard Worker        parser.add_argument(
357*bb4ee6a4SAndroid Build Coastguard Worker            "--aarch64-sysroot",
358*bb4ee6a4SAndroid Build Coastguard Worker            default="/build/arm64-generic",
359*bb4ee6a4SAndroid Build Coastguard Worker            help="AARCH64 sysroot directory (default=%(default)s)",
360*bb4ee6a4SAndroid Build Coastguard Worker        )
361*bb4ee6a4SAndroid Build Coastguard Worker        parser.add_argument(
362*bb4ee6a4SAndroid Build Coastguard Worker            "--x86_64-sysroot",
363*bb4ee6a4SAndroid Build Coastguard Worker            default="/build/amd64-generic",
364*bb4ee6a4SAndroid Build Coastguard Worker            help="x86_64 sysroot directory (default=%(default)s)",
365*bb4ee6a4SAndroid Build Coastguard Worker        )
366*bb4ee6a4SAndroid Build Coastguard Worker
367*bb4ee6a4SAndroid Build Coastguard Worker    parser.add_argument(
368*bb4ee6a4SAndroid Build Coastguard Worker        "--noclean",
369*bb4ee6a4SAndroid Build Coastguard Worker        dest="clean",
370*bb4ee6a4SAndroid Build Coastguard Worker        default=True,
371*bb4ee6a4SAndroid Build Coastguard Worker        action="store_false",
372*bb4ee6a4SAndroid Build Coastguard Worker        help="Keep the tempororary build directories.",
373*bb4ee6a4SAndroid Build Coastguard Worker    )
374*bb4ee6a4SAndroid Build Coastguard Worker    parser.add_argument(
375*bb4ee6a4SAndroid Build Coastguard Worker        "--copy",
376*bb4ee6a4SAndroid Build Coastguard Worker        default=False,
377*bb4ee6a4SAndroid Build Coastguard Worker        help="Copies .exe files to an output directory for later use",
378*bb4ee6a4SAndroid Build Coastguard Worker    )
379*bb4ee6a4SAndroid Build Coastguard Worker    parser.add_argument(
380*bb4ee6a4SAndroid Build Coastguard Worker        "--copy-directory",
381*bb4ee6a4SAndroid Build Coastguard Worker        default="/output",
382*bb4ee6a4SAndroid Build Coastguard Worker        help="Destination of .exe files when using --copy",
383*bb4ee6a4SAndroid Build Coastguard Worker    )
384*bb4ee6a4SAndroid Build Coastguard Worker    parser.add_argument(
385*bb4ee6a4SAndroid Build Coastguard Worker        "--serial",
386*bb4ee6a4SAndroid Build Coastguard Worker        default=True,
387*bb4ee6a4SAndroid Build Coastguard Worker        action="store_false",
388*bb4ee6a4SAndroid Build Coastguard Worker        dest="parallel",
389*bb4ee6a4SAndroid Build Coastguard Worker        help="Run cargo build serially rather than in parallel",
390*bb4ee6a4SAndroid Build Coastguard Worker    )
391*bb4ee6a4SAndroid Build Coastguard Worker    # TODO(b/154029826): Remove this option once all sysroots are available.
392*bb4ee6a4SAndroid Build Coastguard Worker    parser.add_argument(
393*bb4ee6a4SAndroid Build Coastguard Worker        "--x86_64-only",
394*bb4ee6a4SAndroid Build Coastguard Worker        default=False,
395*bb4ee6a4SAndroid Build Coastguard Worker        action="store_true",
396*bb4ee6a4SAndroid Build Coastguard Worker        help="Only runs tests on x86_64 sysroots",
397*bb4ee6a4SAndroid Build Coastguard Worker    )
398*bb4ee6a4SAndroid Build Coastguard Worker    parser.add_argument(
399*bb4ee6a4SAndroid Build Coastguard Worker        "--only-build-targets",
400*bb4ee6a4SAndroid Build Coastguard Worker        default=False,
401*bb4ee6a4SAndroid Build Coastguard Worker        action="store_true",
402*bb4ee6a4SAndroid Build Coastguard Worker        help="Builds only the tested modules. If false, builds the entire crate",
403*bb4ee6a4SAndroid Build Coastguard Worker    )
404*bb4ee6a4SAndroid Build Coastguard Worker    parser.add_argument(
405*bb4ee6a4SAndroid Build Coastguard Worker        "--size-only",
406*bb4ee6a4SAndroid Build Coastguard Worker        dest="size_only",
407*bb4ee6a4SAndroid Build Coastguard Worker        default=False,
408*bb4ee6a4SAndroid Build Coastguard Worker        action="store_true",
409*bb4ee6a4SAndroid Build Coastguard Worker        help="Only perform builds that output their binary size (i.e. release non-test).",
410*bb4ee6a4SAndroid Build Coastguard Worker    )
411*bb4ee6a4SAndroid Build Coastguard Worker    parser.add_argument(
412*bb4ee6a4SAndroid Build Coastguard Worker        "--job_type",
413*bb4ee6a4SAndroid Build Coastguard Worker        default="local",
414*bb4ee6a4SAndroid Build Coastguard Worker        choices=["kokoro", "local"],
415*bb4ee6a4SAndroid Build Coastguard Worker        help="Set to kokoro if this script is executed by a kokoro job, otherwise local",
416*bb4ee6a4SAndroid Build Coastguard Worker    )
417*bb4ee6a4SAndroid Build Coastguard Worker    parser.add_argument(
418*bb4ee6a4SAndroid Build Coastguard Worker        "--skip_file_name",
419*bb4ee6a4SAndroid Build Coastguard Worker        default=".win_build_test_skip" if IS_WINDOWS else ".build_test_skip",
420*bb4ee6a4SAndroid Build Coastguard Worker        choices=[
421*bb4ee6a4SAndroid Build Coastguard Worker            ".build_test_skip",
422*bb4ee6a4SAndroid Build Coastguard Worker            ".win_build_test_skip",
423*bb4ee6a4SAndroid Build Coastguard Worker            ".windows_build_test_skip",
424*bb4ee6a4SAndroid Build Coastguard Worker        ],
425*bb4ee6a4SAndroid Build Coastguard Worker        help="Skips building and testing a crate if the crate contains specified file in its root directory.",
426*bb4ee6a4SAndroid Build Coastguard Worker    )
427*bb4ee6a4SAndroid Build Coastguard Worker    parser.add_argument(
428*bb4ee6a4SAndroid Build Coastguard Worker        "--build_mode",
429*bb4ee6a4SAndroid Build Coastguard Worker        default="release",
430*bb4ee6a4SAndroid Build Coastguard Worker        choices=["release", "debug"],
431*bb4ee6a4SAndroid Build Coastguard Worker        help="Build mode of the binaries.",
432*bb4ee6a4SAndroid Build Coastguard Worker    )
433*bb4ee6a4SAndroid Build Coastguard Worker
434*bb4ee6a4SAndroid Build Coastguard Worker    return parser
435*bb4ee6a4SAndroid Build Coastguard Worker
436*bb4ee6a4SAndroid Build Coastguard Worker
437*bb4ee6a4SAndroid Build Coastguard Workerdef main(argv):
438*bb4ee6a4SAndroid Build Coastguard Worker    opts = get_parser().parse_args(argv)
439*bb4ee6a4SAndroid Build Coastguard Worker    os.environ["RUST_BACKTRACE"] = "1"
440*bb4ee6a4SAndroid Build Coastguard Worker    if IS_WINDOWS:
441*bb4ee6a4SAndroid Build Coastguard Worker        if opts.build_mode == "release":
442*bb4ee6a4SAndroid Build Coastguard Worker            build_test_cases = [
443*bb4ee6a4SAndroid Build Coastguard Worker                # (sysroot path, target triple, debug/release, skip_file_name, should test?)
444*bb4ee6a4SAndroid Build Coastguard Worker                (
445*bb4ee6a4SAndroid Build Coastguard Worker                    opts.x86_64_msvc_sysroot,
446*bb4ee6a4SAndroid Build Coastguard Worker                    X86_64_WIN_MSVC_TRIPLE,
447*bb4ee6a4SAndroid Build Coastguard Worker                    "release",
448*bb4ee6a4SAndroid Build Coastguard Worker                    opts.skip_file_name,
449*bb4ee6a4SAndroid Build Coastguard Worker                    True,
450*bb4ee6a4SAndroid Build Coastguard Worker                ),
451*bb4ee6a4SAndroid Build Coastguard Worker                (
452*bb4ee6a4SAndroid Build Coastguard Worker                    opts.x86_64_msvc_sysroot,
453*bb4ee6a4SAndroid Build Coastguard Worker                    X86_64_WIN_MSVC_TRIPLE,
454*bb4ee6a4SAndroid Build Coastguard Worker                    "release",
455*bb4ee6a4SAndroid Build Coastguard Worker                    opts.skip_file_name,
456*bb4ee6a4SAndroid Build Coastguard Worker                    False,
457*bb4ee6a4SAndroid Build Coastguard Worker                ),
458*bb4ee6a4SAndroid Build Coastguard Worker            ]
459*bb4ee6a4SAndroid Build Coastguard Worker        elif opts.build_mode == "debug":
460*bb4ee6a4SAndroid Build Coastguard Worker            build_test_cases = [
461*bb4ee6a4SAndroid Build Coastguard Worker                (
462*bb4ee6a4SAndroid Build Coastguard Worker                    opts.x86_64_msvc_sysroot,
463*bb4ee6a4SAndroid Build Coastguard Worker                    X86_64_WIN_MSVC_TRIPLE,
464*bb4ee6a4SAndroid Build Coastguard Worker                    "debug",
465*bb4ee6a4SAndroid Build Coastguard Worker                    opts.skip_file_name,
466*bb4ee6a4SAndroid Build Coastguard Worker                    True,
467*bb4ee6a4SAndroid Build Coastguard Worker                ),
468*bb4ee6a4SAndroid Build Coastguard Worker            ]
469*bb4ee6a4SAndroid Build Coastguard Worker    else:
470*bb4ee6a4SAndroid Build Coastguard Worker        build_test_cases = [
471*bb4ee6a4SAndroid Build Coastguard Worker            # (sysroot path, target triple, debug/release, skip_file_name, should test?)
472*bb4ee6a4SAndroid Build Coastguard Worker            (opts.x86_64_sysroot, X86_64_TRIPLE, "debug", opts.skip_file_name, False),
473*bb4ee6a4SAndroid Build Coastguard Worker            (opts.x86_64_sysroot, X86_64_TRIPLE, "release", opts.skip_file_name, False),
474*bb4ee6a4SAndroid Build Coastguard Worker            (opts.x86_64_sysroot, X86_64_TRIPLE, "debug", opts.skip_file_name, True),
475*bb4ee6a4SAndroid Build Coastguard Worker            (opts.x86_64_sysroot, X86_64_TRIPLE, "release", opts.skip_file_name, True),
476*bb4ee6a4SAndroid Build Coastguard Worker        ]
477*bb4ee6a4SAndroid Build Coastguard Worker        if not opts.x86_64_only:
478*bb4ee6a4SAndroid Build Coastguard Worker            build_test_cases = [
479*bb4ee6a4SAndroid Build Coastguard Worker                # (sysroot path, target triple, debug/release, skip_file_name, should test?)
480*bb4ee6a4SAndroid Build Coastguard Worker                (opts.arm_sysroot, ARM_TRIPLE, "debug", opts.skip_file_name, False),
481*bb4ee6a4SAndroid Build Coastguard Worker                (opts.arm_sysroot, ARM_TRIPLE, "release", opts.skip_file_name, False),
482*bb4ee6a4SAndroid Build Coastguard Worker                (
483*bb4ee6a4SAndroid Build Coastguard Worker                    opts.aarch64_sysroot,
484*bb4ee6a4SAndroid Build Coastguard Worker                    AARCH64_TRIPLE,
485*bb4ee6a4SAndroid Build Coastguard Worker                    "debug",
486*bb4ee6a4SAndroid Build Coastguard Worker                    opts.skip_file_name,
487*bb4ee6a4SAndroid Build Coastguard Worker                    False,
488*bb4ee6a4SAndroid Build Coastguard Worker                ),
489*bb4ee6a4SAndroid Build Coastguard Worker                (
490*bb4ee6a4SAndroid Build Coastguard Worker                    opts.aarch64_sysroot,
491*bb4ee6a4SAndroid Build Coastguard Worker                    AARCH64_TRIPLE,
492*bb4ee6a4SAndroid Build Coastguard Worker                    "release",
493*bb4ee6a4SAndroid Build Coastguard Worker                    opts.skip_file_name,
494*bb4ee6a4SAndroid Build Coastguard Worker                    False,
495*bb4ee6a4SAndroid Build Coastguard Worker                ),
496*bb4ee6a4SAndroid Build Coastguard Worker            ] + build_test_cases
497*bb4ee6a4SAndroid Build Coastguard Worker        os.chdir(os.path.dirname(sys.argv[0]))
498*bb4ee6a4SAndroid Build Coastguard Worker
499*bb4ee6a4SAndroid Build Coastguard Worker    if opts.size_only:
500*bb4ee6a4SAndroid Build Coastguard Worker        # Only include non-test release builds
501*bb4ee6a4SAndroid Build Coastguard Worker        build_test_cases = [
502*bb4ee6a4SAndroid Build Coastguard Worker            case for case in build_test_cases if case[2] == "release" and not case[4]
503*bb4ee6a4SAndroid Build Coastguard Worker        ]
504*bb4ee6a4SAndroid Build Coastguard Worker
505*bb4ee6a4SAndroid Build Coastguard Worker    # First we need to build necessary DLLs.
506*bb4ee6a4SAndroid Build Coastguard Worker    # Because build_or_test may be called by multithreads in parallel,
507*bb4ee6a4SAndroid Build Coastguard Worker    # we want to build the DLLs only once up front.
508*bb4ee6a4SAndroid Build Coastguard Worker    modes = set()
509*bb4ee6a4SAndroid Build Coastguard Worker    for case in build_test_cases:
510*bb4ee6a4SAndroid Build Coastguard Worker        modes.add(case[2])
511*bb4ee6a4SAndroid Build Coastguard Worker    for mode in modes:
512*bb4ee6a4SAndroid Build Coastguard Worker        build_dlls(os.getcwd(), mode, opts.job_type, BUILD_FEATURES)
513*bb4ee6a4SAndroid Build Coastguard Worker
514*bb4ee6a4SAndroid Build Coastguard Worker    # set keyword args to build_or_test based on opts
515*bb4ee6a4SAndroid Build Coastguard Worker    build_partial = functools.partial(
516*bb4ee6a4SAndroid Build Coastguard Worker        build_or_test,
517*bb4ee6a4SAndroid Build Coastguard Worker        no_run=True,
518*bb4ee6a4SAndroid Build Coastguard Worker        clean=opts.clean,
519*bb4ee6a4SAndroid Build Coastguard Worker        copy_output=opts.copy,
520*bb4ee6a4SAndroid Build Coastguard Worker        copy_directory=opts.copy_directory,
521*bb4ee6a4SAndroid Build Coastguard Worker        only_build_targets=opts.only_build_targets,
522*bb4ee6a4SAndroid Build Coastguard Worker    )
523*bb4ee6a4SAndroid Build Coastguard Worker
524*bb4ee6a4SAndroid Build Coastguard Worker    if opts.parallel:
525*bb4ee6a4SAndroid Build Coastguard Worker        pool = multiprocessing.pool.Pool(len(build_test_cases))
526*bb4ee6a4SAndroid Build Coastguard Worker        results = pool.starmap(build_partial, build_test_cases, 1)
527*bb4ee6a4SAndroid Build Coastguard Worker    else:
528*bb4ee6a4SAndroid Build Coastguard Worker        results = [build_partial(*case) for case in build_test_cases]
529*bb4ee6a4SAndroid Build Coastguard Worker
530*bb4ee6a4SAndroid Build Coastguard Worker    print_summary("build", build_test_cases, results, opts)
531*bb4ee6a4SAndroid Build Coastguard Worker
532*bb4ee6a4SAndroid Build Coastguard Worker    # exit early if any builds failed
533*bb4ee6a4SAndroid Build Coastguard Worker    if not all([r[0] for r in results]):
534*bb4ee6a4SAndroid Build Coastguard Worker        return 1
535*bb4ee6a4SAndroid Build Coastguard Worker
536*bb4ee6a4SAndroid Build Coastguard Worker    # run tests for cases where should_test is True
537*bb4ee6a4SAndroid Build Coastguard Worker    test_cases = [case for case in build_test_cases if case[4]]
538*bb4ee6a4SAndroid Build Coastguard Worker
539*bb4ee6a4SAndroid Build Coastguard Worker    # Run tests serially. We set clean=False so it re-uses the results of the build phase.
540*bb4ee6a4SAndroid Build Coastguard Worker    results = [
541*bb4ee6a4SAndroid Build Coastguard Worker        build_or_test(
542*bb4ee6a4SAndroid Build Coastguard Worker            *case,
543*bb4ee6a4SAndroid Build Coastguard Worker            no_run=False,
544*bb4ee6a4SAndroid Build Coastguard Worker            clean=False,
545*bb4ee6a4SAndroid Build Coastguard Worker            copy_output=opts.copy,
546*bb4ee6a4SAndroid Build Coastguard Worker            copy_directory=opts.copy_directory,
547*bb4ee6a4SAndroid Build Coastguard Worker            only_build_targets=opts.only_build_targets,
548*bb4ee6a4SAndroid Build Coastguard Worker        )
549*bb4ee6a4SAndroid Build Coastguard Worker        for case in test_cases
550*bb4ee6a4SAndroid Build Coastguard Worker    ]
551*bb4ee6a4SAndroid Build Coastguard Worker
552*bb4ee6a4SAndroid Build Coastguard Worker    print_summary("test", test_cases, results, opts)
553*bb4ee6a4SAndroid Build Coastguard Worker
554*bb4ee6a4SAndroid Build Coastguard Worker    if not all([r[0] for r in results]):
555*bb4ee6a4SAndroid Build Coastguard Worker        return 1
556*bb4ee6a4SAndroid Build Coastguard Worker
557*bb4ee6a4SAndroid Build Coastguard Worker    return 0
558*bb4ee6a4SAndroid Build Coastguard Worker
559*bb4ee6a4SAndroid Build Coastguard Worker
560*bb4ee6a4SAndroid Build Coastguard Workerdef print_summary(title, cases, results, opts):
561*bb4ee6a4SAndroid Build Coastguard Worker    print("---")
562*bb4ee6a4SAndroid Build Coastguard Worker    print(f"{title} summary:")
563*bb4ee6a4SAndroid Build Coastguard Worker    for test_case, result in zip(cases, results):
564*bb4ee6a4SAndroid Build Coastguard Worker        _, triple, kind, _, test_it = test_case
565*bb4ee6a4SAndroid Build Coastguard Worker        title = "%s_%s" % (triple.split("-")[0], kind)
566*bb4ee6a4SAndroid Build Coastguard Worker        if test_it:
567*bb4ee6a4SAndroid Build Coastguard Worker            title += "_test"
568*bb4ee6a4SAndroid Build Coastguard Worker
569*bb4ee6a4SAndroid Build Coastguard Worker        success, result_msg = result
570*bb4ee6a4SAndroid Build Coastguard Worker
571*bb4ee6a4SAndroid Build Coastguard Worker        result_color = FAIL_COLOR
572*bb4ee6a4SAndroid Build Coastguard Worker        if success:
573*bb4ee6a4SAndroid Build Coastguard Worker            result_color = PASS_COLOR
574*bb4ee6a4SAndroid Build Coastguard Worker
575*bb4ee6a4SAndroid Build Coastguard Worker        display_size = ""
576*bb4ee6a4SAndroid Build Coastguard Worker        # Stripped binary isn't available when only certain packages are built, the tool is not available
577*bb4ee6a4SAndroid Build Coastguard Worker        # on Windows.
578*bb4ee6a4SAndroid Build Coastguard Worker        if (
579*bb4ee6a4SAndroid Build Coastguard Worker            success
580*bb4ee6a4SAndroid Build Coastguard Worker            and kind == "release"
581*bb4ee6a4SAndroid Build Coastguard Worker            and not test_it
582*bb4ee6a4SAndroid Build Coastguard Worker            and not opts.only_build_targets
583*bb4ee6a4SAndroid Build Coastguard Worker            and not IS_WINDOWS
584*bb4ee6a4SAndroid Build Coastguard Worker        ):
585*bb4ee6a4SAndroid Build Coastguard Worker            display_size = get_stripped_size(triple) + " stripped binary"
586*bb4ee6a4SAndroid Build Coastguard Worker
587*bb4ee6a4SAndroid Build Coastguard Worker        print("%20s: %s%15s%s %s" % (title, result_color, result_msg, END_COLOR, display_size))
588*bb4ee6a4SAndroid Build Coastguard Worker
589*bb4ee6a4SAndroid Build Coastguard Worker
590*bb4ee6a4SAndroid Build Coastguard Workerif __name__ == "__main__":
591*bb4ee6a4SAndroid Build Coastguard Worker    sys.exit(main(sys.argv[1:]))
592