Skip to content

Commit

Permalink
Add use_runfiles aspect_hint to include runfiles for specific cc_libr… (
Browse files Browse the repository at this point in the history
#2479)

Fixes #2477

Include all data from cc_libraries as runfiles or resources, depending
on aspect_hints.
Provide aspect_hints for resource collection for all resource targets
(eg, swift_library, cc_library, etc)

By default all data is now included from cc_libraries as runfiles and
follows the expected runfiles folder structure, with files retaining
their nested folders and being placed in
/external/pkg_name/some/file.txt when included from a http_archive or
local_repository.

The default behavior for other resource collecting targets like
swift_library has not changed, and will continue to collect and process
data as resources.

To allow modification of this default behavior, users may add
aspect_hints to the target cc_library/swift_library/etc. There are three
supported aspect_hints:
@build_bazel_rules_apple//apple:use_runfiles
@build_bazel_rules_apple//apple:use_resources
@build_bazel_rules_apple//apple:suppress_resources

##### Example
Here is an example of modifying the default behavior to bundle data.txt
as a resource instead of a runfile.
```
cc_library(
    name = "libapp",
    srcs = ["main.cpp",],
    data = [":data.txt"],
    aspect_hints = ["@build_bazel_rules_apple//apple:use_runfiles"],
)

macos_application(
    name = "app_macos",
    deps = [":libapp"],
)
```
data.txt is bundled in Contents/Resources/data.txt

#### Note
Hints apply only to the target and do not affect transitive deps,
however if a target includes runfiles then all runfiles are bundled
(including transitive runfiles) regardless of the hints applied to
transitive targets.

---------

Co-authored-by: Luis Padron <[email protected]>
  • Loading branch information
gkoreman and luispadron authored Aug 7, 2024
1 parent 4b40a88 commit 91be02a
Show file tree
Hide file tree
Showing 14 changed files with 389 additions and 28 deletions.
18 changes: 18 additions & 0 deletions apple/BUILD
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("//apple/internal/aspects:resource_aspect_hint.bzl", "apple_resource_hint", "apple_resource_hint_action")
load(":cc_toolchain_forwarder.bzl", "cc_toolchain_forwarder")

package(default_visibility = ["//visibility:public"])
Expand Down Expand Up @@ -278,3 +279,20 @@ filegroup(
],
visibility = ["//:__pkg__"],
)

# An aspect hint that enables runfile inclusion as AppleResources
# for cc_libraries. Runfiles keep their folder structure.
apple_resource_hint(
name = "use_resources",
action = apple_resource_hint_action.resources,
)

apple_resource_hint(
name = "use_runfiles",
action = apple_resource_hint_action.runfiles,
)

