diff --git a/prelude/cxx/cxx_library.bzl b/prelude/cxx/cxx_library.bzl index 29ac418ee9c0b..ca89aca0855df 100644 --- a/prelude/cxx/cxx_library.bzl +++ b/prelude/cxx/cxx_library.bzl @@ -1609,8 +1609,15 @@ def _static_library( # object files instead of the originating objects. object_external_debug_info = [] if linker_type == LinkerType("darwin"): - object_external_debug_info.append(archive.artifact) - object_external_debug_info.extend(archive.external_objects) + if archive.external_objects: + # On Darwin, when using virtual archives, object files are passed + # to the linker directly between --start-lib --end-lib flags to + # achieve archive semantics without creating the archive. Providing + # the archive artifact as an input here is unnecessary. + object_external_debug_info.extend(archive.external_objects) + else: + # For normal archives, we just need to provide the archive artifact + object_external_debug_info.append(archive.artifact) elif objects_have_external_debug_info: object_external_debug_info.extend(objects) diff --git a/prelude/linking/link_info.bzl b/prelude/linking/link_info.bzl index 4c286cab7a59f..49386f2cdafbb 100644 --- a/prelude/linking/link_info.bzl +++ b/prelude/linking/link_info.bzl @@ -247,7 +247,16 @@ def _is_linkable_comprised_of_object_files_or_a_lazy_archive(linkable: LinkableT # Adds appropriate args representing `linkable` to `args` def append_linkable_args(args: cmd_args, linkable: LinkableTypes): if isinstance(linkable, ArchiveLinkable): - if linkable.link_whole: + if linkable.linker_type == LinkerType("darwin") and linkable.archive.external_objects: + if not linkable.link_whole: + args.add("-Wl,--start-lib") + + for object in linkable.archive.external_objects: + args.add(object) + + if not linkable.link_whole: + args.add("-Wl,--end-lib") + elif linkable.link_whole: args.add(get_link_whole_args(linkable.linker_type, [linkable.archive.artifact])) else: args.add(linkable.archive.artifact)