diff --git a/cc/toolchains/directory_tool.bzl b/cc/toolchains/directory_tool.bzl new file mode 100644 index 0000000..b4572e7 --- /dev/null +++ b/cc/toolchains/directory_tool.bzl @@ -0,0 +1,49 @@ +# Copyright 2024 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Macro to extract tools from a directory.""" + +load("@bazel_skylib//rules/directory:glob.bzl", "directory_glob") +load(":tool.bzl", "cc_tool") + +def cc_directory_tool(name, directory, executable, data = [], exclude = [], allow_empty = False, **kwargs): + """A tool extracted from a directory. + + Args: + name: (str) The name of the generated target + directory: (Label) The directory to extract from + executable: (str) The relative path from the directory to the + executable. + data: (List[str]) A list of globs to runfiles for the executable, + relative to the directory. + exclude: (List[str]) A list of globs to exclude from data. + allow_empty: (bool) If false, any glob that fails to match anything will + result in a failure. + **kwargs: Kwargs to be passed through to cc_tool. + """ + files_name = "_%s_files" % name + directory_glob( + name = files_name, + directory = directory, + srcs = [executable], + data = data, + exclude = exclude, + allow_empty = allow_empty, + visibility = ["//visibility:private"], + ) + + cc_tool( + name = name, + src = files_name, + **kwargs + ) diff --git a/tests/rule_based_toolchain/testdata/BUILD b/tests/rule_based_toolchain/testdata/BUILD index fa2cdd8..950751c 100644 --- a/tests/rule_based_toolchain/testdata/BUILD +++ b/tests/rule_based_toolchain/testdata/BUILD @@ -39,3 +39,10 @@ filegroup( name = "bin_filegroup", srcs = ["bin"], ) + +# Analysis_test is unable to depend on source files directly, but it can depend +# on a filegroup containing a single file. +filegroup( + name = "bin_wrapper_filegroup", + srcs = ["bin_wrapper.sh"], +) diff --git a/tests/rule_based_toolchain/tool/BUILD b/tests/rule_based_toolchain/tool/BUILD index d16ded6..8c48bd8 100644 --- a/tests/rule_based_toolchain/tool/BUILD +++ b/tests/rule_based_toolchain/tool/BUILD @@ -1,4 +1,5 @@ load("@rules_testing//lib:util.bzl", "util") +load("//cc/toolchains:directory_tool.bzl", "cc_directory_tool") load("//cc/toolchains:tool.bzl", "cc_tool") load("//tests/rule_based_toolchain:analysis_test_suite.bzl", "analysis_test_suite") load(":tool_test.bzl", "TARGETS", "TESTS") @@ -19,6 +20,15 @@ util.helper_target( visibility = ["//tests/rule_based_toolchain:__subpackages__"], ) +cc_directory_tool( + name = "directory_tool", + data = ["bin"], + directory = "//tests/rule_based_toolchain/testdata:directory", + executable = "bin_wrapper.sh", + execution_requirements = ["requires-network"], + requires_any_of = ["//tests/rule_based_toolchain/features:direct_constraint"], +) + analysis_test_suite( name = "test_suite", targets = TARGETS, diff --git a/tests/rule_based_toolchain/tool/tool_test.bzl b/tests/rule_based_toolchain/tool/tool_test.bzl index 8e9b68a..0f31a37 100644 --- a/tests/rule_based_toolchain/tool/tool_test.bzl +++ b/tests/rule_based_toolchain/tool/tool_test.bzl @@ -37,8 +37,8 @@ _BIN_WRAPPER_SYMLINK = "tests/rule_based_toolchain/testdata/bin_wrapper" _BIN_WRAPPER = "tests/rule_based_toolchain/testdata/bin_wrapper.sh" _BIN = "tests/rule_based_toolchain/testdata/bin" -def _tool_test(env, targets): - tool = env.expect.that_target(targets.tool).provider(ToolInfo) +def _tool_test(env, targets, target): + tool = env.expect.that_target(target).provider(ToolInfo) tool.exe().short_path_equals(_BIN_WRAPPER) tool.execution_requirements().contains_exactly(["requires-network"]) tool.runfiles().contains_exactly([ @@ -106,14 +106,17 @@ TARGETS = [ "//tests/rule_based_toolchain/features:direct_constraint", "//tests/rule_based_toolchain/tool:tool", "//tests/rule_based_toolchain/tool:wrapped_tool", + "//tests/rule_based_toolchain/tool:directory_tool", "//tests/rule_based_toolchain/testdata:bin_wrapper", "//tests/rule_based_toolchain/testdata:multiple", "//tests/rule_based_toolchain/testdata:bin_filegroup", + "//tests/rule_based_toolchain/testdata:bin_wrapper_filegroup", ] # @unsorted-dict-items TESTS = { - "tool_test": _tool_test, + "tool_test": lambda env, targets: _tool_test(env, targets, targets.tool), + "directory_tool_test": lambda env, targets: _tool_test(env, targets, targets.directory_tool), "wrapped_tool_includes_runfiles_test": _wrapped_tool_includes_runfiles_test, "collect_tools_collects_tools_test": _collect_tools_collects_tools_test, "collect_tools_collects_binaries_test": _collect_tools_collects_binaries_test,