foreign_cc-produced shared library can't be found by dependent binaries at runtime
I can build external libraries using the cmake rule, but when I try to use them as a dependency of a cc_test or cc_binary, on Windows they build but fail at runtime with an error that the shared libraries can't be loaded. Example using ZSTD:
WORKSPACE:
workspace(name = "zstd_build")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# rules for building non-Bazel projects
http_archive(
name = "rules_foreign_cc",
url = "https://github.com/bazelbuild/rules_foreign_cc/archive/refs/tags/0.9.0.tar.gz",
strip_prefix = "rules_foreign_cc-0.9.0",
sha256 = "2a4d07cd64b0719b39a7c12218a3e507672b82a97b98c6a89d38565894cf7c51",
)
load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")
rules_foreign_cc_dependencies()
_ZSTD_ALL_CONTENT = """\
filegroup(
name = "zstd_all",
srcs = glob(["**"]),
visibility = ["//visibility:public"],
)
"""
# libzstd source repository
http_archive(
name = "zstd",
build_file_content = _ZSTD_ALL_CONTENT,
url = "https://github.com/facebook/zstd/releases/download/v1.5.5/zstd-1.5.5.tar.gz",
strip_prefix = "zstd-1.5.5",
sha256 = "9c4396cc829cfae319a6e2615202e82aad41372073482fce286fac78646d3ee4",
)
third_party/zstd/BUILD:
load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake")
cmake(
name = "zstd",
working_directory = "build/cmake",
visibility = ["//visibility:public"],
lib_source = "@zstd//:zstd_all",
install = True,
)
BUILD:
cc_test(
name = "hello_test",
size = "small",
srcs = ["hello_test.cc"],
deps = [
"//third_party/zstd",
],
)
hello_test.cc
#include <zstd.h>
int main() {
size_t cSize = 3;
const char cBuf[] = "foo";
// Read the content size from the frame header should fail with an illegal header format
unsigned long long const rSize = ZSTD_getFrameContentSize(cBuf, cSize);
return !(rSize == ZSTD_CONTENTSIZE_ERROR);
}
bazel build ... succeeds with no errors, and I can see the DLL in bazel-bin/third_party/zstd/zstd/bin/zstd.dll and hello_test executable in bazel-bin/hello_test.exe. Running the .exe results in "error while loading shared libraries: zstd.dll: cannot open shared object file: No such file or directory". If I manually copy it into bazel-bin/, everything works fine.
Is there a step I'm missing that would ensure the shared libraries produced by the cmake rule get placed together with binaries that depend on them?
Platform:
- Windows 10
- MSVC 2019
- Bazel 5.1.0 (Chocolatey)
Pretty sure bazel uses -rpath to find dynamically linked libraries, which doesn't really have good replacements in Windows. If the license allows, you should try to link statically. If that's not possible, you can try to follow some of the suggestions here: https://stackoverflow.com/questions/107888/is-there-a-windows-msvc-equivalent-to-the-rpath-linker-flag
My experience with bazel suggests that bazel is not great with dynamic linking + rules_foreign_cc. For example, even if your target binary has the correct rpaths, they won't be propogated to the dependent libraries.