-
Notifications
You must be signed in to change notification settings - Fork 397
/
Copy pathcapture_build_info.bzl
86 lines (75 loc) · 3.51 KB
/
capture_build_info.bzl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Define a rule to capture the compile-time options.
Our benchmarks report the compile-time build flags, as these are important to evaluate and compiler benchmark results.
With Bazel we need to create a new rule that captures these flags. This rule substitutes some magic strings in
`google/cloud/internal/build_info.cc.in` to the values of several interesting compilation parameters. The substitution
is easy, we simply use a native Bazel function: `ctx.actions.expand_template()`. Finding the values of the compilation
flags requires digging into the C++ toolchain definition. This is documented (at a high-level) here:
https://bazel.build/docs/integrating-with-rules-cc
it links to an example here:
https://github.com/bazelbuild/rules_cc/blob/main/examples/my_c_compile/my_c_compile.bzl
I found this fragment particularly useful:
https://github.com/bazelbuild/rules_cc/blob/0d68932a68bcd6f332b14ccc561990586de2318d/examples/my_c_compile/my_c_compile.bzl#L40-L51
"""
load("@rules_cc//cc:action_names.bzl", "CPP_COMPILE_ACTION_NAME")
load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain")
def _capture_build_info_impl(ctx):
toolchain = find_cc_toolchain(ctx)
feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = toolchain,
requested_features = ctx.features,
unsupported_features = ["module_maps"] + ctx.disabled_features,
)
cc_source = ctx.outputs.output_file
cc_vars = cc_common.create_compile_variables(
feature_configuration = feature_configuration,
cc_toolchain = toolchain,
user_compile_flags = ctx.fragments.cpp.cxxopts + ctx.fragments.cpp.conlyopts,
source_file = cc_source.path,
)
command_line = cc_common.get_memory_inefficient_command_line(
feature_configuration = feature_configuration,
action_name = CPP_COMPILE_ACTION_NAME,
variables = cc_vars,
)
# The command_line is a list of strings, the last two are `-c` and `.../*.cc` we want to ignore them
if len(command_line) > 2:
command_line = command_line[:-2]
cc_flags = " ".join(command_line)
compilation_mode = ctx.var.get("COMPILATION_MODE", "fastbuild")
ctx.actions.expand_template(
template = ctx.file.template,
output = ctx.outputs.output_file,
substitutions = {
"@CMAKE_CXX_FLAGS@": "bazel:" + compilation_mode,
"${CMAKE_CXX_FLAGS_${GOOGLE_CLOUD_CPP_BUILD_TYPE_UPPER}}": cc_flags,
"@GOOGLE_CLOUD_CPP_BUILD_METADATA@": "",
},
)
capture_build_info = rule(
implementation = _capture_build_info_impl,
attrs = {
"template": attr.label(
allow_single_file = True,
mandatory = True,
),
"output_file": attr.output(mandatory = True),
"_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
},
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
fragments = ["cpp"],
)