xref: /aosp_15_r20/external/pigweed/docs/bazel_compatibility.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker==================================
4*61c4878aSAndroid Build Coastguard WorkerBazel build compatibility patterns
5*61c4878aSAndroid Build Coastguard Worker==================================
6*61c4878aSAndroid Build Coastguard WorkerThis document describes the Bazel patterns Pigweed uses to express that a build
7*61c4878aSAndroid Build Coastguard Workertarget is compatible with a platform. The main motivation is to enable
8*61c4878aSAndroid Build Coastguard Workermaintainable :ref:`wildcard builds <docs-bazel-compatibility-why-wildcard>` of
9*61c4878aSAndroid Build Coastguard Workerupstream Pigweed for non-host platforms:
10*61c4878aSAndroid Build Coastguard Worker
11*61c4878aSAndroid Build Coastguard Worker.. code-block:: sh
12*61c4878aSAndroid Build Coastguard Worker
13*61c4878aSAndroid Build Coastguard Worker   bazelisk build --config=rp2040 //...
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard WorkerThe bulk of this document describes :ref:`recommended patterns
16*61c4878aSAndroid Build Coastguard Worker<docs-bazel-compatibility-recommended>` for expressing compatibility in various
17*61c4878aSAndroid Build Coastguard Workerscenarios. For context, we also discuss :ref:`alternative patterns
18*61c4878aSAndroid Build Coastguard Worker<docs-bazel-compatibility-not-recommended>` and why they should be avoided.
19*61c4878aSAndroid Build Coastguard WorkerFor the implementation plan, see
20*61c4878aSAndroid Build Coastguard Worker:ref:`docs-bazel-compatibility-implementation-plan`.
21*61c4878aSAndroid Build Coastguard Worker
22*61c4878aSAndroid Build Coastguard WorkerSee :ref:`docs-bazel-compatibility-background` and the `Platforms documentation
23*61c4878aSAndroid Build Coastguard Worker<https://bazel.build/extending/platforms>`_ for more context.
24*61c4878aSAndroid Build Coastguard Worker
25*61c4878aSAndroid Build Coastguard Worker-----------------
26*61c4878aSAndroid Build Coastguard WorkerIntended audience
27*61c4878aSAndroid Build Coastguard Worker-----------------
28*61c4878aSAndroid Build Coastguard WorkerThis document is targeted at *upstream Pigweed developers*. The patterns
29*61c4878aSAndroid Build Coastguard Workerdescribed here are suitable for downstream projects, too, but downstream
30*61c4878aSAndroid Build Coastguard Workerprojects can employ a broader variety of approaches. Because Pigweed is
31*61c4878aSAndroid Build Coastguard Workermiddleware that must preserve users' flexibility in configuring it, we need to
32*61c4878aSAndroid Build Coastguard Workerbe more careful.
33*61c4878aSAndroid Build Coastguard Worker
34*61c4878aSAndroid Build Coastguard WorkerThis document assumes you're familiar with regular Bazel usage, but perhaps not
35*61c4878aSAndroid Build Coastguard WorkerBazel's build configurability primitives.
36*61c4878aSAndroid Build Coastguard Worker
37*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-recommended:
38*61c4878aSAndroid Build Coastguard Worker
39*61c4878aSAndroid Build Coastguard Worker----------------------------------
40*61c4878aSAndroid Build Coastguard WorkerRecommended compatibility patterns
41*61c4878aSAndroid Build Coastguard Worker----------------------------------
42*61c4878aSAndroid Build Coastguard Worker
43*61c4878aSAndroid Build Coastguard WorkerSummary
44*61c4878aSAndroid Build Coastguard Worker=======
45*61c4878aSAndroid Build Coastguard WorkerHere's a short but complete summary of the recommendations.
46*61c4878aSAndroid Build Coastguard Worker
47*61c4878aSAndroid Build Coastguard WorkerFor library authors
48*61c4878aSAndroid Build Coastguard Worker-------------------
49*61c4878aSAndroid Build Coastguard WorkerA library is anything represented as a ``cc_library``, ``rust_library``, or
50*61c4878aSAndroid Build Coastguard Workersimilar target that other code is expected to depend on.
51*61c4878aSAndroid Build Coastguard Worker
52*61c4878aSAndroid Build Coastguard Worker#. Rely on :ref:`your dependencies' constraints
53*61c4878aSAndroid Build Coastguard Worker   <docs-bazel-compatibility-inherited>` (which you implicitly inherit)
54*61c4878aSAndroid Build Coastguard Worker   whenever possible.
55*61c4878aSAndroid Build Coastguard Worker#. Otherwise, use one of the :ref:`well-known constraints
56*61c4878aSAndroid Build Coastguard Worker   <docs-bazel-compatibility-well-known>`.
57*61c4878aSAndroid Build Coastguard Worker#. If no well-known constraint fits the bill, introduce a :ref:`module-specific
58*61c4878aSAndroid Build Coastguard Worker   constraint <docs-bazel-compatibility-module-specific>`.
59*61c4878aSAndroid Build Coastguard Worker
60*61c4878aSAndroid Build Coastguard WorkerFor facade authors
61*61c4878aSAndroid Build Coastguard Worker------------------
62*61c4878aSAndroid Build Coastguard Worker:ref:`Facade <docs-facades>` authors are library authors, too. But there are
63*61c4878aSAndroid Build Coastguard Workersome special considerations that apply to facades.
64*61c4878aSAndroid Build Coastguard Worker
65*61c4878aSAndroid Build Coastguard Worker#. :ref:`The facade's default backend should be unspecified
66*61c4878aSAndroid Build Coastguard Worker   <docs-bazel-compatibility-facade-default-backend>`.
67*61c4878aSAndroid Build Coastguard Worker#. If you want to make it easy for users to select a group of backends for
68*61c4878aSAndroid Build Coastguard Worker   related facades simultaneously, :ref:`provide dicts of such backends
69*61c4878aSAndroid Build Coastguard Worker   <docs-bazel-compatibility-facade-backend-dict>` for their use. :ref:`Don't
70*61c4878aSAndroid Build Coastguard Worker   provide multiplexer targets <docs-bazel-compatibility-multiplexer>`.
71*61c4878aSAndroid Build Coastguard Worker#. Whenever possible, :ref:`ensure backends fully implement a facade's
72*61c4878aSAndroid Build Coastguard Worker   interface <docs-bazel-compatibility-facade-backend-interface>`.
73*61c4878aSAndroid Build Coastguard Worker#. When implementing backend-specific tests, you may :ref:`introduce a config
74*61c4878aSAndroid Build Coastguard Worker   setting consuming a label flag <docs-bazel-compatibility-config-setting>`.
75*61c4878aSAndroid Build Coastguard Worker
76*61c4878aSAndroid Build Coastguard WorkerFor SDK build authors
77*61c4878aSAndroid Build Coastguard Worker---------------------
78*61c4878aSAndroid Build Coastguard Worker
79*61c4878aSAndroid Build Coastguard Worker#. :ref:`Provide config headers through a default-incompatible label flag
80*61c4878aSAndroid Build Coastguard Worker   <docs-bazel-compatibility-incompatible-label-flag>`.
81*61c4878aSAndroid Build Coastguard Worker
82*61c4878aSAndroid Build Coastguard WorkerPatterns for library authors
83*61c4878aSAndroid Build Coastguard Worker============================
84*61c4878aSAndroid Build Coastguard Worker
85*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-inherited:
86*61c4878aSAndroid Build Coastguard Worker
87*61c4878aSAndroid Build Coastguard WorkerInherited incompatibility
88*61c4878aSAndroid Build Coastguard Worker-------------------------
89*61c4878aSAndroid Build Coastguard WorkerTargets that transitively depend on incompatible targets are themselves
90*61c4878aSAndroid Build Coastguard Workerconsidered incompatible. This implies that many build targets do not need a
91*61c4878aSAndroid Build Coastguard Worker``target_compatible_with`` attribute.
92*61c4878aSAndroid Build Coastguard Worker
93*61c4878aSAndroid Build Coastguard WorkerExample: your target uses ``//pw_stream:socket_stream`` for RPC communication,
94*61c4878aSAndroid Build Coastguard Workerand ``socket_stream`` requires POSIX sockets. Your target *should not* try to
95*61c4878aSAndroid Build Coastguard Workerexpress this compatibility restriction through the ``target_compatible_with``
96*61c4878aSAndroid Build Coastguard Workerattribute. It will automatically inherit it from ``socket_stream``!
97*61c4878aSAndroid Build Coastguard Worker
98*61c4878aSAndroid Build Coastguard WorkerA particularly important special case are label flags which by default point to
99*61c4878aSAndroid Build Coastguard Workeran always-incompatible target, often :ref:`provided by SDKs
100*61c4878aSAndroid Build Coastguard Worker<docs-bazel-compatibility-incompatible-label-flag>`.
101*61c4878aSAndroid Build Coastguard Worker
102*61c4878aSAndroid Build Coastguard WorkerAsserting compatibility
103*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^^
104*61c4878aSAndroid Build Coastguard WorkerInherited incompatibility is very convenient, but can be dangerous. A change in
105*61c4878aSAndroid Build Coastguard Workerthe transitive dependencies can unexpectedly make a top-level target
106*61c4878aSAndroid Build Coastguard Workerincompatible with a platform it should build for. How to minimize this risk?
107*61c4878aSAndroid Build Coastguard Worker
108*61c4878aSAndroid Build Coastguard WorkerFor tests, the risk is relatively low because ``bazel test`` will print a list
109*61c4878aSAndroid Build Coastguard Workerof SKIPPED tests as part of its output.
110*61c4878aSAndroid Build Coastguard Worker
111*61c4878aSAndroid Build Coastguard Worker.. note::
112*61c4878aSAndroid Build Coastguard Worker
113*61c4878aSAndroid Build Coastguard Worker   TODO: https://pwbug.dev/347752345 - Come up with a way to mitigate the risk
114*61c4878aSAndroid Build Coastguard Worker   of accidentally skipping tests due to incompatibility.
115*61c4878aSAndroid Build Coastguard Worker
116*61c4878aSAndroid Build Coastguard WorkerFor final firmware images, assert that the image is compatible with the
117*61c4878aSAndroid Build Coastguard Workerintended platform by explicitly listing it in CI invocations:
118*61c4878aSAndroid Build Coastguard Worker
119*61c4878aSAndroid Build Coastguard Worker.. code-block:: sh
120*61c4878aSAndroid Build Coastguard Worker
121*61c4878aSAndroid Build Coastguard Worker   # //pw_system:system_example is a binary that should build for this
122*61c4878aSAndroid Build Coastguard Worker   # platform.
123*61c4878aSAndroid Build Coastguard Worker   bazelisk build --config=rp2040 //... //pw_system:system_example
124*61c4878aSAndroid Build Coastguard Worker
125*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-well-known:
126*61c4878aSAndroid Build Coastguard Worker
127*61c4878aSAndroid Build Coastguard WorkerWell-known constraints
128*61c4878aSAndroid Build Coastguard Worker----------------------
129*61c4878aSAndroid Build Coastguard WorkerIf we introduced a separate constraint value for every module that's not purely
130*61c4878aSAndroid Build Coastguard Workeralgorithmic, downstream users' platforms would become needlessly verbose. For
131*61c4878aSAndroid Build Coastguard Workercertain well-defined categories of dependency we will introduce "well-known"
132*61c4878aSAndroid Build Coastguard Workerconstraint values that may be reused by multiple modules.
133*61c4878aSAndroid Build Coastguard Worker
134*61c4878aSAndroid Build Coastguard Worker.. tip::
135*61c4878aSAndroid Build Coastguard Worker
136*61c4878aSAndroid Build Coastguard Worker   When a module's assumptions about the underlying platform are fully captured
137*61c4878aSAndroid Build Coastguard Worker   by one of these well-known constraints, reuse them instead of creating a
138*61c4878aSAndroid Build Coastguard Worker   module-specific constraint.
139*61c4878aSAndroid Build Coastguard Worker
140*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-well-known-os:
141*61c4878aSAndroid Build Coastguard Worker
142*61c4878aSAndroid Build Coastguard WorkerOS-specific modules
143*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^
144*61c4878aSAndroid Build Coastguard WorkerSome build targets are compatible only with specific operating systems.  For
145*61c4878aSAndroid Build Coastguard Workerexample, ``pw_digital_io_linux`` uses Linux syscalls. Such targets should be
146*61c4878aSAndroid Build Coastguard Workerannotated with the appropriate canonical OS ``constraint_value`` from the
147*61c4878aSAndroid Build Coastguard Worker`platforms repo <https://github.com/bazelbuild/platforms>`_:
148*61c4878aSAndroid Build Coastguard Worker
149*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
150*61c4878aSAndroid Build Coastguard Worker
151*61c4878aSAndroid Build Coastguard Worker   cc_library(
152*61c4878aSAndroid Build Coastguard Worker     name = "pw_digital_io_linux",
153*61c4878aSAndroid Build Coastguard Worker     target_compatible_with = ["@platforms//os:linux"],
154*61c4878aSAndroid Build Coastguard Worker   )
155*61c4878aSAndroid Build Coastguard Worker
156*61c4878aSAndroid Build Coastguard WorkerCross-platform modules requiring an OS
157*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
158*61c4878aSAndroid Build Coastguard WorkerSome build targets are only intended for use on platforms with a fully-featured
159*61c4878aSAndroid Build Coastguard WorkerOS (i.e., not on microcontrollers, but on the developer's laptop or
160*61c4878aSAndroid Build Coastguard Workerworkstation, or on an embedded Linux system), *but* are cross-platform and not
161*61c4878aSAndroid Build Coastguard Workerrestricted to one *particular* OS.  Example: an integration test written in Go
162*61c4878aSAndroid Build Coastguard Workerthat starts subprocesses using the ``os/exec`` standard library package.
163*61c4878aSAndroid Build Coastguard Worker
164*61c4878aSAndroid Build Coastguard WorkerFor these cross-platform targets, use the ``incompatible_with_mcu`` helper:
165*61c4878aSAndroid Build Coastguard Worker
166*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
167*61c4878aSAndroid Build Coastguard Worker
168*61c4878aSAndroid Build Coastguard Worker   load("@pigweed//pw_build:compatibility.bzl", "incompatible_with_mcu")
169*61c4878aSAndroid Build Coastguard Worker
170*61c4878aSAndroid Build Coastguard Worker   go_test(
171*61c4878aSAndroid Build Coastguard Worker       name = "integration_test",
172*61c4878aSAndroid Build Coastguard Worker       target_compatible_with = incompatible_with_mcu(),
173*61c4878aSAndroid Build Coastguard Worker   )
174*61c4878aSAndroid Build Coastguard Worker
175*61c4878aSAndroid Build Coastguard Worker.. note::
176*61c4878aSAndroid Build Coastguard Worker
177*61c4878aSAndroid Build Coastguard Worker   RTOSes are not OSes in the sense of this section. See
178*61c4878aSAndroid Build Coastguard Worker   :ref:`docs-bazel-compatibility-rtos`.
179*61c4878aSAndroid Build Coastguard Worker
180*61c4878aSAndroid Build Coastguard WorkerCPU-specific modules (rare)
181*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^^^^^^
182*61c4878aSAndroid Build Coastguard WorkerSome build targets are only intended for particular CPU architectures. In this
183*61c4878aSAndroid Build Coastguard Workercase, use the canonical CPU ``constraint_value`` from the
184*61c4878aSAndroid Build Coastguard Worker`platforms repo <https://github.com/bazelbuild/platforms>`_:
185*61c4878aSAndroid Build Coastguard Worker
186*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
187*61c4878aSAndroid Build Coastguard Worker
188*61c4878aSAndroid Build Coastguard Worker   cc_library(
189*61c4878aSAndroid Build Coastguard Worker     name = "pw_interrupt_cortex_m",
190*61c4878aSAndroid Build Coastguard Worker     # Compatible only with Cortex-M processors.
191*61c4878aSAndroid Build Coastguard Worker     target_compatible_with = select({
192*61c4878aSAndroid Build Coastguard Worker       "@platforms//cpu:armv6-m": [],
193*61c4878aSAndroid Build Coastguard Worker       "@platforms//cpu:armv7-m": [],
194*61c4878aSAndroid Build Coastguard Worker       "@platforms//cpu:armv7e-m": [],
195*61c4878aSAndroid Build Coastguard Worker       "@platforms//cpu:armv7e-mf": [],
196*61c4878aSAndroid Build Coastguard Worker       "@platforms//cpu:armv8-m": [],
197*61c4878aSAndroid Build Coastguard Worker   )
198*61c4878aSAndroid Build Coastguard Worker
199*61c4878aSAndroid Build Coastguard WorkerSDK-provided constraints
200*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^^^
201*61c4878aSAndroid Build Coastguard WorkerIf a module depends on a third-party SDK, and that SDK has ``BUILD.bazel``
202*61c4878aSAndroid Build Coastguard Workerfiles that define ``constraint_values``, feel free to use those authoritative
203*61c4878aSAndroid Build Coastguard Workervalues to indicate target compatibility.
204*61c4878aSAndroid Build Coastguard Worker
205*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
206*61c4878aSAndroid Build Coastguard Worker
207*61c4878aSAndroid Build Coastguard Worker   cc_library(
208*61c4878aSAndroid Build Coastguard Worker       name = "pw_digital_io_rp2040",
209*61c4878aSAndroid Build Coastguard Worker       deps = [
210*61c4878aSAndroid Build Coastguard Worker           # Depends on the Pico SDK.
211*61c4878aSAndroid Build Coastguard Worker           "@pico-sdk//src/rp2_common/pico_stdlib",
212*61c4878aSAndroid Build Coastguard Worker           "@pico-sdk//src/rp2_common/hardware_gpio",
213*61c4878aSAndroid Build Coastguard Worker       ],
214*61c4878aSAndroid Build Coastguard Worker       # The Pico SDK provides authoritative constraint_values.
215*61c4878aSAndroid Build Coastguard Worker       target_compatible_with = ["@pico-sdk//bazel/constraint:rp2040"],
216*61c4878aSAndroid Build Coastguard Worker   )
217*61c4878aSAndroid Build Coastguard Worker
218*61c4878aSAndroid Build Coastguard Worker.. note::
219*61c4878aSAndroid Build Coastguard Worker
220*61c4878aSAndroid Build Coastguard Worker   This also applies to SDKs or libraries for which Pigweed provides
221*61c4878aSAndroid Build Coastguard Worker   ``BUILD.bazel`` files in our ``//third_party`` directory (e.g., FreeRTOS or
222*61c4878aSAndroid Build Coastguard Worker   stm32cube).
223*61c4878aSAndroid Build Coastguard Worker
224*61c4878aSAndroid Build Coastguard Worker
225*61c4878aSAndroid Build Coastguard Worker
226*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-module-specific:
227*61c4878aSAndroid Build Coastguard Worker
228*61c4878aSAndroid Build Coastguard WorkerModule-specific constraints
229*61c4878aSAndroid Build Coastguard Worker---------------------------
230*61c4878aSAndroid Build Coastguard WorkerMany Pigweed modules are purely algorithmic: they make no assumptions about the
231*61c4878aSAndroid Build Coastguard Workerunderlying platform. But many modules *do* make assumptions, sometimes quite
232*61c4878aSAndroid Build Coastguard Workerrestrictive ones. For example, the ``pw_spi_mcuxpresso`` library includes
233*61c4878aSAndroid Build Coastguard Workerheaders from the NXP SDK and will only work for certain NXP chips.
234*61c4878aSAndroid Build Coastguard Worker
235*61c4878aSAndroid Build Coastguard WorkerFor any library that does make such assumptions, and these assumptions are not
236*61c4878aSAndroid Build Coastguard Workercaptured by one of the :ref:`well-known constraints
237*61c4878aSAndroid Build Coastguard Worker<docs-bazel-compatibility-well-known>`, the recommended pattern is to define a
238*61c4878aSAndroid Build Coastguard Worker"boolean" ``constraint_setting`` to express compatibility. We introduce some
239*61c4878aSAndroid Build Coastguard Workersyntactic sugar (:ref:`module-pw_build-bazel-boolean_constraint_value`) for
240*61c4878aSAndroid Build Coastguard Workermaking this concise.
241*61c4878aSAndroid Build Coastguard Worker
242*61c4878aSAndroid Build Coastguard WorkerExample:
243*61c4878aSAndroid Build Coastguard Worker
244*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
245*61c4878aSAndroid Build Coastguard Worker
246*61c4878aSAndroid Build Coastguard Worker   # pw_spi_mcuxpresso/BUILD.bazel
247*61c4878aSAndroid Build Coastguard Worker   load("@pigweed//pw_build:compatibility.bzl", "boolean_constraint_value")
248*61c4878aSAndroid Build Coastguard Worker
249*61c4878aSAndroid Build Coastguard Worker   boolean_constraint_value(
250*61c4878aSAndroid Build Coastguard Worker     name = "compatible",
251*61c4878aSAndroid Build Coastguard Worker   )
252*61c4878aSAndroid Build Coastguard Worker
253*61c4878aSAndroid Build Coastguard Worker   cc_library(
254*61c4878aSAndroid Build Coastguard Worker     name = "pw_spi_mcuxpresso",
255*61c4878aSAndroid Build Coastguard Worker     # srcs, deps, etc omitted
256*61c4878aSAndroid Build Coastguard Worker     target_compatible_with = [":compatible"],
257*61c4878aSAndroid Build Coastguard Worker   )
258*61c4878aSAndroid Build Coastguard Worker
259*61c4878aSAndroid Build Coastguard WorkerUsage in platforms
260*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^
261*61c4878aSAndroid Build Coastguard WorkerTo use this module, a platform must include the constraint value:
262*61c4878aSAndroid Build Coastguard Worker
263*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
264*61c4878aSAndroid Build Coastguard Worker
265*61c4878aSAndroid Build Coastguard Worker   platform(
266*61c4878aSAndroid Build Coastguard Worker     name = "downstream_platform",
267*61c4878aSAndroid Build Coastguard Worker     constraint_values = ["@pigweed//pw_spi_mcuxpresso:compatible"],
268*61c4878aSAndroid Build Coastguard Worker   )
269*61c4878aSAndroid Build Coastguard Worker
270*61c4878aSAndroid Build Coastguard WorkerIf the library happens to be a facade backend, then the platform will have to
271*61c4878aSAndroid Build Coastguard Worker*both* point the label flag to the backend and list the ``constraint_value``.
272*61c4878aSAndroid Build Coastguard Worker
273*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
274*61c4878aSAndroid Build Coastguard Worker
275*61c4878aSAndroid Build Coastguard Worker   platform(
276*61c4878aSAndroid Build Coastguard Worker     name = "downstream_platform",
277*61c4878aSAndroid Build Coastguard Worker     constraint_values = ["@pigweed//pw_sys_io_stm32cube:backend"],
278*61c4878aSAndroid Build Coastguard Worker     flags = [
279*61c4878aSAndroid Build Coastguard Worker       "--@pigweed//pw_sys_io:backend=@pigweed//pw_sys_io_stm32cube",
280*61c4878aSAndroid Build Coastguard Worker     ],
281*61c4878aSAndroid Build Coastguard Worker   )
282*61c4878aSAndroid Build Coastguard Worker
283*61c4878aSAndroid Build Coastguard Worker.. tip::
284*61c4878aSAndroid Build Coastguard Worker
285*61c4878aSAndroid Build Coastguard Worker   Just because a library is a facade backend doesn't mean it has any
286*61c4878aSAndroid Build Coastguard Worker   compatibility restrictions. Many backends (e.g., ``pw_assert_log``) have no
287*61c4878aSAndroid Build Coastguard Worker   such restrictions, and many others rely only on the well-known constraints.
288*61c4878aSAndroid Build Coastguard Worker   So, the number of ``constraint_values`` that need to be added to the typical
289*61c4878aSAndroid Build Coastguard Worker   downstream platform is substantially smaller than the number of configured
290*61c4878aSAndroid Build Coastguard Worker   backends.
291*61c4878aSAndroid Build Coastguard Worker
292*61c4878aSAndroid Build Coastguard WorkerSpecial case: host-compatible platform specific modules
293*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
294*61c4878aSAndroid Build Coastguard WorkerSome modules may require platforms to explicitly assert that they support them,
295*61c4878aSAndroid Build Coastguard Workerbut also work on host platforms by default. An example of this is
296*61c4878aSAndroid Build Coastguard Worker``pw_stream:socket_stream``. Use the following pattern:
297*61c4878aSAndroid Build Coastguard Worker
298*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
299*61c4878aSAndroid Build Coastguard Worker
300*61c4878aSAndroid Build Coastguard Worker   # pw_stream/BUILD.bazel
301*61c4878aSAndroid Build Coastguard Worker   load("@pigweed//pw_build:compatibility.bzl", "boolean_constraint_value", "incompatible_with_mcu")
302*61c4878aSAndroid Build Coastguard Worker
303*61c4878aSAndroid Build Coastguard Worker   boolean_constraint_value(
304*61c4878aSAndroid Build Coastguard Worker     name = "socket_stream_compatible",
305*61c4878aSAndroid Build Coastguard Worker   )
306*61c4878aSAndroid Build Coastguard Worker
307*61c4878aSAndroid Build Coastguard Worker   cc_library(
308*61c4878aSAndroid Build Coastguard Worker     name = "socket_stream",
309*61c4878aSAndroid Build Coastguard Worker     # Compatible with host platforms, and any platform that explicitly
310*61c4878aSAndroid Build Coastguard Worker     # lists `@pigweed//pw_stream:socket_stream_compatible` among its
311*61c4878aSAndroid Build Coastguard Worker     # constraint_values.
312*61c4878aSAndroid Build Coastguard Worker     target_compatible_with = incompatible_with_mcu(unless_platform_has=":socket_stream_compatible"),
313*61c4878aSAndroid Build Coastguard Worker   )
314*61c4878aSAndroid Build Coastguard Worker
315*61c4878aSAndroid Build Coastguard WorkerPatterns for facade authors
316*61c4878aSAndroid Build Coastguard Worker===========================
317*61c4878aSAndroid Build Coastguard Worker
318*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-facade-default-backend:
319*61c4878aSAndroid Build Coastguard Worker
320*61c4878aSAndroid Build Coastguard WorkerDon't provide default facade backends for device
321*61c4878aSAndroid Build Coastguard Worker------------------------------------------------
322*61c4878aSAndroid Build Coastguard WorkerIf the facade has no host-compatible backend, its default backend should be
323*61c4878aSAndroid Build Coastguard Worker``//pw_build:unspecified_backend``:
324*61c4878aSAndroid Build Coastguard Worker
325*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
326*61c4878aSAndroid Build Coastguard Worker
327*61c4878aSAndroid Build Coastguard Worker   label_flag(
328*61c4878aSAndroid Build Coastguard Worker     name = "backend",
329*61c4878aSAndroid Build Coastguard Worker     build_setting_default = "//pw_build:unspecified_backend",
330*61c4878aSAndroid Build Coastguard Worker   )
331*61c4878aSAndroid Build Coastguard Worker
332*61c4878aSAndroid Build Coastguard WorkerOtherwise, use the following pattern:
333*61c4878aSAndroid Build Coastguard Worker
334*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
335*61c4878aSAndroid Build Coastguard Worker
336*61c4878aSAndroid Build Coastguard Worker   load("@pigweed//pw_build:compatibility.bzl", "host_backend_alias")
337*61c4878aSAndroid Build Coastguard Worker
338*61c4878aSAndroid Build Coastguard Worker   label_flag(
339*61c4878aSAndroid Build Coastguard Worker     name = "backend",
340*61c4878aSAndroid Build Coastguard Worker     build_setting_default = ":unspecified_backend",
341*61c4878aSAndroid Build Coastguard Worker   )
342*61c4878aSAndroid Build Coastguard Worker
343*61c4878aSAndroid Build Coastguard Worker   host_backend_alias(
344*61c4878aSAndroid Build Coastguard Worker     name = "unspecified_backend",
345*61c4878aSAndroid Build Coastguard Worker     # "backend" points to the target implementing the host-compatible backend.
346*61c4878aSAndroid Build Coastguard Worker     backend = ":host_backend",
347*61c4878aSAndroid Build Coastguard Worker   )
348*61c4878aSAndroid Build Coastguard Worker
349*61c4878aSAndroid Build Coastguard WorkerThis ensures that:
350*61c4878aSAndroid Build Coastguard Worker
351*61c4878aSAndroid Build Coastguard Worker* If the target platform did not explicitly set a backend for a facade, that
352*61c4878aSAndroid Build Coastguard Worker  facade (and any target that transitively depends on it) is considered
353*61c4878aSAndroid Build Coastguard Worker  incompatible.
354*61c4878aSAndroid Build Coastguard Worker* *Except for the host platform*, which receives the host backend
355*61c4878aSAndroid Build Coastguard Worker  by default.
356*61c4878aSAndroid Build Coastguard Worker
357*61c4878aSAndroid Build Coastguard WorkerFollowing this pattern implies that we don't need a Bazel equivalent of GN's
358*61c4878aSAndroid Build Coastguard Worker``enable_if = pw_chrono_SYSTEM_CLOCK_BACKEND != ""`` (`example
359*61c4878aSAndroid Build Coastguard Worker<https://cs.opensource.google/pigweed/pigweed/+/main:pw_i2c/BUILD.gn;l=136-145;drc=afef6c3c7de6f5a84465aad469a89556d0b34fbb>`__).
360*61c4878aSAndroid Build Coastguard WorkerIn Bazel, every build target is "enabled" if and only if all facades it
361*61c4878aSAndroid Build Coastguard Workertransitively depends on have a backend set.
362*61c4878aSAndroid Build Coastguard Worker
363*61c4878aSAndroid Build Coastguard WorkerProviding multiplexer targets is an alternative way to set default facade
364*61c4878aSAndroid Build Coastguard Workerbackends, but :ref:`is not recommended in upstream Pigweed
365*61c4878aSAndroid Build Coastguard Worker<docs-bazel-compatibility-multiplexer>`. One exception is if your facade needs
366*61c4878aSAndroid Build Coastguard Workera different default host backend depending on the OS. So, the following
367*61c4878aSAndroid Build Coastguard Workeris OK:
368*61c4878aSAndroid Build Coastguard Worker
369*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
370*61c4878aSAndroid Build Coastguard Worker
371*61c4878aSAndroid Build Coastguard Worker   # Host backend that's OS-specific.
372*61c4878aSAndroid Build Coastguard Worker   alias(
373*61c4878aSAndroid Build Coastguard Worker     name = "host_backend",
374*61c4878aSAndroid Build Coastguard Worker     actual = select({
375*61c4878aSAndroid Build Coastguard Worker       "@platforms//os:macos": ":macos_backend",
376*61c4878aSAndroid Build Coastguard Worker       "@platforms//os:linux": ":linux_backend",
377*61c4878aSAndroid Build Coastguard Worker       "@platforms//os:windows": ":windows_backend",
378*61c4878aSAndroid Build Coastguard Worker       "//conditions:default": "//pw_build:unspecified_backend",
379*61c4878aSAndroid Build Coastguard Worker     }),
380*61c4878aSAndroid Build Coastguard Worker   )
381*61c4878aSAndroid Build Coastguard Worker
382*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-facade-backend-dict:
383*61c4878aSAndroid Build Coastguard Worker
384*61c4878aSAndroid Build Coastguard WorkerProvide default backend collections as dicts
385*61c4878aSAndroid Build Coastguard Worker--------------------------------------------
386*61c4878aSAndroid Build Coastguard WorkerIn cases like RTOS-specific backends, where the user is expected to want to set
387*61c4878aSAndroid Build Coastguard Workerall of them at once, provide a dict of default backends for them to include in
388*61c4878aSAndroid Build Coastguard Workertheir platform definition:
389*61c4878aSAndroid Build Coastguard Worker
390*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
391*61c4878aSAndroid Build Coastguard Worker
392*61c4878aSAndroid Build Coastguard Worker   #//pw_build/backends.bzl (in upstream Pigweed)
393*61c4878aSAndroid Build Coastguard Worker
394*61c4878aSAndroid Build Coastguard Worker   # Dict of typical backends for FreeRTOS.
395*61c4878aSAndroid Build Coastguard Worker   FREERTOS_BACKENDS = {
396*61c4878aSAndroid Build Coastguard Worker     "@pigweed//pw_chrono:system_clock_backend": "@pigweed//pw_chrono_freertos:system_clock",
397*61c4878aSAndroid Build Coastguard Worker     "@pigweed//pw_chrono:system_timer_backend": "@pigweed//pw_chrono_freertos:system_timer",
398*61c4878aSAndroid Build Coastguard Worker     # etc.
399*61c4878aSAndroid Build Coastguard Worker   }
400*61c4878aSAndroid Build Coastguard Worker
401*61c4878aSAndroid Build Coastguard Worker   # User's platform definition (in downstream repo)
402*61c4878aSAndroid Build Coastguard Worker   load("@pigweed//pw_build/backends.bzl", "FREERTOS_BACKENDS", "merge_flags")
403*61c4878aSAndroid Build Coastguard Worker
404*61c4878aSAndroid Build Coastguard Worker   platform(
405*61c4878aSAndroid Build Coastguard Worker     name = "my_freertos_device",
406*61c4878aSAndroid Build Coastguard Worker     flags = merge_flags(
407*61c4878aSAndroid Build Coastguard Worker       base = FREERTOS_BACKENDS,
408*61c4878aSAndroid Build Coastguard Worker       overrides = {
409*61c4878aSAndroid Build Coastguard Worker         # Override one of the default backends.
410*61c4878aSAndroid Build Coastguard Worker         "@pigweed//pw_chrono:system_clock_backend": "//src:my_device:pw_system_clock_backend",
411*61c4878aSAndroid Build Coastguard Worker         # Provide additional backends.
412*61c4878aSAndroid Build Coastguard Worker         "@pigweed//pw_sys_io:backend": "//src:my_device:pw_sys_io_backend",
413*61c4878aSAndroid Build Coastguard Worker       },
414*61c4878aSAndroid Build Coastguard Worker     ),
415*61c4878aSAndroid Build Coastguard Worker   )
416*61c4878aSAndroid Build Coastguard Worker
417*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-facade-backend-interface:
418*61c4878aSAndroid Build Coastguard Worker
419*61c4878aSAndroid Build Coastguard WorkerGuard backend-dependent interfaces with constraints
420*61c4878aSAndroid Build Coastguard Worker---------------------------------------------------
421*61c4878aSAndroid Build Coastguard Worker
422*61c4878aSAndroid Build Coastguard WorkerWhat's a backend-dependent interface?
423*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
424*61c4878aSAndroid Build Coastguard WorkerWe :ref:`officially define a facade <docs-facades>` as "an API contract of a
425*61c4878aSAndroid Build Coastguard Workermodule that must be satisfied at compile-time", and a backend as merely "an
426*61c4878aSAndroid Build Coastguard Workerimplementation of a facade’s contract." However, a small number of facades do
427*61c4878aSAndroid Build Coastguard Workernot fit this definition, and expose APIs that vary based on the backend
428*61c4878aSAndroid Build Coastguard Workerselected (!!!).  Examples:
429*61c4878aSAndroid Build Coastguard Worker
430*61c4878aSAndroid Build Coastguard Worker* ``pw_thread: Thread::join()`` :ref:`may or may not be available
431*61c4878aSAndroid Build Coastguard Worker  <module-pw_thread-detaching-joining>` depending on the selected backend.
432*61c4878aSAndroid Build Coastguard Worker* ``pw_async2``: The ``EPollDispatcher`` offers different APIs from other
433*61c4878aSAndroid Build Coastguard Worker  ``pw_async2::Dispatcher`` backends, and parts of :ref:`module-pw_channel`
434*61c4878aSAndroid Build Coastguard Worker  (:cpp:class:`pw::EpollChannel`) rely on those APIs.
435*61c4878aSAndroid Build Coastguard Worker
436*61c4878aSAndroid Build Coastguard WorkerThis breaks the invariant that a facade's APIs either are available (if it has
437*61c4878aSAndroid Build Coastguard Workera backend) or are not available (if it has no backend, in which case targets
438*61c4878aSAndroid Build Coastguard Workerthat depend on the facade are incompatible). These facades might have a backend
439*61c4878aSAndroid Build Coastguard Workerand yet (parts of) their APIs are unavailable!
440*61c4878aSAndroid Build Coastguard Worker
441*61c4878aSAndroid Build Coastguard WorkerWhat to do instead?
442*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^
443*61c4878aSAndroid Build Coastguard Worker
444*61c4878aSAndroid Build Coastguard WorkerFix the class structrure
445*61c4878aSAndroid Build Coastguard Worker........................
446*61c4878aSAndroid Build Coastguard WorkerIf possible, reorganize the class structure so that the facade's API is
447*61c4878aSAndroid Build Coastguard Workerbackend-independent, and users who need the additional functionality must
448*61c4878aSAndroid Build Coastguard Workerdepend directly on the specific backend that provides this.
449*61c4878aSAndroid Build Coastguard Worker
450*61c4878aSAndroid Build Coastguard WorkerThis is the correct fix for the ``EPollDispatcher`` case; see `b/342000726
451*61c4878aSAndroid Build Coastguard Worker<https://pwbug.dev/342000726>`__ for more details.
452*61c4878aSAndroid Build Coastguard Worker
453*61c4878aSAndroid Build Coastguard WorkerExpress the backend-dependent capability through a constraint
454*61c4878aSAndroid Build Coastguard Worker.............................................................
455*61c4878aSAndroid Build Coastguard WorkerIf the backend-dependent interface cannot be refactored away, guard it using a
456*61c4878aSAndroid Build Coastguard Workercustom constraint.
457*61c4878aSAndroid Build Coastguard Worker
458*61c4878aSAndroid Build Coastguard WorkerLet's discuss :ref:`module-pw_thread` as a specific example. The
459*61c4878aSAndroid Build Coastguard Workerbackend-dependence of the interface is that ``Thread::join()`` may or may not
460*61c4878aSAndroid Build Coastguard Workerbe provided by the backend.
461*61c4878aSAndroid Build Coastguard Worker
462*61c4878aSAndroid Build Coastguard WorkerTo expose this to the build system, introduce a corresponding constraint:
463*61c4878aSAndroid Build Coastguard Worker
464*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
465*61c4878aSAndroid Build Coastguard Worker
466*61c4878aSAndroid Build Coastguard Worker   # //pw_thread/BUILD.bazel
467*61c4878aSAndroid Build Coastguard Worker   constraint_setting(
468*61c4878aSAndroid Build Coastguard Worker     name = "joinable",
469*61c4878aSAndroid Build Coastguard Worker     # Default appropriate for the autodetected host platform.
470*61c4878aSAndroid Build Coastguard Worker     default_constraint_value = ":threads_are_joinable",
471*61c4878aSAndroid Build Coastguard Worker   )
472*61c4878aSAndroid Build Coastguard Worker
473*61c4878aSAndroid Build Coastguard Worker   constraint_value(
474*61c4878aSAndroid Build Coastguard Worker     name = "threads_are_joinable",
475*61c4878aSAndroid Build Coastguard Worker     constraint_setting = ":joinable",
476*61c4878aSAndroid Build Coastguard Worker   )
477*61c4878aSAndroid Build Coastguard Worker
478*61c4878aSAndroid Build Coastguard Worker   constraint_value(
479*61c4878aSAndroid Build Coastguard Worker     name = "threads_are_not_joinable",
480*61c4878aSAndroid Build Coastguard Worker     constraint_setting = ":joinable",
481*61c4878aSAndroid Build Coastguard Worker   )
482*61c4878aSAndroid Build Coastguard Worker
483*61c4878aSAndroid Build Coastguard WorkerPlatforms can declare whether threads are joinable or not by including the
484*61c4878aSAndroid Build Coastguard Workerappropriate constraint value in their definitions:
485*61c4878aSAndroid Build Coastguard Worker
486*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
487*61c4878aSAndroid Build Coastguard Worker
488*61c4878aSAndroid Build Coastguard Worker   # //platforms/BUILD.bazel
489*61c4878aSAndroid Build Coastguard Worker   platform(
490*61c4878aSAndroid Build Coastguard Worker     name = "my_device",
491*61c4878aSAndroid Build Coastguard Worker     constraint_values = [
492*61c4878aSAndroid Build Coastguard Worker       "@pigweed//pw_thread:threads_are_not_joinable",
493*61c4878aSAndroid Build Coastguard Worker     ],
494*61c4878aSAndroid Build Coastguard Worker   )
495*61c4878aSAndroid Build Coastguard Worker
496*61c4878aSAndroid Build Coastguard WorkerBuild targets that unconditionally call ``Thread::join()`` (not within a ``#if
497*61c4878aSAndroid Build Coastguard WorkerPW_THREAD_JOINING_ENABLED=1``) should be marked compatible with the
498*61c4878aSAndroid Build Coastguard Worker``"@pigweed//pw_thread:threads_are_joinable"`` constraint value:
499*61c4878aSAndroid Build Coastguard Worker
500*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
501*61c4878aSAndroid Build Coastguard Worker
502*61c4878aSAndroid Build Coastguard Worker   cc_library(
503*61c4878aSAndroid Build Coastguard Worker     name = "my_library_requiring_thread_joining",
504*61c4878aSAndroid Build Coastguard Worker     # This library will be incompatible with "//platforms:my_device", on
505*61c4878aSAndroid Build Coastguard Worker     # which threads are not joinable.
506*61c4878aSAndroid Build Coastguard Worker     target_compatible_with = ["@pigweed//pw_thread:threads_are_joinable"],
507*61c4878aSAndroid Build Coastguard Worker   )
508*61c4878aSAndroid Build Coastguard Worker
509*61c4878aSAndroid Build Coastguard WorkerIf your library will compile both with and without thread joining (either
510*61c4878aSAndroid Build Coastguard Workerbecause it doesn't call ``Thread::join()``, or because all such calls are
511*61c4878aSAndroid Build Coastguard Workerguarded by ``#if PW_THREAD_JOINING_ENABLED=1``), you don't need any
512*61c4878aSAndroid Build Coastguard Worker``target_compatible_with`` attribute.
513*61c4878aSAndroid Build Coastguard Worker
514*61c4878aSAndroid Build Coastguard WorkerConfiguration-dependent interfaces
515*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
516*61c4878aSAndroid Build Coastguard WorkerSome facades have interfaces that depend not just on the choice of backend, but
517*61c4878aSAndroid Build Coastguard Workeron their :ref:`module-structure-compile-time-configuration`. We don't have a
518*61c4878aSAndroid Build Coastguard Workergood pattern for these libraries yet.
519*61c4878aSAndroid Build Coastguard Worker
520*61c4878aSAndroid Build Coastguard Worker.. note::
521*61c4878aSAndroid Build Coastguard Worker
522*61c4878aSAndroid Build Coastguard Worker   TODO: https://pwbug.dev/234872811 - Establish such a pattern.
523*61c4878aSAndroid Build Coastguard Worker
524*61c4878aSAndroid Build Coastguard WorkerPatterns for SDK build authors
525*61c4878aSAndroid Build Coastguard Worker==============================
526*61c4878aSAndroid Build Coastguard WorkerThis section discusses patterns useful when providing a Bazel build for a
527*61c4878aSAndroid Build Coastguard Workerpre-existing library or SDK.
528*61c4878aSAndroid Build Coastguard Worker
529*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-incompatible-label-flag:
530*61c4878aSAndroid Build Coastguard Worker
531*61c4878aSAndroid Build Coastguard WorkerProvide config headers through label flags
532*61c4878aSAndroid Build Coastguard Worker------------------------------------------
533*61c4878aSAndroid Build Coastguard WorkerMany libraries used in embedded projects expect configuration to be provided
534*61c4878aSAndroid Build Coastguard Workerthrough a header file at a predefined include path. For example, FreeRTOS
535*61c4878aSAndroid Build Coastguard Workerexpects the user to provide a configuration header that will be included via
536*61c4878aSAndroid Build Coastguard Worker``#include "FreeRTOSConfig.h``. How to handle this when writing a *generic*
537*61c4878aSAndroid Build Coastguard Worker``BUILD.bazel`` file for such a library?
538*61c4878aSAndroid Build Coastguard Worker
539*61c4878aSAndroid Build Coastguard WorkerUse the following pattern:
540*61c4878aSAndroid Build Coastguard Worker
541*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
542*61c4878aSAndroid Build Coastguard Worker
543*61c4878aSAndroid Build Coastguard Worker   # //third_party/freertos/freertos.BUILD.bazel
544*61c4878aSAndroid Build Coastguard Worker
545*61c4878aSAndroid Build Coastguard Worker   cc_library(
546*61c4878aSAndroid Build Coastguard Worker     name = "freertos",
547*61c4878aSAndroid Build Coastguard Worker     # srcs, hdrs omitted.
548*61c4878aSAndroid Build Coastguard Worker     deps = [
549*61c4878aSAndroid Build Coastguard Worker       # freertos has a dependency on :freertos_config.
550*61c4878aSAndroid Build Coastguard Worker       ":freertos_config",
551*61c4878aSAndroid Build Coastguard Worker     ],
552*61c4878aSAndroid Build Coastguard Worker   )
553*61c4878aSAndroid Build Coastguard Worker
554*61c4878aSAndroid Build Coastguard Worker   # Label flag that points to the cc_library target providing FreeRTOSConfig.h.
555*61c4878aSAndroid Build Coastguard Worker   label_flag(
556*61c4878aSAndroid Build Coastguard Worker       name = "freertos_config",
557*61c4878aSAndroid Build Coastguard Worker       build_setting_default = ":unspecified",
558*61c4878aSAndroid Build Coastguard Worker   )
559*61c4878aSAndroid Build Coastguard Worker
560*61c4878aSAndroid Build Coastguard Worker   cc_library(
561*61c4878aSAndroid Build Coastguard Worker       name = "unspecified",
562*61c4878aSAndroid Build Coastguard Worker       # The default config is not compatible with any configuration: you can't
563*61c4878aSAndroid Build Coastguard Worker       # build FreeRTOS without choosing a config.
564*61c4878aSAndroid Build Coastguard Worker       target_compatible_with = ["@platforms//:incompatible"],
565*61c4878aSAndroid Build Coastguard Worker   )
566*61c4878aSAndroid Build Coastguard Worker
567*61c4878aSAndroid Build Coastguard WorkerWhy is this recommended?
568*61c4878aSAndroid Build Coastguard Worker
569*61c4878aSAndroid Build Coastguard Worker#. The configuration header to use can be selected as part of platform
570*61c4878aSAndroid Build Coastguard Worker   definition, by setting the label flag. This gives the user a lot of
571*61c4878aSAndroid Build Coastguard Worker   flexibility: they can use different headers when building different targets
572*61c4878aSAndroid Build Coastguard Worker   within the same repo.
573*61c4878aSAndroid Build Coastguard Worker#. Any target (test, library, or binary) that depends on the ``freertos``
574*61c4878aSAndroid Build Coastguard Worker   ``cc_library`` will be considered incompatible with the target platform
575*61c4878aSAndroid Build Coastguard Worker   unless that platform explicitly configured FreeRTOS by setting the
576*61c4878aSAndroid Build Coastguard Worker   ``freertos_config`` label flag. So, if your target's only assumption about
577*61c4878aSAndroid Build Coastguard Worker   the platform is that it supports FreeRTOS, including ``freertos`` in your
578*61c4878aSAndroid Build Coastguard Worker   ``deps`` is all you need to do to express this.
579*61c4878aSAndroid Build Coastguard Worker
580*61c4878aSAndroid Build Coastguard WorkerThis pattern is not useful in upstrem Pigweed itself, because Pigweed uses a
581*61c4878aSAndroid Build Coastguard Workermore elaborate  configuration pattern at the C++ source level. See
582*61c4878aSAndroid Build Coastguard Worker:ref:`module-structure-compile-time-configuration`.
583*61c4878aSAndroid Build Coastguard Worker
584*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-not-recommended:
585*61c4878aSAndroid Build Coastguard Worker
586*61c4878aSAndroid Build Coastguard Worker--------------------------------------
587*61c4878aSAndroid Build Coastguard WorkerAlternative patterns (not recommended)
588*61c4878aSAndroid Build Coastguard Worker--------------------------------------
589*61c4878aSAndroid Build Coastguard Worker
590*61c4878aSAndroid Build Coastguard WorkerThis section describes alternative build compatibility patterns that we've used
591*61c4878aSAndroid Build Coastguard Workeror considered in the past. They are **not recommended**. We'll work to remove
592*61c4878aSAndroid Build Coastguard Workertheir instances from Pigweed, replacing them with the recommended patterns.
593*61c4878aSAndroid Build Coastguard Worker
594*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-per-facade-constraint-settings:
595*61c4878aSAndroid Build Coastguard Worker
596*61c4878aSAndroid Build Coastguard WorkerPer-facade constraint settings (not recommended)
597*61c4878aSAndroid Build Coastguard Worker================================================
598*61c4878aSAndroid Build Coastguard WorkerThis approach was once recommended, although it was `never fully rolled out
599*61c4878aSAndroid Build Coastguard Worker<https://pwbug.dev/272090220>`_:
600*61c4878aSAndroid Build Coastguard Worker
601*61c4878aSAndroid Build Coastguard Worker#. For **every facade**, introduce a ``constraint_setting`` (e.g.,
602*61c4878aSAndroid Build Coastguard Worker   ``@pigweed//pw_foo:backend_constraint_setting``). This would be done by
603*61c4878aSAndroid Build Coastguard Worker   whoever defines the facade; if it's an upstream facade, upstream Pigweed
604*61c4878aSAndroid Build Coastguard Worker   should define this setting.
605*61c4878aSAndroid Build Coastguard Worker#. For every backend, introduce a corresponding constraint_value (e.g.,
606*61c4878aSAndroid Build Coastguard Worker   ``//backends/pw_foo:board1_backend_constraint_value``). This should be done
607*61c4878aSAndroid Build Coastguard Worker   by whoever defines the backend; for backends defined in downstream projects,
608*61c4878aSAndroid Build Coastguard Worker   it's done in that project.
609*61c4878aSAndroid Build Coastguard Worker#. Mark the backend ``target_compatible_with`` its associated ``constraint_value``.
610*61c4878aSAndroid Build Coastguard Worker
611*61c4878aSAndroid Build Coastguard WorkerWhy is this not recommended
612*61c4878aSAndroid Build Coastguard Worker---------------------------
613*61c4878aSAndroid Build Coastguard WorkerThe major difference between this and :ref:`what we're recommending
614*61c4878aSAndroid Build Coastguard Worker<docs-bazel-compatibility-recommended>` is that *every* backend was associated
615*61c4878aSAndroid Build Coastguard Workerwith a *unique* ``constraint_value``, regardless of whether the backend imposed
616*61c4878aSAndroid Build Coastguard Workerany constraints on its platform or not. This implied downstream platforms that
617*61c4878aSAndroid Build Coastguard Workerset N backends would also have to list the corresponding N
618*61c4878aSAndroid Build Coastguard Worker``constraint_values``.
619*61c4878aSAndroid Build Coastguard Worker
620*61c4878aSAndroid Build Coastguard WorkerThe original motivation for per-facade constraint settings is now obsolete.
621*61c4878aSAndroid Build Coastguard WorkerThey were intended to allow backend selection via multiplexers before
622*61c4878aSAndroid Build Coastguard Workerplatform-based flags became available. `More details for the curious
623*61c4878aSAndroid Build Coastguard Worker<https://docs.google.com/document/d/1O4xjnQBDpOxCMhlyzsowfYF3Cjq0fOfWB6hHsmsh-qI/edit?resourcekey=0-0B-fT2s05UYoC4TQIGDyvw&tab=t.0#heading=h.u62b26x3p898>`_.
624*61c4878aSAndroid Build Coastguard Worker
625*61c4878aSAndroid Build Coastguard WorkerWhere they still exist in upstream Pigweed, these constraint settings will be
626*61c4878aSAndroid Build Coastguard Workerremoved (see :ref:`docs-bazel-compatibility-implementation-plan`).
627*61c4878aSAndroid Build Coastguard Worker
628*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-config-setting:
629*61c4878aSAndroid Build Coastguard Worker
630*61c4878aSAndroid Build Coastguard WorkerConfig setting from label flag (not recommended except for tests)
631*61c4878aSAndroid Build Coastguard Worker=================================================================
632*61c4878aSAndroid Build Coastguard Worker`This pattern <https://pwbug.dev/342691352#comment3>`_ was an attempt to keep
633*61c4878aSAndroid Build Coastguard Workerthe central feature of per-facade constraint settings (the selection of a
634*61c4878aSAndroid Build Coastguard Workerparticular backend can be detected) without forcing downstream users to list
635*61c4878aSAndroid Build Coastguard Worker``constraint_values`` explicitly in their platforms. A ``config_setting`` is
636*61c4878aSAndroid Build Coastguard Workerdefined that detects if a backend was selected through the label flag:
637*61c4878aSAndroid Build Coastguard Worker
638*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
639*61c4878aSAndroid Build Coastguard Worker
640*61c4878aSAndroid Build Coastguard Worker   # pw_sys_io_stm32cube/BUILD.bazel
641*61c4878aSAndroid Build Coastguard Worker
642*61c4878aSAndroid Build Coastguard Worker   config_setting(
643*61c4878aSAndroid Build Coastguard Worker       name = "backend_setting",
644*61c4878aSAndroid Build Coastguard Worker       flag_values = {
645*61c4878aSAndroid Build Coastguard Worker           "@pigweed//pw_sys_io:backend": "@pigweed//pw_sys_io_stm32cube",
646*61c4878aSAndroid Build Coastguard Worker       },
647*61c4878aSAndroid Build Coastguard Worker   )
648*61c4878aSAndroid Build Coastguard Worker
649*61c4878aSAndroid Build Coastguard Worker   cc_library(
650*61c4878aSAndroid Build Coastguard Worker     name = "pw_sys_io_stm32cube",
651*61c4878aSAndroid Build Coastguard Worker     target_compatible_with = select({
652*61c4878aSAndroid Build Coastguard Worker       ":backend_setting": [],
653*61c4878aSAndroid Build Coastguard Worker       "//conditions:default": ["@platforms//:incompatible"],
654*61c4878aSAndroid Build Coastguard Worker     }),
655*61c4878aSAndroid Build Coastguard Worker   )
656*61c4878aSAndroid Build Coastguard Worker
657*61c4878aSAndroid Build Coastguard WorkerWhy is this not recommended
658*61c4878aSAndroid Build Coastguard Worker---------------------------
659*61c4878aSAndroid Build Coastguard Worker#. We're really insisting on setting the label flag directly to the backend. In
660*61c4878aSAndroid Build Coastguard Worker   particular, we disallow patterns like "point the ``label_flag`` to an
661*61c4878aSAndroid Build Coastguard Worker   ``alias`` that may resolve to different backends based on a ``select``"
662*61c4878aSAndroid Build Coastguard Worker   (because `the config_setting in the above example will be false in that case
663*61c4878aSAndroid Build Coastguard Worker   <https://github.com/bazelbuild/bazel/issues/21189>`_).
664*61c4878aSAndroid Build Coastguard Worker#. It's a special pattern just for facade backends. Libraries which need to
665*61c4878aSAndroid Build Coastguard Worker   restrict compatibility but are not facade backends cannot use it.
666*61c4878aSAndroid Build Coastguard Worker#. Using the ``config_setting`` in ``target_compatible_with`` requires the
667*61c4878aSAndroid Build Coastguard Worker   weird ``select`` trick shown above. It's not very ergonomic, and definitely
668*61c4878aSAndroid Build Coastguard Worker   surprising.
669*61c4878aSAndroid Build Coastguard Worker
670*61c4878aSAndroid Build Coastguard WorkerWhen to use it anyway
671*61c4878aSAndroid Build Coastguard Worker---------------------
672*61c4878aSAndroid Build Coastguard WorkerWe may resort to defining private ``config_settings`` following this pattern to
673*61c4878aSAndroid Build Coastguard Workersolve special problems like `b/336843458 <https://pwbug.dev/336843458>`_ |
674*61c4878aSAndroid Build Coastguard Worker"Bazel tests using pw_unit_test_light can still rely on GoogleTest" or
675*61c4878aSAndroid Build Coastguard Worker`pw_malloc tests
676*61c4878aSAndroid Build Coastguard Worker<https://cs.opensource.google/pigweed/pigweed/+/main:pw_malloc/BUILD.gn;l=190-191;drc=96313b7cc138b0c49742e151927e0d3a013f8b47>`_.
677*61c4878aSAndroid Build Coastguard Worker
678*61c4878aSAndroid Build Coastguard WorkerIn addition, some tests are backend-specific (directly include backend
679*61c4878aSAndroid Build Coastguard Workerheaders). The most common example are tests that depend on
680*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_thread` but directly ``#include "pw_thread_stl/options.h"``.
681*61c4878aSAndroid Build Coastguard WorkerFor such tests, we will define *private* ``config_settings`` following this
682*61c4878aSAndroid Build Coastguard Workerpattern.
683*61c4878aSAndroid Build Coastguard Worker
684*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-board-chipset:
685*61c4878aSAndroid Build Coastguard Worker
686*61c4878aSAndroid Build Coastguard WorkerBoard and chipset constraint settings (not recommended)
687*61c4878aSAndroid Build Coastguard Worker=======================================================
688*61c4878aSAndroid Build Coastguard WorkerPigweed has historically defined a `"board" constraint_setting
689*61c4878aSAndroid Build Coastguard Worker<https://cs.opensource.google/pigweed/pigweed/+/main:pw_build/constraints/board/BUILD.bazel>`_,
690*61c4878aSAndroid Build Coastguard Workerand this setting was used to indicate that some modules are compatible with
691*61c4878aSAndroid Build Coastguard Workerparticular boards.
692*61c4878aSAndroid Build Coastguard Worker
693*61c4878aSAndroid Build Coastguard WorkerWhy is this not recommended
694*61c4878aSAndroid Build Coastguard Worker---------------------------
695*61c4878aSAndroid Build Coastguard WorkerThis is a particularly bad pattern: hardly any Pigweed build targets are only
696*61c4878aSAndroid Build Coastguard Workercompatible with a single board. Modules which have been marked as
697*61c4878aSAndroid Build Coastguard Worker``target_compatible_with = ["//pw_build/constraints/board:mimxrt595_evk"]`` are
698*61c4878aSAndroid Build Coastguard Workergenerally compatible with many other RT595 boards, and even with other NXP
699*61c4878aSAndroid Build Coastguard Workerchips. We've already run into cases in practice where users want to use a
700*61c4878aSAndroid Build Coastguard Workerparticular backend for a different board.
701*61c4878aSAndroid Build Coastguard Worker
702*61c4878aSAndroid Build Coastguard WorkerThe `"chipset" constraint_setting
703*61c4878aSAndroid Build Coastguard Worker<https://cs.opensource.google/pigweed/pigweed/+/main:pw_build/constraints/chipset/BUILD.bazel>`_
704*61c4878aSAndroid Build Coastguard Workerhas the same problem: the build targets it was applied to don't contain
705*61c4878aSAndroid Build Coastguard Workerassembly code, and so are not generally compatible with only a particular
706*61c4878aSAndroid Build Coastguard Workerchipset. It's also unclear how to define chipset values in a vendor-agnostic
707*61c4878aSAndroid Build Coastguard Workermanner.
708*61c4878aSAndroid Build Coastguard Worker
709*61c4878aSAndroid Build Coastguard WorkerThese constraints will be removed (see :ref:`docs-bazel-compatibility-implementation-plan`).
710*61c4878aSAndroid Build Coastguard Worker
711*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-rtos:
712*61c4878aSAndroid Build Coastguard Worker
713*61c4878aSAndroid Build Coastguard WorkerRTOS constraint setting (not recommended)
714*61c4878aSAndroid Build Coastguard Worker=========================================
715*61c4878aSAndroid Build Coastguard WorkerSome modules include headers provided by an RTOS such as embOS, FreeRTOS or
716*61c4878aSAndroid Build Coastguard WorkerZephyr. If they do not make additional assumptions about the platform beyond
717*61c4878aSAndroid Build Coastguard Workerthe availability of those headers, they could just declare themselves
718*61c4878aSAndroid Build Coastguard Workercompatible with the appropriate value of the ``//pw_build/constraints/rtos:rtos``
719*61c4878aSAndroid Build Coastguard Worker``constraint_setting``. Example:
720*61c4878aSAndroid Build Coastguard Worker
721*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
722*61c4878aSAndroid Build Coastguard Worker
723*61c4878aSAndroid Build Coastguard Worker   # pw_chrono_embos/BUILD.bazel
724*61c4878aSAndroid Build Coastguard Worker
725*61c4878aSAndroid Build Coastguard Worker   cc_library(
726*61c4878aSAndroid Build Coastguard Worker     name = "system_clock",
727*61c4878aSAndroid Build Coastguard Worker     target_compatible_with = ["//pw_build/constraints/rtos:embos"],
728*61c4878aSAndroid Build Coastguard Worker   )
729*61c4878aSAndroid Build Coastguard Worker
730*61c4878aSAndroid Build Coastguard WorkerWhy is this not recommended
731*61c4878aSAndroid Build Coastguard Worker---------------------------
732*61c4878aSAndroid Build Coastguard WorkerAt first glance, this seems like a pretty good pattern: RTOSes kind of like
733*61c4878aSAndroid Build Coastguard WorkerOSes, and OSes :ref:`have their "well-known" constraint
734*61c4878aSAndroid Build Coastguard Worker<docs-bazel-compatibility-well-known-os>`. So why not RTOSes?
735*61c4878aSAndroid Build Coastguard Worker
736*61c4878aSAndroid Build Coastguard WorkerRTOSes are *not* like OSes in an important respect: the dependency on them is
737*61c4878aSAndroid Build Coastguard Workeralready expressed in the build system! A library that uses FreeRTOS headers
738*61c4878aSAndroid Build Coastguard Workerwill have an explicit dependency on the ``@freertos`` target. (This is in
739*61c4878aSAndroid Build Coastguard Workercontrast to OSes: a library that includes Linux system headers will not get
740*61c4878aSAndroid Build Coastguard Workerthem from an explicit dependency.)
741*61c4878aSAndroid Build Coastguard Worker
742*61c4878aSAndroid Build Coastguard WorkerSo, we can push the question of compatibility down to that target: if FreeRTOS
743*61c4878aSAndroid Build Coastguard Workeris compatible with your platform, then a library that depends on it is (in
744*61c4878aSAndroid Build Coastguard Workergeneral) compatible, too. Most (all?) RTOSes require configuration through
745*61c4878aSAndroid Build Coastguard Worker``label_flags`` (in particular, to specify the port), so platform compatibility
746*61c4878aSAndroid Build Coastguard Workercan be elegantly handled by setting the default value of that flag to a target
747*61c4878aSAndroid Build Coastguard Workerthat's ``@platforms//:incompatible``.
748*61c4878aSAndroid Build Coastguard Worker
749*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-multiplexer:
750*61c4878aSAndroid Build Coastguard Worker
751*61c4878aSAndroid Build Coastguard WorkerMultiplexer targets (not recommended)
752*61c4878aSAndroid Build Coastguard Worker=====================================
753*61c4878aSAndroid Build Coastguard WorkerHistorically, Pigweed selected default backends for certain facades based on
754*61c4878aSAndroid Build Coastguard Workerplatform constraint values. For example, this was done by
755*61c4878aSAndroid Build Coastguard Worker``//pw_chrono:system_clock``:
756*61c4878aSAndroid Build Coastguard Worker
757*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
758*61c4878aSAndroid Build Coastguard Worker
759*61c4878aSAndroid Build Coastguard Worker   label_flag(
760*61c4878aSAndroid Build Coastguard Worker       name = "system_clock_backend",
761*61c4878aSAndroid Build Coastguard Worker       build_setting_default = ":system_clock_backend_multiplexer",
762*61c4878aSAndroid Build Coastguard Worker   )
763*61c4878aSAndroid Build Coastguard Worker
764*61c4878aSAndroid Build Coastguard Worker   cc_library(
765*61c4878aSAndroid Build Coastguard Worker       name = "system_clock_backend_multiplexer",
766*61c4878aSAndroid Build Coastguard Worker       visibility = ["@pigweed//targets:__pkg__"],
767*61c4878aSAndroid Build Coastguard Worker       deps = select({
768*61c4878aSAndroid Build Coastguard Worker           "//pw_build/constraints/rtos:embos": ["//pw_chrono_embos:system_clock"],
769*61c4878aSAndroid Build Coastguard Worker           "//pw_build/constraints/rtos:freertos": ["//pw_chrono_freertos:system_clock"],
770*61c4878aSAndroid Build Coastguard Worker           "//pw_build/constraints/rtos:threadx": ["//pw_chrono_threadx:system_clock"],
771*61c4878aSAndroid Build Coastguard Worker           "//conditions:default": ["//pw_chrono_stl:system_clock"],
772*61c4878aSAndroid Build Coastguard Worker       }),
773*61c4878aSAndroid Build Coastguard Worker   )
774*61c4878aSAndroid Build Coastguard Worker
775*61c4878aSAndroid Build Coastguard WorkerWhy is this not recommended
776*61c4878aSAndroid Build Coastguard Worker---------------------------
777*61c4878aSAndroid Build Coastguard WorkerThis pattern made it difficult for the user defining a platform to understand
778*61c4878aSAndroid Build Coastguard Workerwhich backends were being automatically set for them (because this information
779*61c4878aSAndroid Build Coastguard Workerwas hidden in the ``BUILD.bazel`` files for individual modules).
780*61c4878aSAndroid Build Coastguard Worker
781*61c4878aSAndroid Build Coastguard WorkerWhat to do instead
782*61c4878aSAndroid Build Coastguard Worker------------------
783*61c4878aSAndroid Build Coastguard WorkerPlatforms should explicitly set the backends of all facades they use via
784*61c4878aSAndroid Build Coastguard Workerplatform-based flags. For users' convenience, backend authors may :ref:`provide
785*61c4878aSAndroid Build Coastguard Workerdefault backend collections as dicts
786*61c4878aSAndroid Build Coastguard Worker<docs-bazel-compatibility-facade-backend-dict>` for explicit inclusion in the
787*61c4878aSAndroid Build Coastguard Workerplatform definition.
788*61c4878aSAndroid Build Coastguard Worker
789*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-implementation-plan:
790*61c4878aSAndroid Build Coastguard Worker
791*61c4878aSAndroid Build Coastguard Worker-----------------
792*61c4878aSAndroid Build Coastguard WorkerAre we there yet?
793*61c4878aSAndroid Build Coastguard Worker-----------------
794*61c4878aSAndroid Build Coastguard WorkerAs of this writing, upstream Pigweed does not yet follow the best practices
795*61c4878aSAndroid Build Coastguard Workerrecommended below.  `b/344654805 <https://pwbug.dev/344654805>`__ tracks fixing
796*61c4878aSAndroid Build Coastguard Workerthis.
797*61c4878aSAndroid Build Coastguard Worker
798*61c4878aSAndroid Build Coastguard WorkerHere's a high-level roadmap for the recommendations' implementation:
799*61c4878aSAndroid Build Coastguard Worker
800*61c4878aSAndroid Build Coastguard Worker#. Implement the "syntactic sugar" referenced in the rest of this doc:
801*61c4878aSAndroid Build Coastguard Worker   ``boolean_constraint_value``, ``incompatible_with_mcu``, etc.
802*61c4878aSAndroid Build Coastguard Worker
803*61c4878aSAndroid Build Coastguard Worker#. `b/342691352  <https://pwbug.dev/342691352>`_ | "Platforms should set
804*61c4878aSAndroid Build Coastguard Worker   backends for Pigweed facades through label flags". For each facade,
805*61c4878aSAndroid Build Coastguard Worker
806*61c4878aSAndroid Build Coastguard Worker   * Remove the :ref:`multiplexer targets
807*61c4878aSAndroid Build Coastguard Worker     <docs-bazel-compatibility-multiplexer>`.
808*61c4878aSAndroid Build Coastguard Worker   * Remove the :ref:`per-facade constraint settings
809*61c4878aSAndroid Build Coastguard Worker     <docs-bazel-compatibility-per-facade-constraint-settings>`.
810*61c4878aSAndroid Build Coastguard Worker   * Remove any :ref:`default backends
811*61c4878aSAndroid Build Coastguard Worker     <docs-bazel-compatibility-facade-default-backend>`.
812*61c4878aSAndroid Build Coastguard Worker
813*61c4878aSAndroid Build Coastguard Worker#. `b/343487589 <https://pwbug.dev/343487589>`_ | Retire the :ref:`Board and
814*61c4878aSAndroid Build Coastguard Worker   chipset constraint settings <docs-bazel-compatibility-board-chipset>`.
815*61c4878aSAndroid Build Coastguard Worker
816*61c4878aSAndroid Build Coastguard Worker
817*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-background:
818*61c4878aSAndroid Build Coastguard Worker
819*61c4878aSAndroid Build Coastguard Worker--------------------
820*61c4878aSAndroid Build Coastguard WorkerAppendix: Background
821*61c4878aSAndroid Build Coastguard Worker--------------------
822*61c4878aSAndroid Build Coastguard Worker
823*61c4878aSAndroid Build Coastguard Worker.. _docs-bazel-compatibility-why-wildcard:
824*61c4878aSAndroid Build Coastguard Worker
825*61c4878aSAndroid Build Coastguard WorkerWhy wildcard builds?
826*61c4878aSAndroid Build Coastguard Worker====================
827*61c4878aSAndroid Build Coastguard WorkerPigweed is generic microcontroller middleware: you can use Pigweed to
828*61c4878aSAndroid Build Coastguard Workeraccelerate development on any microcontroller platform. In addition, Pigweed
829*61c4878aSAndroid Build Coastguard Workerprovides explicit support for a number of specific hardware platforms, such as
830*61c4878aSAndroid Build Coastguard Workerthe :ref:`target-rp2040` or :ref:`STM32f429i Discovery Board
831*61c4878aSAndroid Build Coastguard Worker<target-stm32f429i-disc1-stm32cube>`. For these specific platforms, every
832*61c4878aSAndroid Build Coastguard WorkerPigweed module falls into one of three buckets:
833*61c4878aSAndroid Build Coastguard Worker
834*61c4878aSAndroid Build Coastguard Worker*  **works** with the platform, or,
835*61c4878aSAndroid Build Coastguard Worker*  **is not intended to work** with the platform, because the platform lacks the
836*61c4878aSAndroid Build Coastguard Worker   relevant capabilities (e.g., the :ref:`module-pw_spi_mcuxpresso` module
837*61c4878aSAndroid Build Coastguard Worker   specifically supports NXP chips, and is not intended to work with the
838*61c4878aSAndroid Build Coastguard Worker   Raspberry Pi Pico).
839*61c4878aSAndroid Build Coastguard Worker*  **should work but doesn't yet**; that's a bug or missing feature in Pigweed.
840*61c4878aSAndroid Build Coastguard Worker
841*61c4878aSAndroid Build Coastguard WorkerBazel's wildcard builds provide a nice way to ensure each Pigweed build target
842*61c4878aSAndroid Build Coastguard Workeris known to fall into one of those three buckets. If you run:
843*61c4878aSAndroid Build Coastguard Worker
844*61c4878aSAndroid Build Coastguard Worker.. code-block:: sh
845*61c4878aSAndroid Build Coastguard Worker
846*61c4878aSAndroid Build Coastguard Worker   bazelisk build --config=rp2040 //...
847*61c4878aSAndroid Build Coastguard Worker
848*61c4878aSAndroid Build Coastguard WorkerBazel will attempt to build all Pigweed build targets for the specified
849*61c4878aSAndroid Build Coastguard Workerplatform, with the exception of targets that are explicitly annotated as not
850*61c4878aSAndroid Build Coastguard Workercompatible with it. Such `incompatible targets will be automatically skipped
851*61c4878aSAndroid Build Coastguard Worker<https://bazel.build/extending/platforms#skipping-incompatible-targets>`_.
852*61c4878aSAndroid Build Coastguard Worker
853*61c4878aSAndroid Build Coastguard WorkerChallenge: designing ``constraint_values``
854*61c4878aSAndroid Build Coastguard Worker==========================================
855*61c4878aSAndroid Build Coastguard WorkerAs noted above, for wildcard builds to work we need to annotate some targets as
856*61c4878aSAndroid Build Coastguard Workernot compatible with certain platforms. This is done through the
857*61c4878aSAndroid Build Coastguard Worker`target_compatible_with attribute
858*61c4878aSAndroid Build Coastguard Worker<https://bazel.build/reference/be/common-definitions#common.target_compatible_with>`_,
859*61c4878aSAndroid Build Coastguard Workerwhich is set to a list of `constraint_values
860*61c4878aSAndroid Build Coastguard Worker<https://bazel.build/reference/be/platforms-and-toolchains#constraint_value>`_
861*61c4878aSAndroid Build Coastguard Worker(essentially, enum values). For example, here's a target only compatible with
862*61c4878aSAndroid Build Coastguard WorkerLinux:
863*61c4878aSAndroid Build Coastguard Worker
864*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
865*61c4878aSAndroid Build Coastguard Worker
866*61c4878aSAndroid Build Coastguard Worker   cc_library(
867*61c4878aSAndroid Build Coastguard Worker     name = "pw_digital_io_linux",
868*61c4878aSAndroid Build Coastguard Worker     target_compatible_with = ["@platforms//os:linux"],
869*61c4878aSAndroid Build Coastguard Worker   )
870*61c4878aSAndroid Build Coastguard Worker
871*61c4878aSAndroid Build Coastguard WorkerIf the platform lists all the ``constraint_values`` that appear in the target's
872*61c4878aSAndroid Build Coastguard Worker``target_compatible_with`` attribute, then the target is compatible; otherwise,
873*61c4878aSAndroid Build Coastguard Workerit's incompatible, and will be skipped.
874*61c4878aSAndroid Build Coastguard Worker
875*61c4878aSAndroid Build Coastguard WorkerIf this sounds a little abstract, that's because it is! Bazel is not very
876*61c4878aSAndroid Build Coastguard Workeropinionated about what the constraint_values actually represent. There are only
877*61c4878aSAndroid Build Coastguard Workertwo sets of canonical ``constraint_values``, ``@platforms//os`` and
878*61c4878aSAndroid Build Coastguard Worker``@platforms//cpu``.  Here are some possible choices---not necessarily good
879*61c4878aSAndroid Build Coastguard Workerones, but all seen in the wild:
880*61c4878aSAndroid Build Coastguard Worker
881*61c4878aSAndroid Build Coastguard Worker*  A set of constraint_values representing RTOSes:
882*61c4878aSAndroid Build Coastguard Worker
883*61c4878aSAndroid Build Coastguard Worker   * ``@pigweed//pw_build/constraints/rtos:embos``
884*61c4878aSAndroid Build Coastguard Worker   * ``@pigweed//pw_build/constraints/rtos:freertos``
885*61c4878aSAndroid Build Coastguard Worker
886*61c4878aSAndroid Build Coastguard Worker*  A set of representing individual boards:
887*61c4878aSAndroid Build Coastguard Worker
888*61c4878aSAndroid Build Coastguard Worker   * ``@pigweed//pw_build/constraints/board:mimxrt595_evk``
889*61c4878aSAndroid Build Coastguard Worker   * ``@pigweed//pw_build/constraints/board:stm32f429i-disc1``
890*61c4878aSAndroid Build Coastguard Worker
891*61c4878aSAndroid Build Coastguard Worker*  A pair of constraint values associated with a single module:
892*61c4878aSAndroid Build Coastguard Worker
893*61c4878aSAndroid Build Coastguard Worker   * ``@pigweed//pw_spi_mcuxpresso:compatible`` (the module is by definition compatible with any platform containing this constraint value)
894*61c4878aSAndroid Build Coastguard Worker   * ``@pigweed//pw_spi_mcuxpresso:incompatible``
895*61c4878aSAndroid Build Coastguard Worker
896*61c4878aSAndroid Build Coastguard WorkerThere are many more possible structures.
897*61c4878aSAndroid Build Coastguard Worker
898*61c4878aSAndroid Build Coastguard WorkerWhat about ``constraint_settings``?
899*61c4878aSAndroid Build Coastguard Worker===================================
900*61c4878aSAndroid Build Coastguard WorkerFinal piece of background: we mentioned above that ``constraint_values`` are a bit
901*61c4878aSAndroid Build Coastguard Workerlike enum values. The enums themselves (groups of ``constraint_values``) are called
902*61c4878aSAndroid Build Coastguard Worker``constraint_settings``.
903*61c4878aSAndroid Build Coastguard Worker
904*61c4878aSAndroid Build Coastguard WorkerEach ``constraint_value`` belongs to a ``constraint_setting``, and a platform
905*61c4878aSAndroid Build Coastguard Workermay specify at most one value from each setting.
906*61c4878aSAndroid Build Coastguard Worker
907*61c4878aSAndroid Build Coastguard WorkerGuiding principles
908*61c4878aSAndroid Build Coastguard Worker==================
909*61c4878aSAndroid Build Coastguard WorkerThese are the principles that guided the selection of the :ref:`recommended
910*61c4878aSAndroid Build Coastguard Workerpatterns <docs-bazel-compatibility-recommended>`:
911*61c4878aSAndroid Build Coastguard Worker
912*61c4878aSAndroid Build Coastguard Worker* **Be consistent.** Make the patterns for different use cases as similar to
913*61c4878aSAndroid Build Coastguard Worker  each other as possible.
914*61c4878aSAndroid Build Coastguard Worker* **Make compatibility granular.** Avoid making assumptions about what sets of
915*61c4878aSAndroid Build Coastguard Worker  backends or HAL modules will be simultaneously compatible with the same
916*61c4878aSAndroid Build Coastguard Worker  platforms.
917*61c4878aSAndroid Build Coastguard Worker* **Minimize the amount of boilerplate** that downstream users need to put up
918*61c4878aSAndroid Build Coastguard Worker  with.
919*61c4878aSAndroid Build Coastguard Worker* **Support the autodetected host platform.** That is, ensure ``bazel build
920*61c4878aSAndroid Build Coastguard Worker  --platforms=@platforms//host //...`` works. This is necessary internally (for
921*61c4878aSAndroid Build Coastguard Worker  google3) and arguably more convenient for downstream users generally.
922