text: """
  Rules for overridding the linker for Apple builds
  """
  
  def _attrs(linker, extra_attrs):
      """
      Get the shared attributes for all the linker rules
  
      Args:
          linker: The default linker binary
          extra_attrs: Extra attributes For the specific rule
      """
      attrs = {
          "linker": attr.label(
              default = linker,
              allow_single_file = True,
              executable = True,
              cfg = "exec",
              doc = "The linker to use",
          ),
          "ld64_linkopts": attr.string_list(
              doc = "The options to pass to ld64 if 'enable' is False",
          ),
          "linkopts": attr.string_list(
              doc = "The options to pass to both the overriden linker and ld64",
          ),
          "enable": attr.bool(
              default = True,
              doc = "Whether to enable the overriden linker, useful for disabling with select",
          ),
      }
      attrs.update(extra_attrs)
      return attrs
  
  def _linker_override(ctx, override_linkopts):
      """Construct the providers to override the linker
  
      Args:
          ctx: The rule context, expected to have some shared attrs
          override_linkopts: Linker options to use with the custom linker
      """
  
      if not ctx.attr.linker:
          fail("error: linker not specified")
  
      linkopts = list(ctx.attr.linkopts)
      if ctx.attr.enable:
          linker_inputs_depset = ctx.attr.linker.files
          linkopts.append(
              ctx.expand_location(
                  "--ld-path=$(location {})".format(ctx.attr.linker.label),
                  targets = [ctx.attr.linker],
              ),
          )
          linkopts.extend(override_linkopts)
      else:
          linker_inputs_depset = depset([])
          linkopts.extend(ctx.attr.ld64_linkopts)
  
      linkopts_depset = depset(direct = linkopts, order = "topological")
      return [
          apple_common.new_objc_provider(
              link_inputs = linker_inputs_depset,
              linkopt = linkopts_depset,
          ),
          CcInfo(
              linking_context = cc_common.create_linking_context(
                  linker_inputs = depset([
                      cc_common.create_linker_input(
                          additional_inputs = linker_inputs_depset,
                          owner = ctx.label,
                          user_link_flags = linkopts_depset,
                      ),
                  ]),
              ),
          ),
      ]
  
  def _apple_linker_override(ctx):
      return _linker_override(ctx, ctx.attr.override_linkopts)
  
  apple_linker_override = rule(
      implementation = _apple_linker_override,
      attrs = _attrs(
          None,
          {
              "override_linkopts": attr.string_list(
                  mandatory = False,
                  doc = "The options to pass to the custom linker, and not ld64 (see enable)",
              ),
          },
      ),
      provides = [apple_common.Objc, CcInfo],
  )
  
  def _zld_override(ctx):
      return _linker_override(ctx, ctx.attr.zld_linkopts)
  
  zld_override = rule(
      implementation = _zld_override,
      attrs = _attrs(
          "@rules_apple_linker_zld//:zld_bin",
          {
              "zld_linkopts": attr.string_list(
                  mandatory = False,
                  doc = "The options to pass to zld, and not ld64 (see enable)",
              ),
          },
      ),
      provides = [apple_common.Objc, CcInfo],
  )
  
  def _lld_override(ctx):
      return _linker_override(ctx, ctx.attr.lld_linkopts)
  
  lld_override = rule(
      implementation = _lld_override,
      attrs = _attrs(
          "@rules_apple_linker_lld//:lld_bin",
          {
              "lld_linkopts": attr.string_list(
                  mandatory = False,
                  doc = "The options to pass to lld, and not ld64 (see enable)",
              ),
          },
      ),
      provides = [apple_common.Objc, CcInfo],
  )
  