From eea765c36af54181a4c5e82663a43c08dba73c2e Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Tue, 23 Jul 2024 21:39:55 +0200 Subject: [PATCH] Test cc_binary dynamic_deps runfiles --- examples/.bazelrc | 3 + examples/dynamic_deps/BUILD.bazel | 33 +++++++++++ examples/dynamic_deps/bin.cpp | 6 ++ examples/dynamic_deps/bin_test.sh | 25 +++++++++ examples/dynamic_deps/cc_define_binary.bzl | 5 ++ examples/dynamic_deps/lib/BUILD.bazel | 14 +++++ examples/dynamic_deps/lib/lib.cpp | 7 +++ examples/dynamic_deps/lib/lib.h | 3 + examples/dynamic_deps/rules/BUILD.bazel | 0 examples/dynamic_deps/rules/runfiles_dir.bzl | 59 ++++++++++++++++++++ 10 files changed, 155 insertions(+) create mode 100644 examples/dynamic_deps/BUILD.bazel create mode 100644 examples/dynamic_deps/bin.cpp create mode 100755 examples/dynamic_deps/bin_test.sh create mode 100644 examples/dynamic_deps/cc_define_binary.bzl create mode 100644 examples/dynamic_deps/lib/BUILD.bazel create mode 100644 examples/dynamic_deps/lib/lib.cpp create mode 100644 examples/dynamic_deps/lib/lib.h create mode 100644 examples/dynamic_deps/rules/BUILD.bazel create mode 100644 examples/dynamic_deps/rules/runfiles_dir.bzl diff --git a/examples/.bazelrc b/examples/.bazelrc index 0610445..c6932fe 100644 --- a/examples/.bazelrc +++ b/examples/.bazelrc @@ -6,6 +6,9 @@ startup --nowindows_enable_symlinks # top-level configuration. common --experimental_output_directory_naming_scheme=diff_against_dynamic_baseline +# Required with Bazel 6 +common --experimental_cc_shared_library + # Prevent Java compiler warnings such as: # [0.002s][warning][perf,memops] Cannot use file /tmp/hsperfdata_runner/2 because it is locked by another process (errno = 11) common --incompatible_sandbox_hermetic_tmp diff --git a/examples/dynamic_deps/BUILD.bazel b/examples/dynamic_deps/BUILD.bazel new file mode 100644 index 0000000..7132c22 --- /dev/null +++ b/examples/dynamic_deps/BUILD.bazel @@ -0,0 +1,33 @@ +load("//dynamic_deps/rules:runfiles_dir.bzl", "runfiles_dir") +load(":cc_define_binary.bzl", "cc_define_binary") + +cc_define_binary( + name = "bin", + srcs = ["bin.cpp"], + dynamic_deps = ["//dynamic_deps/lib:shared"], + deps = ["//dynamic_deps/lib"], +) + +runfiles_dir( + name = "bin_runfiles", + executable = ":bin", +) + +sh_test( + name = "bin_test_runfiles", + srcs = ["bin_test.sh"], + args = ["$(rlocationpath :bin)"], + data = [":bin"], + deps = ["@bazel_tools//tools/bash/runfiles"], +) + +sh_test( + name = "bin_test_direct", + srcs = ["bin_test.sh"], + args = select({ + "@platforms//os:windows": ["$(rlocationpath :bin_runfiles)/bin.exe"], + "//conditions:default": ["$(rlocationpath :bin_runfiles)/bin"], + }), + data = [":bin_runfiles"], + deps = ["@bazel_tools//tools/bash/runfiles"], +) diff --git a/examples/dynamic_deps/bin.cpp b/examples/dynamic_deps/bin.cpp new file mode 100644 index 0000000..186532a --- /dev/null +++ b/examples/dynamic_deps/bin.cpp @@ -0,0 +1,6 @@ +#include "dynamic_deps/lib/lib.h" + +int main() { + PrintGreeting(); + return 0; +} \ No newline at end of file diff --git a/examples/dynamic_deps/bin_test.sh b/examples/dynamic_deps/bin_test.sh new file mode 100755 index 0000000..5f1296f --- /dev/null +++ b/examples/dynamic_deps/bin_test.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# --- begin runfiles.bash initialization v3 --- +# Copy-pasted from the Bazel Bash runfiles library v3. +set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash +# shellcheck disable=SC1090 +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v3 --- + +bin_path=$(rlocation "$1" || { >&2 echo "$1 not found"; exit 1; }) +output=$(env \ + -u RUNFILES_DIR \ + -u RUNFILES_MANIFEST \ + -u RUNFILES_MANIFEST_ONLY \ + -u JAVA_RUNFILES \ + "$bin_path" || { >&2 echo "Failed to run $bin_path"; exit 1; }) +if [[ "$output" != "Hello,_world!" ]]; then + echo "Unexpected output: $output" + exit 1 +fi \ No newline at end of file diff --git a/examples/dynamic_deps/cc_define_binary.bzl b/examples/dynamic_deps/cc_define_binary.bzl new file mode 100644 index 0000000..2be759b --- /dev/null +++ b/examples/dynamic_deps/cc_define_binary.bzl @@ -0,0 +1,5 @@ +load("@with_cfg.bzl", "with_cfg") + +_builder = with_cfg(native.cc_binary) +_builder.extend("copt", ["-DGREETING=\"Hello,_world!\""]) +cc_define_binary, _cc_define_binary = _builder.build() diff --git a/examples/dynamic_deps/lib/BUILD.bazel b/examples/dynamic_deps/lib/BUILD.bazel new file mode 100644 index 0000000..ab4151d --- /dev/null +++ b/examples/dynamic_deps/lib/BUILD.bazel @@ -0,0 +1,14 @@ +cc_library( + name = "lib", + srcs = ["lib.cpp"], + hdrs = ["lib.h"], + visibility = ["//dynamic_deps:__pkg__"], + tags = ["manual"], +) + +cc_shared_library( + name = "shared", + deps = [":lib"], + visibility = ["//dynamic_deps:__pkg__"], + tags = ["manual"], +) diff --git a/examples/dynamic_deps/lib/lib.cpp b/examples/dynamic_deps/lib/lib.cpp new file mode 100644 index 0000000..411ec6f --- /dev/null +++ b/examples/dynamic_deps/lib/lib.cpp @@ -0,0 +1,7 @@ +#include "lib.h" + +#include + +void PrintGreeting() { + std::cout << GREETING << std::endl; +} \ No newline at end of file diff --git a/examples/dynamic_deps/lib/lib.h b/examples/dynamic_deps/lib/lib.h new file mode 100644 index 0000000..2d26b57 --- /dev/null +++ b/examples/dynamic_deps/lib/lib.h @@ -0,0 +1,3 @@ +#pragma once + +void PrintGreeting(); diff --git a/examples/dynamic_deps/rules/BUILD.bazel b/examples/dynamic_deps/rules/BUILD.bazel new file mode 100644 index 0000000..e69de29 diff --git a/examples/dynamic_deps/rules/runfiles_dir.bzl b/examples/dynamic_deps/rules/runfiles_dir.bzl new file mode 100644 index 0000000..a3b0460 --- /dev/null +++ b/examples/dynamic_deps/rules/runfiles_dir.bzl @@ -0,0 +1,59 @@ +def _runfiles_dir_impl(ctx): + # type: (ctx) -> list + out_dir = ctx.actions.declare_directory(ctx.label.name) + default_info = ctx.attr.executable[DefaultInfo] + executable = default_info.files_to_run.executable + name = executable.basename + + args = ctx.actions.args() + args.add(out_dir.path) + + direct_inputs = [default_info.files_to_run.repo_mapping_manifest] + transitive_inputs = [default_info.default_runfiles.files] + inputs = depset(direct_inputs, transitive = transitive_inputs) + + ctx.actions.run_shell( + inputs = inputs, + outputs = [out_dir], + command = """ +mkdir -p {out_dir}/{name}.runfiles +cp {executable} {out_dir}/{name} +cp {repo_mapping} {out_dir}/{name}.repo_mapping +""".format( + name = name, + out_dir = out_dir.path, + executable = executable.path, + repo_mapping = default_info.files_to_run.repo_mapping_manifest.path, + ) + "\n".join([ + """ +mkdir -p $(dirname {out_dir}/{name}.runfiles/{rlocationpath}) +cp {path} {out_dir}/{name}.runfiles/{rlocationpath} +""".format( + name = name, + out_dir = out_dir.path, + path = f.path, + rlocationpath = _rlocationpath(ctx, f), + ) + for f in default_info.default_runfiles.files.to_list() + ]), + ) + + return [ + DefaultInfo(files = depset([out_dir])), + ] + +def _rlocationpath(ctx, f): + if f.short_path.startswith("../"): + return f.short_path[3:] + else: + return ctx.workspace_name + "/" + f.short_path + +runfiles_dir = rule( + implementation = _runfiles_dir_impl, + attrs = { + "executable": attr.label( + cfg = "target", + executable = True, + ), + }, +)