Skip to content

Commit 5cbc574

Browse files
committed
feat: build host-only doc tools in host config under cross --platforms
The runnable documentation targets (docs, docs_combo, docs_check, docs_link_check, live_preview, live_preview_combo_experimental, ide_support) are host tools that run Python/Sphinx locally. Under a cross `--platforms` (e.g. QNX) they were configured for the target platform and failed Python toolchain resolution, breaking `bazel build //...` in cross-compiling consumers. Wrap each with `platform_transition_binary` from aspect_bazel_lib, which transitions the wrapped binary to a fixed `target_platform` (`@local_config_platform//:host`) and forwards its executable, runfiles and RunEnvironmentInfo, so `bazel run //:docs` keeps working. `sphinx_build` is only consumed as a tool (already built in the exec/host config) and is tagged `manual` so wildcard builds under a cross platform do not try to configure it for the target platform. aspect_bazel_lib is already in the module graph via aspect_rules_py; it is declared as a direct dep so the rule can be loaded.
1 parent 59d1740 commit 5cbc574

2 files changed

Lines changed: 88 additions & 20 deletions

File tree

MODULE.bazel

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ use_repo(pip, "docs_as_code_hub_env")
4747

4848
# Additional Python rules provided by aspect, e.g. an improved version of
4949
bazel_dep(name = "aspect_rules_py", version = "1.4.0")
50+
51+
# `platform_transition_binary` (used to build host-only doc tools in the host
52+
# config under a cross `--platforms`). Already in the graph via aspect_rules_py.
53+
bazel_dep(name = "aspect_bazel_lib", version = "2.16.0")
5054
bazel_dep(name = "buildifier_prebuilt", version = "8.2.0.2")
5155

5256
# PlantUML for docs

docs.bzl

Lines changed: 84 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,21 @@ Easy streamlined way for S-CORE docs-as-code.
4141
#
4242
# For user-facing documentation, refer to `/README.md`.
4343

44+
load("@aspect_bazel_lib//lib:transitions.bzl", "platform_transition_binary")
4445
load("@aspect_rules_py//py:defs.bzl", "py_binary", "py_venv")
4546
load("@docs_as_code_hub_env//:requirements.bzl", "all_requirements")
4647
load("@rules_python//sphinxdocs:sphinx.bzl", "sphinx_build_binary", "sphinx_docs")
4748

49+
# -- Host-platform transition for host-only documentation tooling --------------
50+
#
51+
# The runnable doc targets (docs, ide_support, live_preview, ...) are pure host tools that run
52+
# Python/Sphinx locally. Under a cross `--platforms` (e.g. QNX) they would be configured for the
53+
# target platform and fail Python toolchain resolution. To avoid that, each is wrapped with
54+
# `platform_transition_binary` from aspect_bazel_lib, which transitions the wrapped binary to a fixed
55+
# `target_platform` (the autodetected host, `@local_config_platform//:host`) while forwarding its
56+
# executable, runfiles and RunEnvironmentInfo -- so `bazel build //...` under a cross platform and
57+
# `bazel run //:docs` both keep working.
58+
4859
def _rewrite_needs_json_to_docs_sources(labels):
4960
"""Replace '@repo//:needs_json' -> '@repo//:docs_sources' for every item."""
5061
out = []
@@ -63,8 +74,10 @@ def _rewrite_needs_json_to_sourcelinks(labels):
6374
s = str(x)
6475
if s.endswith("//:needs_json"):
6576
out.append(s.replace("//:needs_json", "//:sourcelinks_json"))
77+
6678
#Items which do not end up with '//:needs_json' shall not be appended to 'out'.
6779
#They are treated separately and are not related to source code linking.
80+
6881
return out
6982

7083
def _merge_sourcelinks(name, sourcelinks, known_good = None):
@@ -100,15 +113,19 @@ def _missing_requirements(deps):
100113
"""Add Python hub dependencies if they are missing."""
101114
found = []
102115
missing = []
116+
103117
def _target_to_packagename(target):
104118
return str(target).split("/")[-1].split(":")[0]
119+
105120
all_packages = [_target_to_packagename(pkg) for pkg in all_requirements]
121+
106122
def _find(pkg):
107123
for dep in deps:
108124
dep_pkg = _target_to_packagename(dep)
109125
if dep_pkg == pkg:
110126
return True
111127
return False
128+
112129
for pkg in all_packages:
113130
if _find(pkg):
114131
found.append(pkg)
@@ -166,6 +183,11 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good =
166183

