xref: /aosp_15_r20/external/pigweed/seed/0113.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _seed-0113:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker===========================================
4*61c4878aSAndroid Build Coastguard Worker0113: Add modular Bazel C/C++ toolchain API
5*61c4878aSAndroid Build Coastguard Worker===========================================
6*61c4878aSAndroid Build Coastguard Worker.. seed::
7*61c4878aSAndroid Build Coastguard Worker   :number: 0113
8*61c4878aSAndroid Build Coastguard Worker   :name: Add modular Bazel C/C++ toolchain API
9*61c4878aSAndroid Build Coastguard Worker   :status: Accepted
10*61c4878aSAndroid Build Coastguard Worker   :proposal_date: 2023-09-28
11*61c4878aSAndroid Build Coastguard Worker   :cl: 173453
12*61c4878aSAndroid Build Coastguard Worker   :authors: Armando Montanez
13*61c4878aSAndroid Build Coastguard Worker   :facilitator: Ted Pudlik
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker-------
16*61c4878aSAndroid Build Coastguard WorkerSummary
17*61c4878aSAndroid Build Coastguard Worker-------
18*61c4878aSAndroid Build Coastguard WorkerThis SEED proposes custom Starlark rules for declaring C/C++ toolchains in
19*61c4878aSAndroid Build Coastguard WorkerBazel, and scalable patterns for sharing modular components of C/C++ toolchain
20*61c4878aSAndroid Build Coastguard Workerdefinitions.
21*61c4878aSAndroid Build Coastguard Worker
22*61c4878aSAndroid Build Coastguard Worker----------
23*61c4878aSAndroid Build Coastguard WorkerMotivation
24*61c4878aSAndroid Build Coastguard Worker----------
25*61c4878aSAndroid Build Coastguard WorkerThere is a lot of boilerplate involved in standing up a Bazel C/C++ toolchain.
26*61c4878aSAndroid Build Coastguard WorkerWhile a good portion of the verbosity of specifying a new toolchain is
27*61c4878aSAndroid Build Coastguard Workerimportant, necessary machinery, nearly as much suffers from one or more of the
28*61c4878aSAndroid Build Coastguard Workerfollowing problems:
29*61c4878aSAndroid Build Coastguard Worker
30*61c4878aSAndroid Build Coastguard Worker- **Underdocumented patterns**: The
31*61c4878aSAndroid Build Coastguard Worker  `create_cc_toolchain_config_info() <https://bazel.build/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info>`_
32*61c4878aSAndroid Build Coastguard Worker  method has an attribute called ``target_cpu`` that doesn't have an associated
33*61c4878aSAndroid Build Coastguard Worker  list of expected values, which suggests the argument is for bookkeeping
34*61c4878aSAndroid Build Coastguard Worker  purposes and doesn't affect Bazel behavior. The reality is this argument
35*61c4878aSAndroid Build Coastguard Worker  *does* have expected values that change behavior, but these are undocumented
36*61c4878aSAndroid Build Coastguard Worker  (see `this GitHub issue <https://github.com/bazelbuild/bazel/issues/19353>`_
37*61c4878aSAndroid Build Coastguard Worker  for more information).
38*61c4878aSAndroid Build Coastguard Worker
39*61c4878aSAndroid Build Coastguard Worker- **Not inherently modular**: Bazel expects the overwhelming majority of a
40*61c4878aSAndroid Build Coastguard Worker  C/C++ toolchain to be specified as part of a call to
41*61c4878aSAndroid Build Coastguard Worker  ``create_cc_toolchain_config_info()``. Because this is a Starlark method,
42*61c4878aSAndroid Build Coastguard Worker  there's a lot of flexibility with how you construct a toolchain config, but
43*61c4878aSAndroid Build Coastguard Worker  very little by way of existing patterns for creating something that is
44*61c4878aSAndroid Build Coastguard Worker  testable, sharable, or in other ways modular. The existing
45*61c4878aSAndroid Build Coastguard Worker  `tutorial for creating a C/C++ toolchain <https://bazel.build/tutorials/ccp-toolchain-config#configure-cc-toolchain>`_
46*61c4878aSAndroid Build Coastguard Worker  illustrates expanding out the toolchain definition as a no-argument Starlark
47*61c4878aSAndroid Build Coastguard Worker  rule.
48*61c4878aSAndroid Build Coastguard Worker
49*61c4878aSAndroid Build Coastguard WorkerAs Pigweed fully embraces multi-platform builds, it is critical for both
50*61c4878aSAndroid Build Coastguard WorkerPigweed and users of Pigweed that it is easy to stand up custom toolchain
51*61c4878aSAndroid Build Coastguard Workerdefinitions that work for the relevant hardware project-specific code/libraries.
52*61c4878aSAndroid Build Coastguard Worker
53*61c4878aSAndroid Build Coastguard WorkerThis SEED seeks to address the shortcomings in Bazel C/C++ toolchain
54*61c4878aSAndroid Build Coastguard Workerdeclaration by establishing patterns and providing custom build rules that
55*61c4878aSAndroid Build Coastguard Workerare owned and maintained by Pigweed.
56*61c4878aSAndroid Build Coastguard Worker
57*61c4878aSAndroid Build Coastguard Worker--------
58*61c4878aSAndroid Build Coastguard WorkerProposal
59*61c4878aSAndroid Build Coastguard Worker--------
60*61c4878aSAndroid Build Coastguard Worker1. Introduce rules for defining C/C++ toolchains
61*61c4878aSAndroid Build Coastguard Worker================================================
62*61c4878aSAndroid Build Coastguard WorkerIn an effort to improve the experience of defining a C/C++ toolchain, Pigweed
63*61c4878aSAndroid Build Coastguard Workerwill introduce new Bazel rules that allow toolchains to share common boilerplate
64*61c4878aSAndroid Build Coastguard Workerwithout hindering power-user functionality.
65*61c4878aSAndroid Build Coastguard Worker
66*61c4878aSAndroid Build Coastguard WorkerWhile this work centers around an improved experience for defining a toolchain
67*61c4878aSAndroid Build Coastguard Workervia ``create_cc_toolchain_config_info()``, other build rules will be introduced
68*61c4878aSAndroid Build Coastguard Workerfor closely related aspects of the toolchain definition process.
69*61c4878aSAndroid Build Coastguard Worker
70*61c4878aSAndroid Build Coastguard WorkerAn example of what these rules would look like in practice is as follows:
71*61c4878aSAndroid Build Coastguard Worker
72*61c4878aSAndroid Build Coastguard Worker.. code-block::
73*61c4878aSAndroid Build Coastguard Worker
74*61c4878aSAndroid Build Coastguard Worker   # A tool that can be used by various build actions.
75*61c4878aSAndroid Build Coastguard Worker   pw_cc_tool(
76*61c4878aSAndroid Build Coastguard Worker       name = "clang_tool",
77*61c4878aSAndroid Build Coastguard Worker       path = "@cipd_llvm_toolchain//:bin/clang",
78*61c4878aSAndroid Build Coastguard Worker       additional_files = [
79*61c4878aSAndroid Build Coastguard Worker          "@cipd_llvm_toolchain//:all",
80*61c4878aSAndroid Build Coastguard Worker       ],
81*61c4878aSAndroid Build Coastguard Worker   )
82*61c4878aSAndroid Build Coastguard Worker
83*61c4878aSAndroid Build Coastguard Worker   # A mapping of a tool to actions, with flag sets that define behaviors.
84*61c4878aSAndroid Build Coastguard Worker   pw_cc_action_config(
85*61c4878aSAndroid Build Coastguard Worker       name = "clang",
86*61c4878aSAndroid Build Coastguard Worker       actions = ALL_ASM_ACTIONS + ALL_C_COMPILER_ACTIONS,
87*61c4878aSAndroid Build Coastguard Worker       tools = [
88*61c4878aSAndroid Build Coastguard Worker           ":clang_tool",
89*61c4878aSAndroid Build Coastguard Worker       ],
90*61c4878aSAndroid Build Coastguard Worker       flag_sets = [
91*61c4878aSAndroid Build Coastguard Worker           # Most flags should NOT end up here. Only unconditional flags that
92*61c4878aSAndroid Build Coastguard Worker           # should ALWAYS be bound to this tool (e.g. static library
93*61c4878aSAndroid Build Coastguard Worker           # workaround fix for macOS).
94*61c4878aSAndroid Build Coastguard Worker           "@pw_toolchain//flag_sets:generate_depfile",
95*61c4878aSAndroid Build Coastguard Worker       ],
96*61c4878aSAndroid Build Coastguard Worker   )
97*61c4878aSAndroid Build Coastguard Worker
98*61c4878aSAndroid Build Coastguard Worker   # A trivial flag to be consumed by a C/C++ toolchain.
99*61c4878aSAndroid Build Coastguard Worker   pw_cc_flag_set(
100*61c4878aSAndroid Build Coastguard Worker       name = "werror",
101*61c4878aSAndroid Build Coastguard Worker       actions = ALL_COMPILE_ACTIONS,
102*61c4878aSAndroid Build Coastguard Worker       flags = [
103*61c4878aSAndroid Build Coastguard Worker           "-Werror",
104*61c4878aSAndroid Build Coastguard Worker       ],
105*61c4878aSAndroid Build Coastguard Worker   )
106*61c4878aSAndroid Build Coastguard Worker
107*61c4878aSAndroid Build Coastguard Worker   # A list of flags that can be added to a toolchain configuration.
108*61c4878aSAndroid Build Coastguard Worker   pw_cc_flag_set(
109*61c4878aSAndroid Build Coastguard Worker       name = "user_compile_options",
110*61c4878aSAndroid Build Coastguard Worker       actions = ALL_COMPILE_ACTIONS,
111*61c4878aSAndroid Build Coastguard Worker       flag_groups = [
112*61c4878aSAndroid Build Coastguard Worker           ":user_compile_options_flags",
113*61c4878aSAndroid Build Coastguard Worker       ]
114*61c4878aSAndroid Build Coastguard Worker   )
115*61c4878aSAndroid Build Coastguard Worker
116*61c4878aSAndroid Build Coastguard Worker   # A more complex compiler flag that requires template expansion.
117*61c4878aSAndroid Build Coastguard Worker   pw_cc_flag_group(
118*61c4878aSAndroid Build Coastguard Worker       name = "user_compile_options_flags",
119*61c4878aSAndroid Build Coastguard Worker       flags = ["%{user_compile_flags}"],
120*61c4878aSAndroid Build Coastguard Worker       iterate_over = "user_compile_flags",
121*61c4878aSAndroid Build Coastguard Worker       expand_if_available = "user_compile_flags",
122*61c4878aSAndroid Build Coastguard Worker   )
123*61c4878aSAndroid Build Coastguard Worker
124*61c4878aSAndroid Build Coastguard Worker   # The underlying definition of a complete C/C++ toolchain.
125*61c4878aSAndroid Build Coastguard Worker   pw_cc_toolchain(
126*61c4878aSAndroid Build Coastguard Worker       name = "host_toolchain_linux",
127*61c4878aSAndroid Build Coastguard Worker       action_configs = [
128*61c4878aSAndroid Build Coastguard Worker           ":clang",
129*61c4878aSAndroid Build Coastguard Worker           ":clang++",
130*61c4878aSAndroid Build Coastguard Worker           # ...
131*61c4878aSAndroid Build Coastguard Worker       ],
132*61c4878aSAndroid Build Coastguard Worker       additional_files = ":linux_sysroot_files",
133*61c4878aSAndroid Build Coastguard Worker       action_config_flag_sets = [
134*61c4878aSAndroid Build Coastguard Worker           "@pw_toolchain//flag_sets:no_canonical_prefixes",
135*61c4878aSAndroid Build Coastguard Worker           ":user_compile_options",
136*61c4878aSAndroid Build Coastguard Worker           ":werror",
137*61c4878aSAndroid Build Coastguard Worker       ],
138*61c4878aSAndroid Build Coastguard Worker       features = [
139*61c4878aSAndroid Build Coastguard Worker           "@pw_toolchain//features:c++17",
140*61c4878aSAndroid Build Coastguard Worker       ],
141*61c4878aSAndroid Build Coastguard Worker       target_cpu = "x86_64",
142*61c4878aSAndroid Build Coastguard Worker       target_system_name = "x86_64-unknown-linux-gnu",
143*61c4878aSAndroid Build Coastguard Worker       toolchain_identifier = "host-toolchain-linux",
144*61c4878aSAndroid Build Coastguard Worker   )
145*61c4878aSAndroid Build Coastguard Worker
146*61c4878aSAndroid Build Coastguard Worker   # Toolchain resolution parameters for the above C/C++ toolchain.
147*61c4878aSAndroid Build Coastguard Worker   toolchain(
148*61c4878aSAndroid Build Coastguard Worker       name = "host_cc_toolchain_linux",
149*61c4878aSAndroid Build Coastguard Worker       exec_compatible_with = [
150*61c4878aSAndroid Build Coastguard Worker           "@platforms//os:linux",
151*61c4878aSAndroid Build Coastguard Worker       ],
152*61c4878aSAndroid Build Coastguard Worker       target_compatible_with = [
153*61c4878aSAndroid Build Coastguard Worker           "@platforms//os:linux",
154*61c4878aSAndroid Build Coastguard Worker       ],
155*61c4878aSAndroid Build Coastguard Worker       toolchain = ":host_toolchain_linux",
156*61c4878aSAndroid Build Coastguard Worker       toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
157*61c4878aSAndroid Build Coastguard Worker   )
158*61c4878aSAndroid Build Coastguard Worker
159*61c4878aSAndroid Build Coastguard Worker2. Provide standard toolchain building-blocks
160*61c4878aSAndroid Build Coastguard Worker=============================================
161*61c4878aSAndroid Build Coastguard WorkerPigweed will build out a repository of sharable instantiations of the
162*61c4878aSAndroid Build Coastguard Workeraforementioned custom rules to give projects the resources they need to quickly
163*61c4878aSAndroid Build Coastguard Workerand easily assemble toolchains for desktop and embedded targets. This includes,
164*61c4878aSAndroid Build Coastguard Workerbut is not limited to:
165*61c4878aSAndroid Build Coastguard Worker
166*61c4878aSAndroid Build Coastguard Worker- Rules that define tool sets for common toolchains (LLVM/clang, GNU/gcc).
167*61c4878aSAndroid Build Coastguard Worker- Fully specified, modular
168*61c4878aSAndroid Build Coastguard Worker  `features <https://bazel.build/docs/cc-toolchain-config-reference#features>`_.
169*61c4878aSAndroid Build Coastguard Worker- Common flag sets that users may want to apply directly to their toolchains.
170*61c4878aSAndroid Build Coastguard Worker  (enabling/disabling warnings, C++ standard version, etc.)
171*61c4878aSAndroid Build Coastguard Worker- Platform/architecture support rules, including host OS SDK integrations
172*61c4878aSAndroid Build Coastguard Worker  (Xcode, Windows SDK) and architecture-specific flag sets.
173*61c4878aSAndroid Build Coastguard Worker
174*61c4878aSAndroid Build Coastguard WorkerThese components will help establish patterns that will make it significantly
175*61c4878aSAndroid Build Coastguard Workereasier for Pigweed users (and Bazel users at large) to define their own
176*61c4878aSAndroid Build Coastguard Workertoolchains.
177*61c4878aSAndroid Build Coastguard Worker
178*61c4878aSAndroid Build Coastguard Worker---------------------
179*61c4878aSAndroid Build Coastguard WorkerProblem investigation
180*61c4878aSAndroid Build Coastguard Worker---------------------
181*61c4878aSAndroid Build Coastguard WorkerThis section explores previous work, and details why existing solutions don't
182*61c4878aSAndroid Build Coastguard Workermeet Pigweed's needs.
183*61c4878aSAndroid Build Coastguard Worker
184*61c4878aSAndroid Build Coastguard Workerbazelembedded/rules_cc_toolchain
185*61c4878aSAndroid Build Coastguard Worker================================
186*61c4878aSAndroid Build Coastguard WorkerThe `rules_cc_toolchain <https://github.com/bazelembedded/rules_cc_toolchain>`_
187*61c4878aSAndroid Build Coastguard Workeras part of the larger bazelembedded suite was actually the initial foundation
188*61c4878aSAndroid Build Coastguard Workerof Pigweed's Bazel build. While this served as a very good initial foundation,
189*61c4878aSAndroid Build Coastguard Workerit didn't provide the flexibility needed to easily stand up additional
190*61c4878aSAndroid Build Coastguard Workertoolchains in ways that gave downstream projects sufficient control over the
191*61c4878aSAndroid Build Coastguard Workerflags, libraries, tools, and sysroot.
192*61c4878aSAndroid Build Coastguard Worker
193*61c4878aSAndroid Build Coastguard WorkerTo work around the limited configurability of toolchain flags, Pigweed employed
194*61c4878aSAndroid Build Coastguard Workerthe following workarounds:
195*61c4878aSAndroid Build Coastguard Worker
196*61c4878aSAndroid Build Coastguard Worker#. Place ``copts`` and ``linkopts`` in ``.bazelrc``: This was problematic
197*61c4878aSAndroid Build Coastguard Worker   because ``.bazelrc`` is not intrinsically shared with or propagated to
198*61c4878aSAndroid Build Coastguard Worker   downstream users of Pigweed. Also, flags here are unilaterally applied
199*61c4878aSAndroid Build Coastguard Worker   without OS-specific considerations.
200*61c4878aSAndroid Build Coastguard Worker#. Attach flags to build targets with custom wrappers: This approach
201*61c4878aSAndroid Build Coastguard Worker   intrinsically requires the existence of the ``pw_cc_library``, which
202*61c4878aSAndroid Build Coastguard Worker   introduces difficulty around consistent interoperability with other Bazel
203*61c4878aSAndroid Build Coastguard Worker   projects (among other issues detailed in
204*61c4878aSAndroid Build Coastguard Worker   `b/267498492 <https://issues.pigweed.dev/issues/267498492>`_).
205*61c4878aSAndroid Build Coastguard Worker
206*61c4878aSAndroid Build Coastguard WorkerSome other issues encountered when working with this solution include:
207*61c4878aSAndroid Build Coastguard Worker
208*61c4878aSAndroid Build Coastguard Worker- These rules intended to be modular, but in practice were relatively tightly
209*61c4878aSAndroid Build Coastguard Worker  coupled.
210*61c4878aSAndroid Build Coastguard Worker- Transitive dependencies throughout the toolchain definition process resulted
211*61c4878aSAndroid Build Coastguard Worker  in some hard-to-debug issues (see
212*61c4878aSAndroid Build Coastguard Worker  `this pull request <https://github.com/bazelembedded/rules_cc_toolchain/pull/39>`_
213*61c4878aSAndroid Build Coastguard Worker  and `b/254518544 <https://issues.pigweed.dev/issues/254518544>`_.
214*61c4878aSAndroid Build Coastguard Worker
215*61c4878aSAndroid Build Coastguard Workerbazelembedded/modular_cc_toolchains
216*61c4878aSAndroid Build Coastguard Worker===================================
217*61c4878aSAndroid Build Coastguard WorkerThe `modular_cc_toolchains <https://github.com/bazelembedded/modular_cc_toolchains>`_
218*61c4878aSAndroid Build Coastguard Workerrepository is a new attempt as part of the bazelembedded suite at providing
219*61c4878aSAndroid Build Coastguard Workertruly modular toolchain rules. The proposed direction is much more in-line
220*61c4878aSAndroid Build Coastguard Workerwith the needs of Pigweed, but at the moment the repository exists as an
221*61c4878aSAndroid Build Coastguard Workerinitial draft of ideas rather than a complete implementation.
222*61c4878aSAndroid Build Coastguard Worker
223*61c4878aSAndroid Build Coastguard WorkerThis repository greatly inspired Pigweed's initial prototype for modular
224*61c4878aSAndroid Build Coastguard Workertoolchains, but diverges significantly from the underlying Bazel C/C++
225*61c4878aSAndroid Build Coastguard Workertoolchain building-blocks. If this work was already complete and
226*61c4878aSAndroid Build Coastguard Workerwell-established, it probably would have satisfied some of Pigweed's key needs.
227*61c4878aSAndroid Build Coastguard Worker
228*61c4878aSAndroid Build Coastguard WorkerlowRISC/crt
229*61c4878aSAndroid Build Coastguard Worker===========
230*61c4878aSAndroid Build Coastguard WorkerThe `compiler repository toolkit <https://github.com/lowRISC/crt>`_ is another
231*61c4878aSAndroid Build Coastguard Workerscalable approach at toolchains. This repository strives to be an all-in-one
232*61c4878aSAndroid Build Coastguard Workerrepository for embedded toolchains, and does a very good job at providing
233*61c4878aSAndroid Build Coastguard Workerscalable models for establishing toolchains. This repository is relatively
234*61c4878aSAndroid Build Coastguard Workermonolithic, though, and doesn't necessarily address the concern of quickly
235*61c4878aSAndroid Build Coastguard Workerand easily standing up custom toolchains. Instead, it's more suited towards
236*61c4878aSAndroid Build Coastguard Workercontributing new one-size-fits-all toolchains to ``crt`` directly.
237*61c4878aSAndroid Build Coastguard Worker
238*61c4878aSAndroid Build Coastguard WorkerAndroid's toolchain
239*61c4878aSAndroid Build Coastguard Worker===================
240*61c4878aSAndroid Build Coastguard WorkerAndroid's Bazel-based build has invested heavily in toolchains, but they're
241*61c4878aSAndroid Build Coastguard Workervery tightly coupled to the use cases of Android. For example,
242*61c4878aSAndroid Build Coastguard Worker`this <https://cs.android.com/android/platform/superproject/main/+/main:build/bazel/toolchains/clang/host/linux-x86/cc_toolchain_features.bzl;l=375-389;drc=097d710c349758fc2732497fe5c3d1b0a32fa4a8>`_ binds ``-fstrict-aliasing`` to a condition based on the target architecture.
243*61c4878aSAndroid Build Coastguard WorkerThese toolchains scale for the purpose of Android, but unfortunately are
244*61c4878aSAndroid Build Coastguard Workerinherently not modular or reusable outside of that context.
245*61c4878aSAndroid Build Coastguard Worker
246*61c4878aSAndroid Build Coastguard WorkerDue to the sheer amount of investment in these toolchains, though, they serve
247*61c4878aSAndroid Build Coastguard Workeras a good reference for building out a complete toolchain in Bazel.
248*61c4878aSAndroid Build Coastguard Worker
249*61c4878aSAndroid Build Coastguard WorkerPigweed's modular Bazel toolchain prototype
250*61c4878aSAndroid Build Coastguard Worker===========================================
251*61c4878aSAndroid Build Coastguard WorkerAs part of an exploratory phase of getting toolchains set up for Linux and
252*61c4878aSAndroid Build Coastguard WorkermacOS,
253*61c4878aSAndroid Build Coastguard Worker`an initial prototype <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/157634>`_
254*61c4878aSAndroid Build Coastguard Workerfor modular Bazel toolchains was drafted and deployed to Pigweed. This work
255*61c4878aSAndroid Build Coastguard Workerintroduced two key build rules: ``pw_cc_toolchain_feature`` and
256*61c4878aSAndroid Build Coastguard Worker``pw_cc_toolchain``. With both of these rules, it’s possible to instantiate a
257*61c4878aSAndroid Build Coastguard Workervast array of toolchain variants without writing a single line of Starlark. A
258*61c4878aSAndroid Build Coastguard Workerfew examples of these building blocks in action are provided below.
259*61c4878aSAndroid Build Coastguard Worker
260*61c4878aSAndroid Build Coastguard Worker.. code-block::
261*61c4878aSAndroid Build Coastguard Worker
262*61c4878aSAndroid Build Coastguard Worker   # pw_cc_toolchain example taken from https://cs.opensource.google/pigweed/pigweed/+/main:pw_toolchain/host_clang/BUILD.bazel;l=113-143;drc=7df1768d915fe11dae05751f70f143e60acfb17a.
263*61c4878aSAndroid Build Coastguard Worker
264*61c4878aSAndroid Build Coastguard Worker   pw_cc_toolchain(
265*61c4878aSAndroid Build Coastguard Worker       name = "host_toolchain_linux",
266*61c4878aSAndroid Build Coastguard Worker       abi_libc_version = "unknown",
267*61c4878aSAndroid Build Coastguard Worker       abi_version = "unknown",
268*61c4878aSAndroid Build Coastguard Worker       all_files = ":all_linux_files",
269*61c4878aSAndroid Build Coastguard Worker       ar = "@llvm_toolchain//:bin/llvm-ar",
270*61c4878aSAndroid Build Coastguard Worker
271*61c4878aSAndroid Build Coastguard Worker       # TODO: b/305737273 - Globbing all files for every action has a
272*61c4878aSAndroid Build Coastguard Worker       # performance hit, make these more granular.
273*61c4878aSAndroid Build Coastguard Worker       ar_files = ":all_linux_files",
274*61c4878aSAndroid Build Coastguard Worker       as_files = ":all_linux_files",
275*61c4878aSAndroid Build Coastguard Worker       compiler = "unknown",
276*61c4878aSAndroid Build Coastguard Worker       compiler_files = ":all_linux_files",
277*61c4878aSAndroid Build Coastguard Worker       coverage_files = ":all_linux_files",
278*61c4878aSAndroid Build Coastguard Worker       cpp = "@llvm_toolchain//:bin/clang++",
279*61c4878aSAndroid Build Coastguard Worker       dwp_files = ":all_linux_files",
280*61c4878aSAndroid Build Coastguard Worker       feature_deps = [
281*61c4878aSAndroid Build Coastguard Worker           ":linux_sysroot",
282*61c4878aSAndroid Build Coastguard Worker            "@pw_toolchain//features:no_canonical_prefixes",
283*61c4878aSAndroid Build Coastguard Worker       ],
284*61c4878aSAndroid Build Coastguard Worker       gcc = "@llvm_toolchain//:bin/clang",
285*61c4878aSAndroid Build Coastguard Worker       gcov = "@llvm_toolchain//:bin/llvm-cov",
286*61c4878aSAndroid Build Coastguard Worker       host_system_name = "unknown",
287*61c4878aSAndroid Build Coastguard Worker       ld = "@llvm_toolchain//:bin/clang++",
288*61c4878aSAndroid Build Coastguard Worker       linker_files = ":all_linux_files",
289*61c4878aSAndroid Build Coastguard Worker       objcopy_files = ":all_linux_files",
290*61c4878aSAndroid Build Coastguard Worker       strip = "@llvm_toolchain//:bin/llvm-strip",
291*61c4878aSAndroid Build Coastguard Worker       strip_files = ":all_linux_files",
292*61c4878aSAndroid Build Coastguard Worker       supports_param_files = 0,
293*61c4878aSAndroid Build Coastguard Worker       target_cpu = "unknown",
294*61c4878aSAndroid Build Coastguard Worker       target_libc = "unknown",
295*61c4878aSAndroid Build Coastguard Worker       target_system_name = "unknown",
296*61c4878aSAndroid Build Coastguard Worker       toolchain_identifier = "host-toolchain-linux",
297*61c4878aSAndroid Build Coastguard Worker   )
298*61c4878aSAndroid Build Coastguard Worker
299*61c4878aSAndroid Build Coastguard Worker   # pw_cc_toolchain_feature examples taken from https://cs.opensource.google/pigweed/pigweed/+/main:pw_toolchain_bazel/features/BUILD.bazel;l=21-34;drc=f96fd31675d136bd37a7f3840102cb256d555cea.
300*61c4878aSAndroid Build Coastguard Worker
301*61c4878aSAndroid Build Coastguard Worker   # Disables linking of the default C++ standard library to allow linking of a
302*61c4878aSAndroid Build Coastguard Worker   # different version.
303*61c4878aSAndroid Build Coastguard Worker   pw_cc_toolchain_feature(
304*61c4878aSAndroid Build Coastguard Worker       name = "no_default_cpp_stdlib",
305*61c4878aSAndroid Build Coastguard Worker       linkopts = ["-nostdlib++"],
306*61c4878aSAndroid Build Coastguard Worker   )
307*61c4878aSAndroid Build Coastguard Worker
308*61c4878aSAndroid Build Coastguard Worker   # Prevent relative paths from being converted to absolute paths.
309*61c4878aSAndroid Build Coastguard Worker   # Note: This initial prototype made this a feature, but it should instead
310*61c4878aSAndroid Build Coastguard Worker   # exist as a flag_set.
311*61c4878aSAndroid Build Coastguard Worker   pw_cc_toolchain_feature(
312*61c4878aSAndroid Build Coastguard Worker       name = "no_canonical_prefixes",
313*61c4878aSAndroid Build Coastguard Worker       copts = [
314*61c4878aSAndroid Build Coastguard Worker           "-no-canonical-prefixes",
315*61c4878aSAndroid Build Coastguard Worker       ],
316*61c4878aSAndroid Build Coastguard Worker   )
317*61c4878aSAndroid Build Coastguard Worker
318*61c4878aSAndroid Build Coastguard WorkerWhat’s worth noting is that the ``pw_cc_toolchain_feature`` build rule looks
319*61c4878aSAndroid Build Coastguard Workervery similar to a GN ``config``. This was no mistake, and was an attempt to
320*61c4878aSAndroid Build Coastguard Workersubstantially reduce the boiler plate for creating new sharable compiler flag
321*61c4878aSAndroid Build Coastguard Workergroups.
322*61c4878aSAndroid Build Coastguard Worker
323*61c4878aSAndroid Build Coastguard WorkerUnfortunately, it quickly became apparent that this approach limited control
324*61c4878aSAndroid Build Coastguard Workerover the underlying toolchain definition creation process. In order to support
325*61c4878aSAndroid Build Coastguard Worker``always_link`` on macOS, a custom logic and flags had to be directly baked into
326*61c4878aSAndroid Build Coastguard Workerthe rule used to declare toolchains
327*61c4878aSAndroid Build Coastguard Worker(`relevant change <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/168614/17/pw_toolchain_bazel/cc_toolchain/private/cc_toolchain.bzl>`_).
328*61c4878aSAndroid Build Coastguard WorkerWhile workarounds like this should be possible, the fact that this had to be
329*61c4878aSAndroid Build Coastguard Workerupstreamed internally to ``pw_cc_toolchain`` exposed limitations in the
330*61c4878aSAndroid Build Coastguard Workerabstraction patterns that were established. Such limitations could preclude
331*61c4878aSAndroid Build Coastguard Workersome project from using ``pw_cc_toolchain`` at all.
332*61c4878aSAndroid Build Coastguard Worker
333*61c4878aSAndroid Build Coastguard Worker---------------
334*61c4878aSAndroid Build Coastguard WorkerDetailed design
335*61c4878aSAndroid Build Coastguard Worker---------------
336*61c4878aSAndroid Build Coastguard WorkerThe core design proposal is to transform the providers used by
337*61c4878aSAndroid Build Coastguard Worker``cc_common.create_cc_toolchain_config_info()`` into build rules. The approach
338*61c4878aSAndroid Build Coastguard Workerhas been prototyped
339*61c4878aSAndroid Build Coastguard Worker`here <https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/168351/1>`_,
340*61c4878aSAndroid Build Coastguard Workerand retains API compatibility with the initial prototype as a proof-of-concept.
341*61c4878aSAndroid Build Coastguard Worker
342*61c4878aSAndroid Build Coastguard WorkerOne core pattern established by this design is transforming content that would
343*61c4878aSAndroid Build Coastguard Workertypically live as Starlark to instead live in build files. This is done to
344*61c4878aSAndroid Build Coastguard Workermake it easier to read and reference existing work.
345*61c4878aSAndroid Build Coastguard Worker
346*61c4878aSAndroid Build Coastguard WorkerImplementation requirements
347*61c4878aSAndroid Build Coastguard Worker===========================
348*61c4878aSAndroid Build Coastguard WorkerCompatibility with native C/C++ rules
349*61c4878aSAndroid Build Coastguard Worker-------------------------------------
350*61c4878aSAndroid Build Coastguard WorkerThe core of Pigweed's toolchain build rules will rely on the providers
351*61c4878aSAndroid Build Coastguard Workerdefined as part of Bazel's
352*61c4878aSAndroid Build Coastguard Worker`rules_cc <https://github.com/bazelbuild/rules_cc/blob/main/cc/cc_toolchain_config_lib.bzl>`_. This means that the new rules can interop with
353*61c4878aSAndroid Build Coastguard Workerexisting work that directly uses these toolchain primitives. It also provides
354*61c4878aSAndroid Build Coastguard Workera clear path for migrating existing toolchains piece-by-piece (which may be
355*61c4878aSAndroid Build Coastguard Workerwritten completely in Starlark).
356*61c4878aSAndroid Build Coastguard Worker
357*61c4878aSAndroid Build Coastguard WorkerAny extensions beyond the existing providers (e.g. specifying
358*61c4878aSAndroid Build Coastguard Worker``additional_files`` on a ``pw_cc_tool``) must happen parallel to existing
359*61c4878aSAndroid Build Coastguard Workerproviders so that rules that consume the ``cc_toolchain_config_lib`` providers
360*61c4878aSAndroid Build Coastguard Workercan work with vanilla providers.
361*61c4878aSAndroid Build Coastguard Worker
362*61c4878aSAndroid Build Coastguard WorkerCompatibility with Bazel rules ecosystem
363*61c4878aSAndroid Build Coastguard Worker----------------------------------------
364*61c4878aSAndroid Build Coastguard WorkerIn following with the larger Bazel rules ecosystem, the toolchain building
365*61c4878aSAndroid Build Coastguard Workerblocks will be designed such that they can be used independently from Pigweed.
366*61c4878aSAndroid Build Coastguard WorkerThis allows this work to be used for non-embedded projects, and reduces the
367*61c4878aSAndroid Build Coastguard Workeroverhead for standing up a custom Bazel C/C++ toolchain in any arbitrary
368*61c4878aSAndroid Build Coastguard Workerproject.
369*61c4878aSAndroid Build Coastguard Worker
370*61c4878aSAndroid Build Coastguard WorkerInitially, the work will live as ``pw_toolchain_bazel`` in the main Pigweed
371*61c4878aSAndroid Build Coastguard Workerrepository to facilitate testing. This module must not depend on any other
372*61c4878aSAndroid Build Coastguard Workeraspects of Pigweed. As the toolchain rules mature, they will eventually be
373*61c4878aSAndroid Build Coastguard Workeravailable as a separate repository to match the modularity patterns used by
374*61c4878aSAndroid Build Coastguard Workerthe larger Bazel rules ecosystem.
375*61c4878aSAndroid Build Coastguard Worker
376*61c4878aSAndroid Build Coastguard WorkerIntroduce ``pw_cc_flag_set`` and ``pw_cc_flag_group``
377*61c4878aSAndroid Build Coastguard Worker=====================================================
378*61c4878aSAndroid Build Coastguard WorkerThe majority of build flags would be expressed as ``pw_cc_flag_set`` and
379*61c4878aSAndroid Build Coastguard Worker``pw_cc_flag_group`` pairs.
380*61c4878aSAndroid Build Coastguard Worker
381*61c4878aSAndroid Build Coastguard Worker.. code-block::
382*61c4878aSAndroid Build Coastguard Worker
383*61c4878aSAndroid Build Coastguard Worker   # A simple flag_set with a single flag.
384*61c4878aSAndroid Build Coastguard Worker   pw_cc_flag_set(
385*61c4878aSAndroid Build Coastguard Worker       name = "werror",
386*61c4878aSAndroid Build Coastguard Worker       # Only applies to C/C++ compile actions (i.e. no assemble/link/ar).
387*61c4878aSAndroid Build Coastguard Worker       actions = ALL_CPP_COMPILER_ACTIONS + ALL_C_COMPILER_ACTIONS,
388*61c4878aSAndroid Build Coastguard Worker       flags = [
389*61c4878aSAndroid Build Coastguard Worker           "-Werror",
390*61c4878aSAndroid Build Coastguard Worker       ],
391*61c4878aSAndroid Build Coastguard Worker   )
392*61c4878aSAndroid Build Coastguard Worker
393*61c4878aSAndroid Build Coastguard Worker   # A flag_group that potentially expands to multiple flags.
394*61c4878aSAndroid Build Coastguard Worker   pw_cc_flag_group(
395*61c4878aSAndroid Build Coastguard Worker       name = "user_compile_options_flags",
396*61c4878aSAndroid Build Coastguard Worker       flags = ["%{user_compile_flags}"],
397*61c4878aSAndroid Build Coastguard Worker       iterate_over = "user_compile_flags",
398*61c4878aSAndroid Build Coastguard Worker       expand_if_available = "user_compile_flags",
399*61c4878aSAndroid Build Coastguard Worker   )
400*61c4878aSAndroid Build Coastguard Worker
401*61c4878aSAndroid Build Coastguard Worker   # A flag_set that relies on a non-trivial or non-constant expression of
402*61c4878aSAndroid Build Coastguard Worker   # flags.
403*61c4878aSAndroid Build Coastguard Worker   pw_cc_flag_set(
404*61c4878aSAndroid Build Coastguard Worker       name = "user_compile_options",
405*61c4878aSAndroid Build Coastguard Worker       actions = ALL_COMPILE_ACTIONS,
406*61c4878aSAndroid Build Coastguard Worker       flag_groups = [
407*61c4878aSAndroid Build Coastguard Worker           ":user_compile_options_flags",
408*61c4878aSAndroid Build Coastguard Worker       ]
409*61c4878aSAndroid Build Coastguard Worker   )
410*61c4878aSAndroid Build Coastguard Worker
411*61c4878aSAndroid Build Coastguard WorkerThese closely mimic the API of ``cc_toolchain_config_lib.flag_set()`` and
412*61c4878aSAndroid Build Coastguard Worker``cc_toolchain_config_lib.flag_group()``, with the following exceptions:
413*61c4878aSAndroid Build Coastguard Worker
414*61c4878aSAndroid Build Coastguard Worker**pw_cc_flag_set**
415*61c4878aSAndroid Build Coastguard Worker
416*61c4878aSAndroid Build Coastguard Worker*Added*
417*61c4878aSAndroid Build Coastguard Worker
418*61c4878aSAndroid Build Coastguard Worker- ``flags`` (added): Express a constant, trivial list of flags. If this is
419*61c4878aSAndroid Build Coastguard Worker  specified, ``flag_groups`` may not be specified. This eliminates the need
420*61c4878aSAndroid Build Coastguard Worker  for specifying a corresponding ``pw_cc_flag_group`` for every
421*61c4878aSAndroid Build Coastguard Worker  ``pw_cc_flag_set`` for most flags.
422*61c4878aSAndroid Build Coastguard Worker
423*61c4878aSAndroid Build Coastguard Worker**pw_cc_flag_group**
424*61c4878aSAndroid Build Coastguard Worker
425*61c4878aSAndroid Build Coastguard Worker*Removed*
426*61c4878aSAndroid Build Coastguard Worker
427*61c4878aSAndroid Build Coastguard Worker- ``expand_if_true``\, ``expand_if_false``\, ``expand_if_equal``\: More complex
428*61c4878aSAndroid Build Coastguard Worker  rules that rely on these should live as custom Starlark rules that provide a
429*61c4878aSAndroid Build Coastguard Worker  ``FlagGroupInfo``\, or ``FlagSetInfo`` (depending on which is more ergonomic
430*61c4878aSAndroid Build Coastguard Worker  to express the intent). See :ref:`pw_cc_flag_set-exceptions` below for an
431*61c4878aSAndroid Build Coastguard Worker  example that illustrates how express more complex ``flag_group``\s that rely
432*61c4878aSAndroid Build Coastguard Worker  on these attributes.
433*61c4878aSAndroid Build Coastguard Worker
434*61c4878aSAndroid Build Coastguard WorkerApplication of flags
435*61c4878aSAndroid Build Coastguard Worker--------------------
436*61c4878aSAndroid Build Coastguard WorkerFlags can be applied to a toolchain in three ways. This section attempts to
437*61c4878aSAndroid Build Coastguard Workerprovide initial guidance for where flags should be applied, though it's likely
438*61c4878aSAndroid Build Coastguard Workerbetter practices will evolve as this work sees more use. For the latest
439*61c4878aSAndroid Build Coastguard Workerguidance, please consult the official documentation when it rolls out to
440*61c4878aSAndroid Build Coastguard Worker``pw_toolchain_bazel``.
441*61c4878aSAndroid Build Coastguard Worker
442*61c4878aSAndroid Build Coastguard WorkerFlags unconditionally applied to a toolchain
443*61c4878aSAndroid Build Coastguard Worker~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
444*61c4878aSAndroid Build Coastguard WorkerThe majority of flags fall into this category. Architecture flags,
445*61c4878aSAndroid Build Coastguard Workerglobally-applied warnings, global defines, and other similar flags should be
446*61c4878aSAndroid Build Coastguard Workerapplied in the ``action_config_flag_sets`` attribute of a ``pw_cc_toolchain``
447*61c4878aSAndroid Build Coastguard Worker(see :ref:`pw_cc_toolchain-toolchain-declarations` for more information). Each
448*61c4878aSAndroid Build Coastguard Worker``pw_cc_flag_set`` (or other rule that provides a ``FlagSetInfo`` provider)
449*61c4878aSAndroid Build Coastguard Workerlisted in ``action_config_flag_sets`` is unconditionally applied to every tool
450*61c4878aSAndroid Build Coastguard Workerthat matches the ``actions`` listed in the flag set.
451*61c4878aSAndroid Build Coastguard Worker
452*61c4878aSAndroid Build Coastguard Worker.. _application-of-flags-feature-flags:
453*61c4878aSAndroid Build Coastguard Worker
454*61c4878aSAndroid Build Coastguard WorkerFeature flags
455*61c4878aSAndroid Build Coastguard Worker~~~~~~~~~~~~~
456*61c4878aSAndroid Build Coastguard WorkerFlag sets applied as features may or may not be enabled even if they are listed
457*61c4878aSAndroid Build Coastguard Workerin the ``features`` attribute of a ``pw_cc_toolchain``. The
458*61c4878aSAndroid Build Coastguard Worker`official Bazel documentation on features <https://bazel.build/docs/cc-toolchain-config-reference#features>`_
459*61c4878aSAndroid Build Coastguard Workerprovides some good guidance on when features should be employed. To summarize,
460*61c4878aSAndroid Build Coastguard Workerfeatures should be used when either they should be controllable by users
461*61c4878aSAndroid Build Coastguard Workerinvoking the build, or if they affect build behavior beyond simply
462*61c4878aSAndroid Build Coastguard Workeradding/removing flags (e.g. by introducing additional build actions).
463*61c4878aSAndroid Build Coastguard Worker
464*61c4878aSAndroid Build Coastguard WorkerFlags unconditionally applied to a tool
465*61c4878aSAndroid Build Coastguard Worker~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
466*61c4878aSAndroid Build Coastguard WorkerThese flags are flags that are bound to a particular tool. These are not
467*61c4878aSAndroid Build Coastguard Workerexpressed as part of a ``pw_cc_toolchain``, and are instead bound to a
468*61c4878aSAndroid Build Coastguard Worker``pw_cc_action_config``. This means that the flag set is unconditionally
469*61c4878aSAndroid Build Coastguard Workerapplied to every user of that action config. These kinds of flag applications
470*61c4878aSAndroid Build Coastguard Workershould be reserved for flags required to assemble a working set of tools (such
471*61c4878aSAndroid Build Coastguard Workeras generating a depfile, or adding support for static library link handling
472*61c4878aSAndroid Build Coastguard Worker:ref:`as illustrated below <pw_cc_flag_set-exceptions>`).
473*61c4878aSAndroid Build Coastguard Worker
474*61c4878aSAndroid Build Coastguard WorkerFlag application order
475*61c4878aSAndroid Build Coastguard Worker~~~~~~~~~~~~~~~~~~~~~~
476*61c4878aSAndroid Build Coastguard WorkerWhen invoking the underlying tools, the intended order of flags is as follows:
477*61c4878aSAndroid Build Coastguard Worker
478*61c4878aSAndroid Build Coastguard Worker#. Flags listed in the ``flag_sets`` list of a ``pw_cc_action_config``.
479*61c4878aSAndroid Build Coastguard Worker#. Flags listed in ``action_config_flag_sets`` of a ``pw_cc_toolchain``.
480*61c4878aSAndroid Build Coastguard Worker#. Flags listed in ``features`` of a ``pw_cc_toolchain``.
481*61c4878aSAndroid Build Coastguard Worker
482*61c4878aSAndroid Build Coastguard WorkerThese lists are intended to be sensitive to ordering, earlier items in the lists
483*61c4878aSAndroid Build Coastguard Workershould appear in the final tool invocation flags before later items in the list.
484*61c4878aSAndroid Build Coastguard Worker
485*61c4878aSAndroid Build Coastguard WorkerAs transitive dependencies between features/flags are not supported as part of
486*61c4878aSAndroid Build Coastguard Workerthis proposal, exact traversal of transitive flag dependencies will be left
487*61c4878aSAndroid Build Coastguard Workerto be decided if/when that feature is introduced. This proposal suggests
488*61c4878aSAndroid Build Coastguard Workerpostorder handling of flags as the most intuitive order.
489*61c4878aSAndroid Build Coastguard Worker
490*61c4878aSAndroid Build Coastguard Worker.. _pw_cc_flag_set-exceptions:
491*61c4878aSAndroid Build Coastguard Worker
492*61c4878aSAndroid Build Coastguard WorkerExceptions
493*61c4878aSAndroid Build Coastguard Worker----------
494*61c4878aSAndroid Build Coastguard WorkerSome flags are too complex to be nicely expressed in a Bazel build file. These
495*61c4878aSAndroid Build Coastguard Workerflag sets or flag groups will need to be expressed in Starlark as custom rules.
496*61c4878aSAndroid Build Coastguard WorkerFortunately, this will interop well with simpler flag sets since the underlying
497*61c4878aSAndroid Build Coastguard Workerproviders are all the same.
498*61c4878aSAndroid Build Coastguard Worker
499*61c4878aSAndroid Build Coastguard Worker**Example**
500*61c4878aSAndroid Build Coastguard Worker
501*61c4878aSAndroid Build Coastguard WorkerIn a Starlark file (e.g. ``//tools/llvm/llvm_ar_patch.bzl``), the required
502*61c4878aSAndroid Build Coastguard Worker``flag_set`` can be defined:
503*61c4878aSAndroid Build Coastguard Worker
504*61c4878aSAndroid Build Coastguard Worker.. code-block::
505*61c4878aSAndroid Build Coastguard Worker
506*61c4878aSAndroid Build Coastguard Worker   # Starlark rules in a .bzl file for a relatively complicated workaround for
507*61c4878aSAndroid Build Coastguard Worker   # what would normally be inherently managed by Bazel internally.
508*61c4878aSAndroid Build Coastguard Worker   # TODO: b/297413805 - Remove this implementation.
509*61c4878aSAndroid Build Coastguard Worker
510*61c4878aSAndroid Build Coastguard Worker   def _pw_cc_static_libs_to_link_impl():
511*61c4878aSAndroid Build Coastguard Worker      """Returns a flag_set provider that sets up static libraries to link."""
512*61c4878aSAndroid Build Coastguard Worker      return flag_set(
513*61c4878aSAndroid Build Coastguard Worker               actions = [
514*61c4878aSAndroid Build Coastguard Worker                   ACTION_NAMES.cpp_link_static_library,
515*61c4878aSAndroid Build Coastguard Worker               ],
516*61c4878aSAndroid Build Coastguard Worker               flag_groups = [
517*61c4878aSAndroid Build Coastguard Worker                   flag_group(
518*61c4878aSAndroid Build Coastguard Worker                       expand_if_available = "libraries_to_link",
519*61c4878aSAndroid Build Coastguard Worker                       iterate_over = "libraries_to_link",
520*61c4878aSAndroid Build Coastguard Worker                       flag_groups = [
521*61c4878aSAndroid Build Coastguard Worker                           flag_group(
522*61c4878aSAndroid Build Coastguard Worker                               expand_if_equal = variable_with_value(
523*61c4878aSAndroid Build Coastguard Worker                                   name = "libraries_to_link.type",
524*61c4878aSAndroid Build Coastguard Worker                                   value = "object_file",
525*61c4878aSAndroid Build Coastguard Worker                               ),
526*61c4878aSAndroid Build Coastguard Worker                               flags = ["%{libraries_to_link.name}"],
527*61c4878aSAndroid Build Coastguard Worker                           ),
528*61c4878aSAndroid Build Coastguard Worker                           flag_group(
529*61c4878aSAndroid Build Coastguard Worker                               expand_if_equal = variable_with_value(
530*61c4878aSAndroid Build Coastguard Worker                                   name = "libraries_to_link.type",
531*61c4878aSAndroid Build Coastguard Worker                                   value = "object_file_group",
532*61c4878aSAndroid Build Coastguard Worker                               ),
533*61c4878aSAndroid Build Coastguard Worker                               flags = ["%{libraries_to_link.object_files}"],
534*61c4878aSAndroid Build Coastguard Worker                               iterate_over = "libraries_to_link.object_files",
535*61c4878aSAndroid Build Coastguard Worker                           ),
536*61c4878aSAndroid Build Coastguard Worker                       ],
537*61c4878aSAndroid Build Coastguard Worker                   ),
538*61c4878aSAndroid Build Coastguard Worker               ],
539*61c4878aSAndroid Build Coastguard Worker           )
540*61c4878aSAndroid Build Coastguard Worker
541*61c4878aSAndroid Build Coastguard Worker   pw_cc_static_libs_to_link = rule(
542*61c4878aSAndroid Build Coastguard Worker       implementation = _pw_cc_static_libs_to_link_impl,
543*61c4878aSAndroid Build Coastguard Worker       provides = [FlagSetInfo],
544*61c4878aSAndroid Build Coastguard Worker   )
545*61c4878aSAndroid Build Coastguard Worker
546*61c4878aSAndroid Build Coastguard WorkerAnd then in the ``BUILD.bazel`` file, the rules would be used as if they
547*61c4878aSAndroid Build Coastguard Workerwere a ``pw_cc_flag_set``:
548*61c4878aSAndroid Build Coastguard Worker
549*61c4878aSAndroid Build Coastguard Worker.. code-block::
550*61c4878aSAndroid Build Coastguard Worker
551*61c4878aSAndroid Build Coastguard Worker   load(
552*61c4878aSAndroid Build Coastguard Worker       "@pw_toolchain//tools/llvm:llvm_ar_patch.bzl",
553*61c4878aSAndroid Build Coastguard Worker       "pw_cc_static_libs_to_link"
554*61c4878aSAndroid Build Coastguard Worker   )
555*61c4878aSAndroid Build Coastguard Worker
556*61c4878aSAndroid Build Coastguard Worker   pw_cc_static_libs_to_link(
557*61c4878aSAndroid Build Coastguard Worker       name = "static_library_action_flags",
558*61c4878aSAndroid Build Coastguard Worker   )
559*61c4878aSAndroid Build Coastguard Worker
560*61c4878aSAndroid Build Coastguard Worker   pw_cc_action_config(
561*61c4878aSAndroid Build Coastguard Worker       name = "llvm_ar",
562*61c4878aSAndroid Build Coastguard Worker       actions = ACTION_NAMES.cpp_link_static_library,
563*61c4878aSAndroid Build Coastguard Worker       tools = [
564*61c4878aSAndroid Build Coastguard Worker           ":llvm_ar_tool",
565*61c4878aSAndroid Build Coastguard Worker       ],
566*61c4878aSAndroid Build Coastguard Worker       flag_sets = [
567*61c4878aSAndroid Build Coastguard Worker           ":static_library_action_flags",
568*61c4878aSAndroid Build Coastguard Worker       ],
569*61c4878aSAndroid Build Coastguard Worker   )
570*61c4878aSAndroid Build Coastguard Worker
571*61c4878aSAndroid Build Coastguard WorkerIntroduce ``pw_cc_feature`` and ``pw_cc_feature_set``
572*61c4878aSAndroid Build Coastguard Worker=====================================================
573*61c4878aSAndroid Build Coastguard WorkerThese types are just permutations of the ``cc_toolchain_config_lib.feature()``
574*61c4878aSAndroid Build Coastguard Workerand ``cc_toolchain_config_lib.with_feature_set()`` API. For guidance on when
575*61c4878aSAndroid Build Coastguard Workerthese should be used, see
576*61c4878aSAndroid Build Coastguard Worker:ref:`application of feature flags <application-of-flags-feature-flags>`.
577*61c4878aSAndroid Build Coastguard Worker
578*61c4878aSAndroid Build Coastguard Worker.. code-block::
579*61c4878aSAndroid Build Coastguard Worker
580*61c4878aSAndroid Build Coastguard Worker   pw_cc_feature_set(
581*61c4878aSAndroid Build Coastguard Worker       name = "static_pie_requirements",
582*61c4878aSAndroid Build Coastguard Worker       with_features = ["pie"],
583*61c4878aSAndroid Build Coastguard Worker       # If this doesn't work when certain features are enabled, they should
584*61c4878aSAndroid Build Coastguard Worker       # be specified as ``without_features``.
585*61c4878aSAndroid Build Coastguard Worker   )
586*61c4878aSAndroid Build Coastguard Worker
587*61c4878aSAndroid Build Coastguard Worker   pw_cc_feature(
588*61c4878aSAndroid Build Coastguard Worker       name = "static_pie",
589*61c4878aSAndroid Build Coastguard Worker       flag_sets = [
590*61c4878aSAndroid Build Coastguard Worker           "//flag_sets:static_pie",
591*61c4878aSAndroid Build Coastguard Worker       ],
592*61c4878aSAndroid Build Coastguard Worker       implies = ["static_link_flag"],
593*61c4878aSAndroid Build Coastguard Worker       requires = [
594*61c4878aSAndroid Build Coastguard Worker           ":static_pie_requirements",
595*61c4878aSAndroid Build Coastguard Worker       ],
596*61c4878aSAndroid Build Coastguard Worker   )
597*61c4878aSAndroid Build Coastguard Worker
598*61c4878aSAndroid Build Coastguard WorkerIntroduce ``pw_cc_action_config`` and ``pw_cc_tool``
599*61c4878aSAndroid Build Coastguard Worker====================================================
600*61c4878aSAndroid Build Coastguard WorkerThese are closely related to the ``ActionConfigInfo`` and ``ToolInfo``
601*61c4878aSAndroid Build Coastguard Workerproviders, but allow additional files to be attached and a list of actions to
602*61c4878aSAndroid Build Coastguard Workerbe attached rather than a single action.
603*61c4878aSAndroid Build Coastguard Worker
604*61c4878aSAndroid Build Coastguard Worker.. code-block::
605*61c4878aSAndroid Build Coastguard Worker
606*61c4878aSAndroid Build Coastguard Worker   pw_cc_tool(
607*61c4878aSAndroid Build Coastguard Worker       name = "clang_tool",
608*61c4878aSAndroid Build Coastguard Worker       path = "@llvm_toolchain//:bin/clang",
609*61c4878aSAndroid Build Coastguard Worker       additional_files = [
610*61c4878aSAndroid Build Coastguard Worker           "@llvm_toolchain//:all",
611*61c4878aSAndroid Build Coastguard Worker       ],
612*61c4878aSAndroid Build Coastguard Worker   )
613*61c4878aSAndroid Build Coastguard Worker
614*61c4878aSAndroid Build Coastguard Worker   pw_cc_action_config(
615*61c4878aSAndroid Build Coastguard Worker       name = "clang",
616*61c4878aSAndroid Build Coastguard Worker       actions = ALL_ASM_ACTIONS + ALL_C_COMPILER_ACTIONS,
617*61c4878aSAndroid Build Coastguard Worker       tools = [
618*61c4878aSAndroid Build Coastguard Worker           ":clang_tool",
619*61c4878aSAndroid Build Coastguard Worker       ],
620*61c4878aSAndroid Build Coastguard Worker       flag_sets = [
621*61c4878aSAndroid Build Coastguard Worker           # Most flags should NOT end up here. Only unconditional flags that
622*61c4878aSAndroid Build Coastguard Worker           # should ALWAYS be bound to this tool (e.g. static library
623*61c4878aSAndroid Build Coastguard Worker           # workaround fix for macOS).
624*61c4878aSAndroid Build Coastguard Worker           "//flag_sets:generate_depfile",
625*61c4878aSAndroid Build Coastguard Worker       ],
626*61c4878aSAndroid Build Coastguard Worker   )
627*61c4878aSAndroid Build Coastguard Worker
628*61c4878aSAndroid Build Coastguard Worker.. _pw_cc_toolchain-toolchain-declarations:
629*61c4878aSAndroid Build Coastguard Worker
630*61c4878aSAndroid Build Coastguard WorkerToolchain declarations
631*61c4878aSAndroid Build Coastguard Worker======================
632*61c4878aSAndroid Build Coastguard WorkerIn following with the other proposed rules, ``pw_cc_toolchain`` largely
633*61c4878aSAndroid Build Coastguard Workerfollows the API of ``cc_common.create_cc_toolchain_config_info()``. Most of the
634*61c4878aSAndroid Build Coastguard Workerattributes are logically passed through, with the following exceptions:
635*61c4878aSAndroid Build Coastguard Worker
636*61c4878aSAndroid Build Coastguard Worker- **action_config_flag_sets**: Flag sets to apply to action configs. Since flag
637*61c4878aSAndroid Build Coastguard Worker  sets are intrinsically bound to actions, there’s no need to divide them at
638*61c4878aSAndroid Build Coastguard Worker  this level.
639*61c4878aSAndroid Build Coastguard Worker- **additional_files**: Now that tools can spec out required files, those
640*61c4878aSAndroid Build Coastguard Worker  should be propagated and mostly managed internally. The ``\*_files`` members
641*61c4878aSAndroid Build Coastguard Worker  will still be available, but shouldn’t see much use. additional_files is like
642*61c4878aSAndroid Build Coastguard Worker  “all_files”, but applies to all action_configs.
643*61c4878aSAndroid Build Coastguard Worker
644*61c4878aSAndroid Build Coastguard Worker.. code-block::
645*61c4878aSAndroid Build Coastguard Worker
646*61c4878aSAndroid Build Coastguard Worker   pw_cc_toolchain(
647*61c4878aSAndroid Build Coastguard Worker       name = "host_toolchain_linux",
648*61c4878aSAndroid Build Coastguard Worker       abi_libc_version = "unknown",  # We should consider how to move this out in the future.
649*61c4878aSAndroid Build Coastguard Worker       abi_version = "unknown",
650*61c4878aSAndroid Build Coastguard Worker       action_configs = [
651*61c4878aSAndroid Build Coastguard Worker           "@llvm_toolchain//tools:clang",
652*61c4878aSAndroid Build Coastguard Worker           "@llvm_toolchain//tools:clang++",
653*61c4878aSAndroid Build Coastguard Worker           "@llvm_toolchain//tools:lld",
654*61c4878aSAndroid Build Coastguard Worker           "@llvm_toolchain//tools:llvm_ar",
655*61c4878aSAndroid Build Coastguard Worker           "@llvm_toolchain//tools:llvm_cov",
656*61c4878aSAndroid Build Coastguard Worker           "@llvm_toolchain//tools:llvm_strip",
657*61c4878aSAndroid Build Coastguard Worker       ],
658*61c4878aSAndroid Build Coastguard Worker       additional_files = ":linux_sysroot_files",
659*61c4878aSAndroid Build Coastguard Worker       action_config_flag_sets = [
660*61c4878aSAndroid Build Coastguard Worker           ":linux_sysroot",
661*61c4878aSAndroid Build Coastguard Worker           "@pw_toolchain//flag_collections:strict_warnings",
662*61c4878aSAndroid Build Coastguard Worker           "@pw_toolchain//flag_sets:no_canonical_prefixes",
663*61c4878aSAndroid Build Coastguard Worker       ],
664*61c4878aSAndroid Build Coastguard Worker       features = [
665*61c4878aSAndroid Build Coastguard Worker           "@pw_toolchain//features:c++17",
666*61c4878aSAndroid Build Coastguard Worker       ],
667*61c4878aSAndroid Build Coastguard Worker       host_system_name = "unknown",
668*61c4878aSAndroid Build Coastguard Worker       supports_param_files = 0,  # Seems like this should be attached to a pw_cc_action_config...
669*61c4878aSAndroid Build Coastguard Worker       target_cpu = "unknown",
670*61c4878aSAndroid Build Coastguard Worker       target_libc = "unknown",
671*61c4878aSAndroid Build Coastguard Worker       target_system_name = "unknown",
672*61c4878aSAndroid Build Coastguard Worker       toolchain_identifier = "host-toolchain-linux",
673*61c4878aSAndroid Build Coastguard Worker       cxx_builtin_include_directories = [
674*61c4878aSAndroid Build Coastguard Worker           "%package(@llvm_toolchain//)%/include/x86_64-unknown-linux-gnu/c++/v1",
675*61c4878aSAndroid Build Coastguard Worker           "%package(@llvm_toolchain//)%/include/c++/v1",
676*61c4878aSAndroid Build Coastguard Worker           "%package(@llvm_toolchain//)%/lib/clang/17/include",
677*61c4878aSAndroid Build Coastguard Worker           "%sysroot%/usr/local/include",
678*61c4878aSAndroid Build Coastguard Worker           "%sysroot%/usr/include/x86_64-linux-gnu",
679*61c4878aSAndroid Build Coastguard Worker           "%sysroot%/usr/include",
680*61c4878aSAndroid Build Coastguard Worker       ],
681*61c4878aSAndroid Build Coastguard Worker   )
682*61c4878aSAndroid Build Coastguard Worker
683*61c4878aSAndroid Build Coastguard Worker------------
684*61c4878aSAndroid Build Coastguard WorkerAlternatives
685*61c4878aSAndroid Build Coastguard Worker------------
686*61c4878aSAndroid Build Coastguard WorkerImprove Bazel's native C/C++ toolchain rules
687*61c4878aSAndroid Build Coastguard Worker============================================
688*61c4878aSAndroid Build Coastguard WorkerImproving Bazel's native rules for defining C/C++ toolchains is out of the
689*61c4878aSAndroid Build Coastguard Workerscope of Pigweed's work. Changing the underlying toolchain API as Bazel
690*61c4878aSAndroid Build Coastguard Workerunderstands it is a massive undertaking from the perspective of migrating
691*61c4878aSAndroid Build Coastguard Workerexisting code. We hope that the custom rule effort can help guide future
692*61c4878aSAndroid Build Coastguard Workerdecisions when it comes to toolchain scalability and maintainability.
693*61c4878aSAndroid Build Coastguard Worker
694*61c4878aSAndroid Build Coastguard Worker----------
695*61c4878aSAndroid Build Coastguard WorkerNext steps
696*61c4878aSAndroid Build Coastguard Worker----------
697*61c4878aSAndroid Build Coastguard WorkerRust toolchain interop
698*61c4878aSAndroid Build Coastguard Worker======================
699*61c4878aSAndroid Build Coastguard WorkerPigweed's Rust toolchains have some interoperability concerns and requirements.
700*61c4878aSAndroid Build Coastguard WorkerThe extend of this needs to be thoroughly investigated as a next step to ensure
701*61c4878aSAndroid Build Coastguard Workerthat the Rust/C/C++ toolchain experience is relatively unified and ergonomic.
702*61c4878aSAndroid Build Coastguard Worker
703*61c4878aSAndroid Build Coastguard WorkerMore maintainable ``cxx_builtin_include_directories``
704*61c4878aSAndroid Build Coastguard Worker=====================================================
705*61c4878aSAndroid Build Coastguard WorkerIn the future, it would be nice to have a more sharable solution for managing
706*61c4878aSAndroid Build Coastguard Worker``cxx_builtin_include_directories`` on a ``pw_cc_toolchain``. This could
707*61c4878aSAndroid Build Coastguard Workerplausibly be done by allowing ``pw_cc_flag_set`` to express
708*61c4878aSAndroid Build Coastguard Worker``cxx_builtin_include_directories`` so they can be propagated back up to the
709*61c4878aSAndroid Build Coastguard Worker``pw_cc_toolchain``.
710*61c4878aSAndroid Build Coastguard Worker
711*61c4878aSAndroid Build Coastguard WorkerFeature name collision guidance
712*61c4878aSAndroid Build Coastguard Worker===============================
713*61c4878aSAndroid Build Coastguard WorkerFeatures support relatively complex relationships among each other, but
714*61c4878aSAndroid Build Coastguard Workertraditionally rely on string names to express these relationships rather than
715*61c4878aSAndroid Build Coastguard Workerlabels. This introduces significant ambiguity, as it's possible for multiple
716*61c4878aSAndroid Build Coastguard Workerfeatures to use the same logical name so long as they aren't both employed in
717*61c4878aSAndroid Build Coastguard Workerthe same toolchain. In practice, the only way to tell what features will end up
718*61c4878aSAndroid Build Coastguard Workerenabled is to manually unpack what features a toolchain pulls in, and
719*61c4878aSAndroid Build Coastguard Workercross-reference it against the output of
720*61c4878aSAndroid Build Coastguard Worker`--experimental_save_feature_state <https://bazel.build/reference/command-line-reference#flag--experimental_save_feature_state>`_.
721*61c4878aSAndroid Build Coastguard Worker
722*61c4878aSAndroid Build Coastguard WorkerOne potential solution to this problem is to add a mechanism for expressing
723*61c4878aSAndroid Build Coastguard Workerfeatures as labels, which will allow relationships to be expressed more
724*61c4878aSAndroid Build Coastguard Workerconcretely, and help prevent unintended naming collisions. This would not
725*61c4878aSAndroid Build Coastguard Workerreplace the ability to express relationships with features not accessible via
726*61c4878aSAndroid Build Coastguard Workerlabels, but rather live alongside it.
727