Is there a rule representing an ECMAScript library in Bazel rules_nodejs? - bazel

Most of my code is represented by ECMA Script libraries that have import and export rather than require statements.
Is there a suggested way to represent such libraries using rules_dotnet?
I am looking for something like this:
load("#build_bazel_rules_nodejs//:index.bzl", "ecmascript_library")
ecmascript_library(
name = "foo",
srcs = [
"foo.js"
],
)
ecmascript_library(
name = "bar",
srcs = [
"bar.js"
],
deps = [
":foo",
],
)
Where Bazel will ensure the search paths for rules consuming bar can find foo.
I would then like to use my library definitions to create bundles for Node.js etc.
How can I accomplish this?

Related

Using a custom Java toolchain in shell binary target

I am having a simple shell script that executes a prebuilt binary. The build file looks like this:
filegroup(
name = "generator_srcs",
srcs = glob([
"configuration/**",
"features/**",
"plugins/**"
]) + [
"commonapi-generator-linux-x86_64.ini",
"artifacts.xml"
],
)
filegroup(
name = "generator_binary",
srcs = ["commonapi-generator-linux-x86_64"],
data = [":generator_srcs"],
)
sh_binary(
name = "generator",
srcs = ["#//tools:generator.sh"],
data = [":generator_binary"],
toolchains = ["#//toolchain:jre_toolchain_definition"],
args = ["$(location :generator_binary)", "$(JAVA)"],
)
However the prebuilt binary depends on a specific Java Runtime Environment. Therefore I simply defined a custom java_runtime that fits the requirements of the binary. The corresponding build file looks like this:
java_runtime(
name = "jre8u181-b13",
srcs = glob([
"jre/**"
]),
java_home = "jre",
licenses = [],
visibility = [
"//visibility:public"
]
)
config_setting(
name = "jre_version_setting",
values = {"java_runtime_version": "1.8"},
visibility = ["//visibility:private"],
)
toolchain(
name = "jre_toolchain_definition",
target_settings = [":jre_version_setting"],
toolchain_type = "#bazel_tools//tools/jdk:runtime_toolchain_type",
toolchain = ":jre8u181-b13",
visibility = ["//visibility:public"],
)
When I am trying to build and run the target generator bazel throws the error:
//toolchain:jre_toolchain_definition does not have mandatory providers: 'TemplateVariableInfo'
This is the point where I am a little bit lost. As stated in this post the rule should provide toolchain specific make variables. Therefore I was looking around in the bazel github repository and found the rule java_runtime_alias which seems to provide some useful variables that I could use in my sh_binary target. But in this rule automatic toolchain resolution happens. I would like to rewrite the rule such that I can hand over my custom toolchain target as an argument but I don't know how. Should I define an attribute?

Apply cpu transition to cc_binary rule in Bazel

I've a c target that always must be compiled for darwin_x86_64, no matter the --cpu set when calling bazel build. It's the only target that always must be compiled for a specific cpu in a big project.
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
In the bazel documentation it seems to be possible to do this using transitions. Maybe something like:
def _force_x86_64_impl(settings, attr):
return {"//command_line_option:cpu": "darwin_x86_64"}
force_x86_64 = transition(
implementation = _force_x86_64_impl,
inputs = [],
outputs = ["//command_line_option:cpu"]
)
But how do I tie these two together? I'm probably missing something obvious, but I can't seem to find the relevant documentation over at bazel.build.
You've got the transition defined, now you need to attach it to a rule.
r = rule(
implementation = _r_impl,
attrs = {
"_allowlist_function_transition": attr.label(
default = "#bazel_tools//tools/allowlists/function_transition_allowlist",
),
"srcs": attr.label(cfg = force_x86_64),
},
)
def _r_impl(ctx):
return [DefaultInfo(files = ctx.attr.srcs[0][DefaultInfo].files)]
This defines a rule that attaches the appropriate transition to the srcs you pass it, and then simply forwards the list of files from DefaultInfo. Depending on what you're doing, this might be sufficient, or you might also want to forward the runfiles contained in DefaultInfo and/or other providers.
Use target_compatible_with
Example (only compiled on Windows):
cc_library(
name = "win_driver_lib",
srcs = ["win_driver_lib.cc"],
target_compatible_with = [
"#platforms//cpu:x86_64",
"#platforms//os:windows",
],
)

How to reference the source directory of a `bazel` BUILD file?

I have something like the following:
sh_binary(
…
args = [
"path/to/this/build/file/relative/to/workspace/root",
],
…
)
Is there a way to compute/generate "path/to/this/build/file/relative/to/workspace/root" so that if the BUILD file is moved, args wouldn't have to be changed? Something similar to $(location) (I haven't gotten $(location) to work since it would introduce a circular dependency)?
Adding the BUILD file as a data dependency allows you to get its $(location):
sh_binary(
…
args = ["$(location BUILD.bazel)"],
data = ["BUILD.bazel"],
…
)

How can I define an owner to an empty_dir using container_image or container_layer from bazel rules_docker?

From the PR that implemented empty_dirs, it seems there's support for defining dir owners (with the names argument) and mode into the add_empty_dir method of TarFile class.
But the container_image rule (and container_layer) supports only mode.
This works:
container_image(
name = "with_empty_dirs",
empty_dirs = [
"etc",
"foo",
"bar",
],
mode = "0o777",
)
But this returns an error: "ERROR: (...) no such attribute 'names' in 'container_image_' rule":
container_image(
name = "with_empty_dirs",
empty_dirs = [
"etc",
"foo",
"bar",
],
names = "nginx",
)
Do we need to “write a customized container_image” if we want to add support for owner of empty_dirs?
In a BUILD file, the attribute you're looking for is ownername. See the pkg_tar reference documentation documentation for more details. Also, I don't think you can pass it directly to container_image, you have to create a separate pkg_tar first. Like this:
pkg_tar(
name = "with_empty_dirs_tar",
empty_dirs = [
"etc",
"foo",
"bar",
],
ownername = "nginx.nginx",
)
container_image(
name = "with_empty_dirs",
tars = [":with_empty_dirs_tar"],
)
In general, container_image has a subset of pkg_tar as direct attributes to make simple forms of adding files, but for complex use cases you should create a pkg_tar yourself for full access to all of its features for adding/arranging files and setting their ownership.
The names you see in that PR is a variable in a Python helper tool which the BUILD file rules use as part of the implementation. There's a layer of abstraction between what you write in a BUILD file and that Python code.

Is there a splat operator in Starlark / Bazel?

Is there a splat operator in Bazel? Like pythons *, or Javacripts ...?
I'm interested in the case where I need to unpack a list into another. What I would like to achieve is something like this:
some_rule (
name = "target_name",
src = [
"file1.txt",
"file2.txt",
*get_more_files()
]
)
In this example get_more_files would return a list of file names, which would be unpacked into src and sit alongside file1.txt and file2.txt.
Note: I am aware of the extend method.
srcs = [ .. ] + get_more_files()
should do the job

Resources