apple_resource_hint(
name = "suppress_resources",
action = apple_resource_hint_action.suppress,
)
8 changes: 8 additions & 0 deletions apple/internal/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ bzl_library(
"//apple:providers",
"//apple/internal/aspects:framework_provider_aspect",
"//apple/internal/aspects:resource_aspect",
"//apple/internal/aspects:resource_aspect_hint",
"//apple/internal/utils:clang_rt_dylibs",
"//apple/internal/utils:main_thread_checker_dylibs",
"@bazel_skylib//lib:collections",
Expand Down Expand Up @@ -394,6 +395,7 @@ bzl_library(
"//apple:providers",
"//apple/internal/aspects:framework_provider_aspect",
"//apple/internal/aspects:resource_aspect",
"//apple/internal/aspects:resource_aspect_hint",
"//apple/internal/utils:clang_rt_dylibs",
"//apple/internal/utils:main_thread_checker_dylibs",
],
Expand Down Expand Up @@ -533,6 +535,7 @@ bzl_library(
"//apple/internal/aspects:app_intents_aspect",
"//apple/internal/aspects:framework_provider_aspect",
"//apple/internal/aspects:resource_aspect",
"//apple/internal/aspects:resource_aspect_hint",
"//apple/internal/aspects:swift_usage_aspect",
"//apple/internal/testing:apple_test_bundle_support",
"@bazel_skylib//lib:dicts",
Expand All @@ -556,6 +559,7 @@ bzl_library(
"//apple:providers",
"//apple/internal/aspects:framework_provider_aspect",
"//apple/internal/aspects:resource_aspect",
"//apple/internal/aspects:resource_aspect_hint",
"//apple/internal/aspects:swift_dynamic_framework_aspect",
"//apple/internal/aspects:swift_usage_aspect",
"//apple/internal/testing:apple_test_bundle_support",
Expand Down Expand Up @@ -667,6 +671,7 @@ bzl_library(
"//apple:providers",
"//apple/internal/aspects:framework_provider_aspect",
"//apple/internal/aspects:resource_aspect",
"//apple/internal/aspects:resource_aspect_hint",
"//apple/internal/utils:clang_rt_dylibs",
"//apple/internal/utils:main_thread_checker_dylibs",
"@bazel_tools//tools/cpp:toolchain_utils.bzl",
Expand Down Expand Up @@ -703,6 +708,7 @@ bzl_library(
"//apple:providers",
"//apple/internal/aspects:framework_provider_aspect",
"//apple/internal/aspects:resource_aspect",
"//apple/internal/aspects:resource_aspect_hint",
"//apple/internal/utils:clang_rt_dylibs",
"//apple/internal/utils:main_thread_checker_dylibs",
"@bazel_skylib//lib:sets",
Expand Down Expand Up @@ -738,6 +744,7 @@ bzl_library(
"//apple:providers",
"//apple/internal/aspects:framework_provider_aspect",
"//apple/internal/aspects:resource_aspect",
"//apple/internal/aspects:resource_aspect_hint",
"//apple/internal/utils:clang_rt_dylibs",
"//apple/internal/utils:main_thread_checker_dylibs",
"@bazel_skylib//lib:sets",
Expand Down Expand Up @@ -771,6 +778,7 @@ bzl_library(
":transition_support",
"//apple:providers",
"//apple/internal/aspects:resource_aspect",
"//apple/internal/aspects:resource_aspect_hint",
"//apple/internal/aspects:swift_usage_aspect",
"//apple/internal/utils:files",
"@bazel_skylib//lib:partial",
Expand Down
12 changes: 12 additions & 0 deletions apple/internal/aspects/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ bzl_library(
],
)

bzl_library(
name = "resource_aspect_hint",
srcs = ["resource_aspect_hint.bzl"],
visibility = [
"//apple/internal:__pkg__",
"//apple/internal/testing:__pkg__",
],
deps = [
"@build_bazel_rules_swift//swift",
],
)

bzl_library(
name = "swift_dynamic_framework_aspect",
srcs = ["swift_dynamic_framework_aspect.bzl"],
Expand Down
62 changes: 58 additions & 4 deletions apple/internal/aspects/resource_aspect.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ load(
"@build_bazel_rules_apple//apple/internal:swift_support.bzl",
"swift_support",
)
load(
"@build_bazel_rules_apple//apple/internal/aspects:resource_aspect_hint.bzl",
"AppleResourceHintInfo",
"apple_resource_hint_action",
)
load(
"@build_bazel_rules_apple//apple/internal/providers:apple_debug_info.bzl",
"AppleDebugInfo",
Expand Down Expand Up @@ -125,48 +130,85 @@ def _apple_resource_aspect_impl(target, ctx):
collect_structured_args = {}
collect_framework_import_bundle_files = None

hint_action = None
default_action = None

# TODO: remove usage of `getattr` and use `aspect_ctx.rule.attr.aspect_hints` directly when we drop Bazel 6.
aspect_hint = None
for hint in getattr(ctx.rule.attr, "aspect_hints", []):
if AppleResourceHintInfo in hint:
if aspect_hint:
fail(("Conflicting AppleResourceHintInfo from aspect hints " +
"'{hint1}' and '{hint2}'. Only one is " +
"allowed.").format(
hint1 = str(aspect_hint.label),
hint2 = str(hint.label),
))
aspect_hint = hint
hint_action = hint[AppleResourceHintInfo].action

# Owner to attach to the resources as they're being bucketed.
owner = None

# The name of the bundle directory to place resources within, if required.
bundle_name = None

if ctx.rule.kind == "objc_library":
default_action = apple_resource_hint_action.resources
collect_args["res_attrs"] = ["data"]

# Only set objc_library targets as owners if they have srcs, non_arc_srcs or deps. This
# treats objc_library targets without sources as resource aggregators.
if ctx.rule.attr.srcs or ctx.rule.attr.non_arc_srcs or ctx.rule.attr.deps:
owner = str(ctx.label)

elif ctx.rule.kind == "cc_library":
default_action = apple_resource_hint_action.runfiles
collect_args["res_attrs"] = ["data"]

elif ctx.rule.kind == "objc_import":
default_action = apple_resource_hint_action.resources
collect_args["res_attrs"] = ["data"]

elif ctx.rule.kind == "cc_import":
default_action = apple_resource_hint_action.runfiles
collect_args["res_attrs"] = ["data"]

elif ctx.rule.kind == "swift_library":
default_action = apple_resource_hint_action.resources
module_names = [x.name for x in target[SwiftInfo].direct_modules if x.swift]
bucketize_args["swift_module"] = module_names[0] if module_names else None
collect_args["res_attrs"] = ["data"]
owner = str(ctx.label)

elif ctx.rule.kind in ["apple_static_framework_import", "apple_static_xcframework_import"]:
default_action = apple_resource_hint_action.resources
if AppleFrameworkImportBundleInfo in target:
collect_framework_import_bundle_files = target[AppleFrameworkImportBundleInfo].bundle_files
collect_args["res_attrs"] = ["data"]
owner = str(ctx.label)

elif ctx.rule.kind == "apple_resource_group":
default_action = apple_resource_hint_action.resources
collect_args["res_attrs"] = ["resources"]
collect_structured_args["res_attrs"] = ["structured_resources"]

elif ctx.rule.kind == "apple_resource_bundle":
default_action = apple_resource_hint_action.resources
collect_infoplists_args["res_attrs"] = ["infoplists"]
collect_args["res_attrs"] = ["resources"]
collect_structured_args["res_attrs"] = ["structured_resources"]
process_args["bundle_id"] = ctx.rule.attr.bundle_id or None
bundle_name = "{}.bundle".format(ctx.rule.attr.bundle_name or ctx.label.name)

if hint_action:
default_action = hint_action

is_resource_action = default_action == apple_resource_hint_action.resources
is_runfiles_action = default_action == apple_resource_hint_action.runfiles

# Collect all resource files related to this target.
if collect_infoplists_args:
if collect_infoplists_args and is_resource_action:
infoplists = resources.collect(
attr = ctx.rule.attr,
**collect_infoplists_args
Expand All @@ -190,7 +232,7 @@ def _apple_resource_aspect_impl(target, ctx):
),
)

if collect_args:
if collect_args and is_resource_action:
resource_files = resources.collect(
attr = ctx.rule.attr,
**collect_args
Expand All @@ -213,7 +255,7 @@ def _apple_resource_aspect_impl(target, ctx):
),
)

if collect_structured_args:
if collect_structured_args and is_resource_action:
# `structured_resources` requires an explicit parent directory, requiring them to be
# processed differently from `resources` and resources inherited from other fields.
#
Expand Down Expand Up @@ -264,7 +306,7 @@ def _apple_resource_aspect_impl(target, ctx):
)

# Collect .bundle/ files from framework_import rules
if collect_framework_import_bundle_files:
if collect_framework_import_bundle_files and is_resource_action:
parent_dir_param = partial.make(
resources.bundle_relative_parent_dir,
extension = "bundle",
Expand All @@ -278,6 +320,18 @@ def _apple_resource_aspect_impl(target, ctx):
),
)

if is_runfiles_action:
# Gather the runfiles and mark them as pre-processed/unprocessed
# dylibs are excluded from runfile packaging because they are included in the Content/Resources directory instead.
apple_resource_infos.append(
resources.bucketize_typed(
[x for x in target[DefaultInfo].default_runfiles.files.to_list() if x.extension != "dylib"],
owner = None,
bucket_type = "unprocessed",
parent_dir_param = partial.make(resources.runfiles_resources_parent_dir),
),
)

# Get the providers from dependencies, referenced by deps and locations for resources.
apple_debug_infos = []
apple_dsym_bundle_infos = []
Expand Down
Loading

0 comments on commit 91be02a

Please sign in to comment.