Skip to content

Pass -no_exported_symbols by default - #3024

Draft
keith wants to merge 7 commits into
mainfrom
ks/add-empty-exported_symbols_list-by-default
Draft

Pass -no_exported_symbols by default#3024
keith wants to merge 7 commits into
mainfrom
ks/add-empty-exported_symbols_list-by-default

Conversation

@keith

@keith keith commented Jul 20, 2026

Copy link
Copy Markdown
Member

Passing -Wl,-no_exported_symbols has been generally
recommended to reduce app size. Since we have the
exported_symbols_list attribute, if those are never set, we can do
this by default. This does require folks export things that they
actually need.

keith added 2 commits July 20, 2026 12:44
Passing `-Wl,-exported_symbols_list,/dev/null` has been generally
recommended to reduce app size. Since we have the
`exported_symbols_list` attribute, if those are never set, we can do
this by default. This does require folks export things that they
actually need.
@keith keith changed the title Add empty exported_symbols_list by default Pass -no_exported_symbols by default Jul 20, 2026
@karim-alweheshy

Copy link
Copy Markdown

One compatibility concern before making -no_exported_symbols the default: it also removes __mh_execute_header.

I verified this on a reduced ios_application with Xcode 26.5 / ld 1267: nm -gU reports zero defined exports and dyld_info -exports is empty. Firebase Crashlytics' current source explicitly says it needs __mh_execute_header and refuses to initialize when that lookup fails (source, reproduced issue).

Would it make sense to retain only that symbol for app-like executables instead?

-Wl,-exported_symbol,__mh_execute_header

On the same reduced input this changed four exports to one while leaving __TEXT / __text unchanged. Explicit exported_symbols_lists can remain additive for apps that need more symbols, including XCTest bundle-loader hosts.

I put together an opt-in, product-scoped implementation with analysis tests for default-off behavior, opt-out, apps, extensions, additive custom exports, and framework exclusion: main...karim-alweheshy:rules_apple:codex/restrict-application-exports

@keith

keith commented Jul 31, 2026

Copy link
Copy Markdown
Member Author

yea i think if we want to move forward with this including that symbol by default would be fine

@karim-alweheshy

Copy link
Copy Markdown

Separately, I prototyped the framework-side counterpart as a reusable apple_exported_symbols_list rule. It takes explicit framework deps and client CcInfo roots (Bazel cannot discover reverse dependencies), derives the client-required exports, keeps non-Swift definitions conservatively by default, and emits an audit report. The conservative policy has an explicit opt-out plus authored runtime roots because it can pull otherwise-unreferenced archive members.

A final Mach-O test covers the unrestricted negative control, the retained client-used Swift API, the removed unused Swift API, and the conservative C runtime root. I kept this independent from the application feature for focused review: main...karim-alweheshy:rules_apple:codex/derive-private-framework-exports

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