forked from envoyproxy/envoy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pch.bzl
113 lines (100 loc) · 3.76 KB
/
pch.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
load(
"@bazel_tools//tools/build_defs/cc:action_names.bzl",
"CPP_COMPILE_ACTION_NAME",
)
def _pch(ctx):
deps_cc_info = cc_common.merge_cc_infos(
cc_infos = [dep[CcInfo] for dep in ctx.attr.deps],
)
if not ctx.attr.enabled:
return [deps_cc_info]
cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]
feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
cc_compiler_path = cc_common.get_tool_for_action(
feature_configuration = feature_configuration,
action_name = CPP_COMPILE_ACTION_NAME,
)
if "clang" not in cc_compiler_path:
fail("error: attempting to use clang PCH without clang: {}".format(cc_compiler_path))
generated_header_file = ctx.actions.declare_file(ctx.label.name + ".h")
ctx.actions.write(
generated_header_file,
"\n".join(["#include \"{}\"".format(include) for include in ctx.attr.includes]) + "\n",
)
pch_flags = ["-x", "c++-header", "-Xclang", "-fno-pch-timestamp"]
pch_file = ctx.actions.declare_file(ctx.label.name + ".pch")
deps_ctx = deps_cc_info.compilation_context
cc_compile_variables = cc_common.create_compile_variables(
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
user_compile_flags = ctx.fragments.cpp.copts + ctx.fragments.cpp.cxxopts + pch_flags,
source_file = generated_header_file.path,
output_file = pch_file.path,
preprocessor_defines = depset(deps_ctx.defines.to_list() + deps_ctx.local_defines.to_list()),
include_directories = deps_ctx.includes,
quote_include_directories = deps_ctx.quote_includes,
system_include_directories = deps_ctx.system_includes,
framework_include_directories = deps_ctx.framework_includes,
)
env = cc_common.get_environment_variables(
feature_configuration = feature_configuration,
action_name = CPP_COMPILE_ACTION_NAME,
variables = cc_compile_variables,
)
command_line = cc_common.get_memory_inefficient_command_line(
feature_configuration = feature_configuration,
action_name = CPP_COMPILE_ACTION_NAME,
variables = cc_compile_variables,
)
transitive_headers = []
for dep in ctx.attr.deps:
transitive_headers.append(dep[CcInfo].compilation_context.headers)
ctx.actions.run(
executable = cc_compiler_path,
arguments = command_line,
env = env,
inputs = depset(
items = [generated_header_file],
transitive = [cc_toolchain.all_files] + transitive_headers,
),
outputs = [pch_file],
)
return [
DefaultInfo(files = depset(items = [pch_file])),
cc_common.merge_cc_infos(
direct_cc_infos = [
CcInfo(
compilation_context = cc_common.create_compilation_context(
headers = depset([pch_file, generated_header_file]),
),
),
],
cc_infos = [deps_cc_info],
),
]
pch = rule(
attrs = dict(
includes = attr.string_list(
mandatory = True,
allow_empty = False,
),
deps = attr.label_list(
mandatory = True,
allow_empty = False,
providers = [CcInfo],
),
enabled = attr.bool(
mandatory = True,
),
_cc_toolchain = attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
),
fragments = ["cpp"],
provides = [CcInfo],
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
implementation = _pch,
)