Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make node toolchain_type public so new toolchains can be added #2591

Merged
merged 1 commit into from
Apr 7, 2021

Conversation

dae
Copy link
Contributor

@dae dae commented Apr 7, 2021

Enables rules_nodejs to be used in cross-compilation contexts, where
the target architecture is not supported by rules_nodejs.

rules_nodejs's default toolchains are limited via target_compatible_with,
which means they will not work when cross-compiling to Android or iOS
with --platforms for example. With this change, users can define their
own toolchain that is limited by execution platform instead of target
platform.

For example, if you're targeting an unsupported platform, but building
on a Mac, you can place the following in the local WORKSPACE:

register_toolchains("//ts/node_toolchain")

And the following in ts/node_toolchain/BUILD.bazel:

toolchain(
    name = "node_toolchain",
    exec_compatible_with = [
        "@platforms//os:osx",
        "@platforms//cpu:x86_64",
    ],
    toolchain = "@nodejs_darwin_amd64_config//:toolchain",
    toolchain_type = "@build_bazel_rules_nodejs//toolchains/node:toolchain_type",
)

Closes #2565

PR Checklist

Please check if your PR fulfills the following requirements:

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature (please, look at the "Scope of the project" section in the README.md file)
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Enables rules_nodejs to be used in cross-compilation contexts, where
the target architecture is not supported by rules_nodejs.

rules_nodejs's default toolchains are limited via target_compatible_with,
which means they will not work when cross-compiling to Android or iOS
with --platforms for example. With this change, users can define their
own toolchain that is limited by execution platform instead of target
platform.

For example, if you're targeting an unsupported platform, but building
on a Mac, you can place the following in the local WORKSPACE:

    register_toolchains("//ts/node_toolchain")

And the following in ts/node_toolchain/BUILD.bazel:

    toolchain(
        name = "node_toolchain",
        exec_compatible_with = [
            "@platforms//os:osx",
            "@platforms//cpu:x86_64",
        ],
        toolchain = "@nodejs_darwin_amd64_config//:toolchain",
        toolchain_type = "@build_bazel_rules_nodejs//toolchains/node:toolchain_type",
    )

Closes bazel-contrib#2565
@google-cla google-cla bot added the cla: yes label Apr 7, 2021
dae added a commit to ankitects/rules_nodejs that referenced this pull request Apr 7, 2021
This currently works when testing packages/esbuild/test, but not when
used via a built package, and I wanted to get an idea of if this is
a desired change before proceeding further.

The current recommended way to pass the esbuild binary to the rule
is to use a select() statement, but that makes a decision based on
the target architecture, not the host architecture, and causes builds
to fail when a target platform has been set with --platforms that is
not one of Mac/Windows/Linux (related: bazel-contrib#2591)

By switching to a toolchain, we can specify that each platform's binary
requires a given host platform, so if building on a Mac for example,
it will invoke the esbuild Mac binary even if a build is targeting
another architecture, eg building a native Android/iOS library that
needs to bundle esbuild output products.

I made some other changes in this PR for discussion - they are not
required for toolchain support, but IMHO would be nice to have:

- Bundle esbuild_repo.bzl, so users can get easy access to the same
esbuild version that the tests are run against. Currently, if you update
rules_nodejs after a change like the move to esbuild 0.11, your build
will break until you update the local esbuild binaries in your repo
to match. The change also makes esbuild behave more like the core
nodejs toolchain, which includes some default binary URLs.
- Change the script that generates esbuild_repo.bzl to use maybe(),
so that users can override the default URLs if they wish. This is not
strictly necessary, as the user could define and register their own
toolchains instead, but it just makes it a bit easier to override the
default values.

If there is interest in the toolchain change (and possibly the repo change),
I'd appreciate some advice on how to proceed. A toolchains= argument to
a rule seems to require an absolute label, so I can't use ":toolchain_type" -
it needs to be "//packages/esbuild:toolchain_type" in local development, and
something like "@npm//@bazel/esbuild:toolchain_type" when installed via
npm.

The package.json in examples/esbuild appears to reference npm packages
directly, so presumably the examples can't be updated until a new release
is made. Is there some trick I can use to replace the npm reference
with the files in dist/bin/packages/esbuild/npm_package? I tried updating
the package.json file to reference
"file:../../dist/bin/packages/esbuild/npm_package", but the build fails,
and I'm not sure if that's because it's creating a symlink in the file:
case. Is there a recommended way I can test out the changes without having
to upload packages to npm?

Is this something there'd be interest in including?
Copy link
Collaborator

@alexeagle alexeagle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! We'll need to add some docs too, your PR description here is nice but not very discoverable later.

@alexeagle alexeagle merged commit b606b79 into bazel-contrib:stable Apr 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants