bazelbuild / bazelbuild/rules_apple
Mergeable libraries tracking issue
- Dominant language
- Starlark
- Stars
- 593
- Forks
- 334
- Avg merge
- 16h 48m
- Merged PRs (30d)
- 9
Description
Note: this is beta 1 so things could change
As part of Xcode 15 the included linker now supports a new concept called ["mergeable libraries"](https://developer.apple.com/documentation/xcode/configuring-your-project-to-use-mergeable-libraries). Mergeable libraries are dynamic libraries with an extra load command that contains enough info to re-link the library similar to a static library. Meaning that you can more (potentially) easily have dynamic libraries for development (to avoid monolithic re-links when you change a single library), but not pay the launch time cost of dynamic libraries in production builds. Today some folks using bazel achieve this by conditionally including their dynamic libraries in production vs debug using `select()`, but it's possible this new approach makes things easier.
The way these currently work is by providing a few different linker flags throughout the build process:
- when producing the dynamic binary that you want to be merged into another binary later in the build process, you pass `-make_mergeable` to the linker
- when consuming a dynamic binary that you want to be merged into your binary, you pass `-merge-lNAME`, `-merge_library path/to/library`, or `-merge_framework NAME`
- when consuming a dynamic binary that your consumers depend on, but you don't want to merge into your binary (to avoid the link time overhead), you can re-export that binary with `-reexport-lNAME`, `-reexport_library path/to/library`, or `-reexport_framework NAME` (bazel might not need to handle this one)
I think there are also a few different levels of potential integration that the rules could do for this, depending on how useful this new feature is vs doing this conditionally as you can do today.
1. Third party frameworks that are vendored to you as dynamic binaries might start containing the extra info needed to link them as a mergeable library. In this case they either need to be linked as a mergeable library (maybe only in release builds), or stripped since the extra info is sizable (potentially doubles the binary size). I think we have to make sure at least that they are stripped to not balloon app size. If you actually wanted to link them as a mergeable library you could do this today with `linkopts = ["-Wl,-merge_framework,NAME"]`.
2. Add support for making current dynamic binaries mergeable, such as `ios_dynamic_framework` and `ios_framework`, and then consuming targets that are known to be mergeable from other binary targets with the correct linkopts (potentially conditionally). This would be roughly equivalent to just adding `-make_mergeable` on the targets, and then propagating some new info to indicate that was the case to add the `-merge_framework` argument further up the dependency tree.
3. Provide a new rule for using this behavior. It's possible the current design of requiring `frameworks = []` to be used to consume `ios_framework` targets is too cumbersome here, especially if the line between static and dynamic frameworks is no longer as meaningful, in which case maybe we should have a different rule for this new case that is always used via deps.
Xcode also suggests mixing mergeable and dynamic libraries when you want to reduce app size when using extensions. This is equivalent to what you could do today by linking multiple static libraries into a single `ios_framework` that was shared between an app and extension, but also potentially complicates how we support these.
Contributor guide
Research direction
No files, tests, or concrete entry point are named. Start by reviewing the ios_dynamic_framework and ios_framework rules and how their linkopts and dependencies are propagated, then compare the three integration levels described in the issue. Done would require an agreed scope and verified handling of the relevant mergeable-library linker flags.
Written by the indexing model from the issue text.
Assessment
- Domain
- build-system, mobile-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 22/100