bazelbuild / rules_apple

Bazel rules to build apps for Apple platforms.
Apache License 2.0
510 stars 268 forks source link

I need to apply a transition on a target defined by ios_extension rule #2558

Open vakhidbetrakhmadov opened 2 weeks ago

vakhidbetrakhmadov commented 2 weeks ago

Hello,

I need to apply a transition on a target defined by ios_extension rule.

I have the following setup:

App -> Extension 
App -> Module_A -> Module_B -> Module_C -> ... -> Module_Z
Extension -> Module_B -> Module_C 

In order to reduce App size, i would like to flavour Module_C for Extension.

In order to flavour Module_C for Extension i need to propagate a custom build setting along the Extension -> ... dependency tree.

I have done some research and it looks like that at the moment there is no supported way of applying a transition on a target defined by a third party rule.

The most commonly proposed workaround that i found is to create a wrapper rule around the third party rule. The wrapper rule can apply required transitions on the wrapped rule and propagate its providers.

I have pretty much done this with ios_extension, but there is an issue that i am facing.

The issue is that not all ios_extension's providers are accessible from outside of rules_apple, and without for example AppleDebugInfo no dSYMs for Extension are generated, or without _AppleSymbolsFileInfo no .symbols for Extension are generated.

I didn't find any difference in the output with/without _AppleCodesigningDossierInfo, AppleExtensionSafeValidationInfo, _AppleSwiftDylibsInfo.

load("//Bazel/flavour:flavour_transition.bzl", "flavour_transition")
load(
    "@build_bazel_rules_apple//apple:providers.bzl",
    "AppleBundleInfo",
    "AppleCodesigningDossierInfo",
    "AppleDsymBundleInfo",
    "AppleResourceInfo",
    "IosExtensionBundleInfo",
)
load(
    "@build_bazel_rules_apple//apple/internal/providers:embeddable_info.bzl",
    "AppleEmbeddableInfo",
)

def _flavoured_ios_extension_impl(ctx):
    ios_extension = ctx.attr.ios_extension[0]

    # The list of providers extracted from the `print(ios_extension)` output (unaccessible providers are commented out).
    ios_extension_providers = [
        DefaultInfo,
        apple_common.AppleExecutableBinary,
        IosExtensionBundleInfo,
        apple_common.AppleDebugOutputs,
        AppleBundleInfo,
        # _AppleCodesigningDossierInfo,
        AppleCodesigningDossierInfo,
        AppleDsymBundleInfo,
        # AppleDebugInfo,
        AppleEmbeddableInfo,
        # _AppleExtensionSafeValidationInfo,
        AppleResourceInfo,
        # _AppleSwiftDylibsInfo,
        # _AppleSymbolsFileInfo,
        OutputGroupInfo,
    ]

    return [
        ios_extension[provider]
        for provider in ios_extension_providers
        if provider in ios_extension
    ]

flavoured_ios_extension = rule(
    implementation = _flavoured_ios_extension_impl,
    doc = "ios_extension wrapper that applies flavour_transition",
    attrs = {
        "ios_extension": attr.label(mandatory = True, cfg = flavour_transition),
        "flavour": attr.string(mandatory = True),
        "_allowlist_function_transition": attr.label(default = "@bazel_tools//tools/allowlists/function_transition_allowlist"),
    },
)
brentleyjones commented 1 week ago

@fmeum Do you know a way to forward providers in a transition without them being public? Ideally we wouldn't have to make the change that #2559 is proposing.

fmeum commented 1 week ago

I don't think that's possible at the moment. There's been some discussion about introducing a way to forward all but a select few providers, but the last time that came up was a year ago.