167184
sphinx_build_binary(
168185
name = "sphinx_build",
186+
# `sphinx_build` is only consumed as a tool (see `needs_json`'s `sphinx` attr below), so Bazel
187+
# already builds it in the exec (host) config -- no host transition needed. It is tagged
188+
# `manual` so a cross-platform `bazel build //...` doesn't configure it for the target platform
189+
# (which would fail Python toolchain resolution).
190+
tags = ["manual"],
169191
visibility = ["//visibility:private"],
170192
data = data + metamodel_data,
171193
deps = deps,
@@ -225,22 +247,34 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good =
225247
docs_env["ACTION"] = "incremental"
226248

227249
py_binary(
228-
name = "docs",
229-
tags = ["cli_help=Build documentation:\nbazel run //:docs"],
250+
name = "docs_impl",
251+
tags = ["manual"],
230252
srcs = [incremental_src],
231253
data = docs_data,
232254
deps = deps,
233-
env = docs_env
255+
env = docs_env,
256+
)
257+
platform_transition_binary(
258+
name = "docs",
259+
binary = ":docs_impl",
260+
target_platform = "@local_config_platform//:host",
261+
tags = ["cli_help=Build documentation:\nbazel run //:docs"],
234262
)
235263

236264
docs_sources_env["ACTION"] = "incremental"
237265
py_binary(
238-
name = "docs_combo",
239-
tags = ["cli_help=Build full documentation with all dependencies:\nbazel run //:docs_combo"],
266+
name = "docs_combo_impl",
267+
tags = ["manual"],
240268
srcs = [incremental_src],
241269
data = combo_data,
242270
deps = deps,
243-
env = docs_sources_env
271+
env = docs_sources_env,
272+
)
273+
platform_transition_binary(
274+
name = "docs_combo",
275+
binary = ":docs_combo_impl",
276+
target_platform = "@local_config_platform//:host",
277+
tags = ["cli_help=Build full documentation with all dependencies:\nbazel run //:docs_combo"],
244278
)
245279

246280
native.alias(
@@ -251,52 +285,82 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good =
251285

252286
docs_env["ACTION"] = "linkcheck"
253287
py_binary(
254-
name = "docs_link_check",
255-
tags = ["cli_help=Verify Links inside Documentation:\nbazel run //:link_check\n (Note: this could take a long time)"],
288+
name = "docs_link_check_impl",
289+
tags = ["manual"],
256290
srcs = [incremental_src],
257291
data = docs_data,
258292
deps = deps,
259-
env = docs_env
293+
env = docs_env,
294+
)
295+
platform_transition_binary(
296+
name = "docs_link_check",
297+
binary = ":docs_link_check_impl",
298+
target_platform = "@local_config_platform//:host",
299+
tags = ["cli_help=Verify Links inside Documentation:\nbazel run //:link_check\n (Note: this could take a long time)"],
260300
)
261301

262302
docs_env["ACTION"] = "check"
263303
py_binary(
264-
name = "docs_check",
265-
tags = ["cli_help=Verify documentation:\nbazel run //:docs_check"],
304+
name = "docs_check_impl",
305+
tags = ["manual"],
266306
srcs = [incremental_src],
267307
data = docs_data,
268308
deps = deps,
269-
env = docs_env
309+
env = docs_env,
310+
)
311+
platform_transition_binary(
312+
name = "docs_check",
313+
binary = ":docs_check_impl",
314+
target_platform = "@local_config_platform//:host",
315+
tags = ["cli_help=Verify documentation:\nbazel run //:docs_check"],
270316
)
271317

272318
docs_env["ACTION"] = "live_preview"
273319
py_binary(
274-
name = "live_preview",
275-
tags = ["cli_help=Live preview documentation in the browser:\nbazel run //:live_preview"],
320+
name = "live_preview_impl",
321+
tags = ["manual"],
276322
srcs = [incremental_src],
277323
data = docs_data,
278324
deps = deps,
279-
env = docs_env
325+
env = docs_env,
326+
)
327+
platform_transition_binary(
328+
name = "live_preview",
329+
binary = ":live_preview_impl",
330+
target_platform = "@local_config_platform//:host",
331+
tags = ["cli_help=Live preview documentation in the browser:\nbazel run //:live_preview"],
280332
)
281333

282334
docs_sources_env["ACTION"] = "live_preview"
283335
py_binary(
284-
name = "live_preview_combo_experimental",
285-
tags = ["cli_help=Live preview full documentation with all dependencies in the browser:\nbazel run //:live_preview_combo_experimental"],
336+
name = "live_preview_combo_experimental_impl",
337+
tags = ["manual"],
286338
srcs = [incremental_src],
287339
data = combo_data,
288340
deps = deps,
289-
env = docs_sources_env
341+
env = docs_sources_env,
342+
)
343+
platform_transition_binary(
344+
name = "live_preview_combo_experimental",
345+
binary = ":live_preview_combo_experimental_impl",
346+
target_platform = "@local_config_platform//:host",
347+
tags = ["cli_help=Live preview full documentation with all dependencies in the browser:\nbazel run //:live_preview_combo_experimental"],
290348
)
291349

292350
py_venv(
293-
name = "ide_support",
294-
tags = ["cli_help=Create virtual environment (.venv_docs) for documentation support:\nbazel run //:ide_support"],
351+
name = "ide_support_impl",
352+
tags = ["manual"],
295353
venv_name = ".venv_docs",
296354
deps = deps,
297355
data = data,
298356
package_collisions = "warning",
299357
)
358+
platform_transition_binary(
359+
name = "ide_support",
360+
binary = ":ide_support_impl",
361+
target_platform = "@local_config_platform//:host",
362+
tags = ["cli_help=Create virtual environment (.venv_docs) for documentation support:\nbazel run //:ide_support"],
363+
)
300364

301365
sphinx_docs(
302366
name = "needs_json",

0 commit comments

Comments
 (0)