patchelf
is a binary that the Nix community has developed in order to modify ELF binary files.
This enables workflows that Nix requires, since it’s placing shared objects in unusual places.
Since I haven’t set up github releases / CI yet ont this repo, you have to clone into your source tree / use git_repository
to actually schlep this into your bazel build.
local_repository( # or git_repository
name = "com_github_rules_patchelf",
path = "bazel/rules/rules_patchelf",
)
load("@com_github_rules_patchelf//:patchelf_configure.bzl", "patchelf_configure")
patchelf_configure(
version = "0.18.0",
)
load("@com_github_rules_patchelf//:patchelf_dependencies.bzl", "patchelf_dependencies")
patchelf_dependencies()
register_toolchains(
"@com_github_rules_patchelf//:patchelf_toolchain", # This toolchain is build-host specific
)
The tool is broadly useful outside of the Nix community, and this is a bazel
rule that allows users to interact with it in a bazel-native C/C++ build.
Personally, I use this to rewrite the ELF sections to use $ORIGIN
as a source for some shared objects, allowing the linker to pull dependent shared libraries from the directory of the toplevel shared library. Patchelf neatly solves this with its --set-rpath
flag
Renaming shared libraries causes the linker to fail, but patchelf solves this through its --set-soname
flag
I use both of these features heavily in order to implement JNI native libraries for java rules, and pack the shared objects into a JAR file on the program’s classpath. Extracting these at runtime and loading them with System.loadLibrary
simplifies JVM deployments.
patchelf(
name = "example_set_soname",
objs = [":my_shared_object"], # generated from a bazel rule
command = "--set-soname libexample.so"
)
genrule(
name = "do_so_rename",
srcs = [":example_set_soname"],
outs = ["libexample.so"],
cmd = "cat $< > $@" # bazel's way of addressing the sole input and output of a genrule
)
patchelf(
name = "example_set_rpath",
objs = [":my_shared_object"],
command = "--set-rpath '$ORIGIN' libdepends.so"
)
I haven’t figured out a nice way to make the DEBUG
error around sha256
’s not being included in the http_archive
in patchelf_dependencies
. Suggestions as to how this should work would be good.
This repo also doen’t have a LICENCE yet, soon to be a oss liscence