Skip to content

feat: derive private framework exports from client link graphs - #3039

Draft
karim-alweheshy wants to merge 1 commit into
bazelbuild:mainfrom
karim-alweheshy:codex/derive-private-framework-exports
Draft

feat: derive private framework exports from client link graphs#3039
karim-alweheshy wants to merge 1 commit into
bazelbuild:mainfrom
karim-alweheshy:codex/derive-private-framework-exports

Conversation

@karim-alweheshy

@karim-alweheshy karim-alweheshy commented Aug 2, 2026

Copy link
Copy Markdown

Private dynamic frameworks assembled from static libraries can publish many
implementation-detail symbols even when only a closed set of applications and
extensions load them. Add an opt-in apple_exported_symbols_list rule that
derives the framework ABI from explicit client CcInfo graphs and feeds the
result to the existing framework exported_symbols_lists attribute.

Bazel cannot discover reverse consumers, so callers provide the complete client
link roots. This is intended for app-private frameworks with a closed client
set, not public frameworks whose current consumers do not define a stable ABI.

The rule keeps client-imported definitions and conservatively preserves
non-Swift definitions by default for Objective-C runtime and dlsym lookup.
Projects that have audited runtime lookup can disable that policy and provide
authored runtime roots instead. It uses the selected Xcode's llvm-nm, supports
custom LLVM toolchains, and exposes a JSON audit report.

Tested with pre-commit run --from-ref upstream/main --to-ref HEAD and
bazel test //tools/exported_symbols_list:exported_symbols_list_test //test/starlark_tests:exported_symbols_list //doc:check_linker --nocache_test_results.
The final Mach-O test compares an unrestricted control and verifies that the
client-used Swift API and conservative C runtime root remain exported while the
unused public Swift API does not.

@karim-alweheshy
karim-alweheshy marked this pull request as ready for review August 5, 2026 05:22
@karim-alweheshy

karim-alweheshy commented Aug 5, 2026

Copy link
Copy Markdown
Author

CI audit: the currently red Bazel 8.x, Bazel 9.x, and last-green lanes all stopped before checkout after repeated pull-ref fetches ended with a mirror bus error. The Bazel 8.0.1 lane did check out the same head and completed the full public test matrix, including all five exported-symbol-list tests. I found no code failure in this run; the remaining red statuses need an infrastructure retry.

@karim-alweheshy

Copy link
Copy Markdown
Author

@adincebic, could you rerun the failed Buildkite lanes when convenient? Bazel 8.x, 9.x, and last-green all stopped before checkout on repeated mirror fetch bus errors; the Bazel 8.0.1 lane checked out this same head and passed the full public suite, including all five new exported-symbol-list tests. Once the infrastructure lanes are green, a review of the linker/export aspect would be appreciated.

@adincebic

Copy link
Copy Markdown
Contributor

@adincebic, could you rerun the failed Buildkite lanes when convenient? Bazel 8.x, 9.x, and last-green all stopped before checkout on repeated mirror fetch bus errors; the Bazel 8.0.1 lane checked out this same head and passed the full public suite, including all five new exported-symbol-list tests. Once the infrastructure lanes are green, a review of the linker/export aspect would be appreciated.

Sure.

@karim-alweheshy
karim-alweheshy marked this pull request as draft August 6, 2026 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants