xref: /aosp_15_r20/external/grpc-grpc/tools/profiling/microbenchmarks/bm_diff/bm_build.py (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1#!/usr/bin/env python3
2#
3# Copyright 2017 gRPC authors.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16""" Python utility to build opt and counters benchmarks """
17
18import argparse
19import multiprocessing
20import os
21import shutil
22import subprocess
23
24import bm_constants
25
26
27def _args():
28    argp = argparse.ArgumentParser(description="Builds microbenchmarks")
29    argp.add_argument(
30        "-b",
31        "--benchmarks",
32        nargs="+",
33        choices=bm_constants._AVAILABLE_BENCHMARK_TESTS,
34        default=bm_constants._AVAILABLE_BENCHMARK_TESTS,
35        help="Which benchmarks to build",
36    )
37    argp.add_argument(
38        "-j",
39        "--jobs",
40        type=int,
41        default=multiprocessing.cpu_count(),
42        help=(
43            "Deprecated. Bazel chooses number of CPUs to build with"
44            " automatically."
45        ),
46    )
47    argp.add_argument(
48        "-n",
49        "--name",
50        type=str,
51        help=(
52            "Unique name of this build. To be used as a handle to pass to the"
53            " other bm* scripts"
54        ),
55    )
56    args = argp.parse_args()
57    assert args.name
58    return args
59
60
61def _build_cmd(cfg, benchmarks):
62    bazel_targets = [
63        "//test/cpp/microbenchmarks:%s" % benchmark for benchmark in benchmarks
64    ]
65    # --dynamic_mode=off makes sure that we get a monolithic binary that can be safely
66    # moved outside of the bazel-bin directory
67    return [
68        "tools/bazel",
69        "build",
70        "--config=%s" % cfg,
71        "--dynamic_mode=off",
72    ] + bazel_targets
73
74
75def _build_config_and_copy(cfg, benchmarks, dest_dir):
76    """Build given config and copy resulting binaries to dest_dir/CONFIG"""
77    subprocess.check_call(_build_cmd(cfg, benchmarks))
78    cfg_dir = dest_dir + "/%s" % cfg
79    os.makedirs(cfg_dir)
80    subprocess.check_call(
81        ["cp"]
82        + [
83            "bazel-bin/test/cpp/microbenchmarks/%s" % benchmark
84            for benchmark in benchmarks
85        ]
86        + [cfg_dir]
87    )
88
89
90def build(name, benchmarks, jobs):
91    dest_dir = "bm_diff_%s" % name
92    shutil.rmtree(dest_dir, ignore_errors=True)
93    _build_config_and_copy("opt", benchmarks, dest_dir)
94
95
96if __name__ == "__main__":
97    args = _args()
98    build(args.name, args.benchmarks, args.jobs)
99