The Perl Toolchain utilizes the portable-perl project.
To import rules_perl in your project, you first need to add it to your WORKSPACE file:
If you are still using WORKSPACE to manage your dependencies:
git_repository(
name = "rules_perl",
remote = "https://github.com/bazelbuild/rules_perl.git",
branch = "main",
)
load("@rules_perl//perl:deps.bzl", "perl_register_toolchains", "perl_rules_dependencies")
perl_rules_dependencies()
perl_register_toolchains()
Once you've imported the rule set into your WORKSPACE, you can then load the perl rules in your BUILD files with:
load("@rules_perl//perl:perl.bzl", "perl_binary")
perl_binary(
name = "hello_world",
srcs = ["hello_world.pl"]
)
Please see example folder for more examples of how to include Perl scripts.
The toolchains are upstream Perl, built from source with ithreads, that runs from wherever Bazel unpacks it:
| OS | CPUs | Builds |
|---|---|---|
| Linux | x86_64, aarch64 | musl-static (default), gnu (glibc ≥ 2.17), musl |
| macOS | x86_64, aarch64 | one |
| Windows | x86_64, aarch64 | msvc (default), gnu (mingw-w64 on the UCRT; x86_64 only) |
--@rules_perl//perl/settings:distribution picks the vendor: perl (default)
or strawberry, Strawberry Perl on Windows x86_64.
--@rules_perl//perl/settings:xs says whether the build needs a perl that can
load XS modules, and on Linux picks the build. Off, the default, resolves
musl-static, which is statically linked and so runs on any Linux whatever its
C library (NixOS included, where the gnu build's loader is not at /lib64),
but cannot load XS. A build with perl_xs turns it on in .bazelrc, which
resolves the gnu build:
common --@rules_perl//perl/settings:xs=true
The static build has one more limit: it cannot read its own path, so when it
is invoked by a relative path, as Bazel actions do, and the script then changes
directory, @INC no longer resolves and lazily loaded modules are not found.
perl_binary is unaffected, its launcher re-executes with an absolute path; a
rule that runs the toolchain's interpreter directly should make @INC absolute
first, as perl/private/xsubpp.pl does.
A target that needs XS can mark itself incompatible with the flag off, so that a wildcard build that leaves it off skips it, and everything depending on it:
target_compatible_with = select({
"@rules_perl//perl/settings:xs_disabled": ["@platforms//:incompatible"],
"//conditions:default": [],
}),
The musl build needs the host's musl loader, so until platform constraints
for the C library exist (platforms_contrib
is not yet released) toolchain resolution does not reach it, nor the Windows
gnu build. A root module can register one ahead of rules_perl's:
register_toolchains("@rules_perl//perl:perl_x86_64_linux_musl_toolchain")
The binaries are GitHub releases of bazel-contrib/portable-perl.
Pure-Perl modules and, with perl_xs, XS modules both build on macOS.
perl_xs compiles with the resolved C toolchain, MSVC (Bazel's default) or
MinGW gcc, and links against the import library of whichever Windows perl is
selected. See the perl_xs documentation.
Perl modules from CPAN can be generated using the cpan_compiler rule in
conjunction with the cpan module extension.
cpanfile.snapshotOn a Bazel whose module extensions have facts, the extension reads Carton's
cpanfile.snapshot directly:
cpan = use_extension("@rules_perl//perl/cpan:extensions.bzl", "cpan")
cpan.install(
name = "cpan",
lock = "//:cpanfile.snapshot",
)
use_repo(cpan, "cpan")
The snapshot names every archive but has no hashes of them, so the first
evaluation fetches each archive once for its hash and remembers it in
MODULE.bazel.lock as a fact; later evaluations, and builds from the
repository cache, need nothing more. Check the lockfile in. A module whose
consumers must not fetch anything unpinned, one published to a registry for
instance, should ship the JSON lock below instead, and a Bazel without facts
can only read that.
cpanfile per the Carton documentation.*.json will need to be created for Bazel to use a lockfile (e.g. cpanfile.snapshot.lock.json)cpan_compiler target:load("//perl/cpan:cpan_compiler.bzl", "cpan_compiler")
cpan_compiler(
name = "compiler",
cpanfile = "cpanfile",
lockfile = "cpanfile.snapshot.lock.json",
visibility = ["//visibility:public"],
)
bazel run the new target.MODULE.bazel pointing to the Bazel *.json lock file:cpan = use_extension("@rules_perl//perl/cpan:extensions.bzl", "cpan")
cpan.install(
name = "cpan",
lock = "//perl/cpan/3rdparty:cpanfile.snapshot.lock.json",
)
use_repo(
cpan,
"cpan",
)
Once the cpan module extension is defined, dependencies will be available through the name given to the module.
Using the example in the steps above, each distribution is a package of @cpan (e.g. @cpan//DateTime), and a
binary from bins a target in it (bins = {"App-cloc": ["bin/cloc"]} gives @cpan//App-cloc:bin_cloc).
@cpan//:DateTime and @cpan//:App-cloc_bin_cloc, the previous spellings, still resolve but are deprecated.
Each distinct archive is downloaded once and shared by every hub that pins it, across modules; a hub only decides which dependencies each distribution sees.
Note that xs dependencies are currently not supported by the cpan extension module.
Downloaded and unpacked: Test::Mock::Simple
This modules was chosen because it has no dependencies and is pure Perl.
Moved the required file to examples/cpan/Test-Mock-Simple-0.10/lib
NOTE: this location has been chosen so you can compare what is in the tar vs what as actually needed. This is a bad location! It would be better to be in cpan/lib.
Create a target for the module in your BUILD file (which resides in the cpan directory):
perl_library(
name = "TestMockSimple",
srcs = ["Test-Mock-Simple-0.10/lib/Test/Mock/Simple.pm"],
)
Now you can specify it as a dependency to any script that requires that module:
env = {
"PERL5LIB": "examples/cpan/Test-Mock-Simple-0.10/lib",
},
deps = ["//examples/cpan:TestMockSimple"],
NOTE: at this time you need to provide the directory that Perl needs to add to @INC.
perl_binary (and perl_test) sets up the PERL5LIB environment variable with values for all perl_library dep's includes.
The default includes are [".", "lib"].
1.1.2.rcr.0100% 42026-11-02 |