[FR][Bug]: Split @rules_nodejs//nodejs:toolchain_type
to appropriately cover all use cases
#3795
Labels
@rules_nodejs//nodejs:toolchain_type
to appropriately cover all use cases
#3795
What is the current behavior?
Currently
@rules_nodejs//nodejs:toolchain_type
is covering 2 separate use cases.When execution and target platforms are the same (as is usually the case) scenarios 1 and 2 can be satisfied by the same toolchain implementation.
However when the execution and target platforms are different, problems arise. For example;
Suppose I am on macOS and building for Linux.
:linux_amd64_toolchain
will be skipped;exec_compatible_with
target_compatible_with
(no constaints):linux_amd64_toolchain_target
can be selected;exec_compatible_with
(no constaints)target_compatible_with
:darwin_arm64_toolchain
can be selected;exec_compatible_with
target_compatible_with
(no constaints)darwin_arm64_toolchain_target
will be skipped;exec_compatible_with
(no constaints)target_compatible_with
That both
:linux_amd64_toolchain_target
and:darwin_arm64_toolchain
represents a contradiction.Describe the feature
Starting off with an example. Rules Java has 3 toolchain types, 2 of which are of interest.
@bazel_tools//tools/jdk:toolchain_type
The compilation toolchain.
This is always run within a rule (think
cfg = "exec"
) and is used to produce platform-neutral output.Implementations use
exec_compatible_with
only.@bazel_tools//tools/jdk:runtime_toolchain_type
The runtime toolchain.
This is used for outputs (e.g. from
java_binary
), which indirectly be used in other rules (as an implementation detail that it not directly executed).Implementations use
target_compatible_with
only.So in Java a rule like
java_binary
would accept both toolchains.@bazel_tools//tools/jdk:toolchain_type
for compilation and@bazel_tools//tools/jdk:runtime_toolchain_type
so the output has a Java runtime to use.This split makes it possible to cross-compile (e.g. build for Linux on macOS).
JS is not a compiled language however the Rules JS toolchains are setup to support such a scenario (a subset at least). The problem, as hinted in "What is the current behavior?", is that such cross-compilation scenarios do not work. Attempts to do so lead to one of 2 outcomes.
:*_toolchain
is resolved.node
from the toolchain runs correctly.node
in the output cannot run on the target platform.:*_toolchain_target
is resolved.node
from the toolchain run cannot run.node
in the output runs correctly on the target platform, provided dependent actions do not depend on the resolvednode
.Implementing a split like what Rules Java has would address this issue, although it still leaves once use case uncovered.
NodeJS has a handful workflows that require the execution and target platforms to be identical.
--build-snapshot
and--build-snapshot-config
)Produces a snapshot blob that can be later loaded with
--snapshot-blob
. Requires NodeJS version, architecture, platform, V8 flags and CPU features match what was used to generate the snapshot.--experimental-sea-config
)This is a multi-step workflow, of which
--experimental-sea-config
incurs the same requirements as "snapshot generation" whenuseSnapshot
oruseCodeCache
are enabled.So, here is my proposal.
@rules_nodejs//nodejs:runtime_toolchain_type
with the same usage semantics as@bazel_tools//tools/jdk:runtime_toolchain_type
. Add implementations for this new type tonodejs_toolchains
generated external repository.:*_toolchain_target
toolchain implementations, bringing usage semantics in line with@bazel_tools//tools/jdk:toolchain_type
(ignoring that JS doesn't need to be compiled).nodejs_toolchains
generated external repository.It may make sense to tweak the plan outlined according to what the bulk of current
@rules_nodejs//nodejs:toolchain_type
usage is for (I suspect right now executable outputs are the primary use case).How existing toolchain types are supposed to be used isn't always obvious at a glance, same goes for those in Rules Java and especially the generic
toolchain_type
name. May be worthwhile workshopping the names.Related
The text was updated successfully, but these errors were encountered: