Skip to content

Support Swift in the iOS embedder#167530

Merged
auto-submit[bot] merged 14 commits into
flutter:masterfrom
cbracken:add-swift-toolchain
Apr 26, 2025
Merged

Support Swift in the iOS embedder#167530
auto-submit[bot] merged 14 commits into
flutter:masterfrom
cbracken:add-swift-toolchain

Conversation

@cbracken

@cbracken cbracken commented Apr 22, 2025

Copy link
Copy Markdown
Member

Adds a swift tool to the gn mac toolchain and wires up support for Swift source_set targets. Ports FlutterUIPressProxy to Swift.

gn toolchain modifications include:

  • Removes //flutter/third_party/libcxx/include and //flutter/third_party/libcxxabi/include from the default include_dirs on all source_set targets, and instead adds them via cflags and cflags_cc so they continue to be picked up by C, C++, Obj-C, Obj-C++ targets. Flutter's custom libc++ library headers should be picked up by C, C++, Objective-C, and Objective-C++ targets, but not Swift targets. Swift code does not use libc++ directly, but many Apple core libraries such as Foundation.framework are implemented in Objective-C/Objective-C++ and directly or indirectly rely on Apple's libc++ implementation in System.framework. Because of this, and because Swift compiles use Clang modules, we should ensure the correct (Apple) libc++ is picked up from Swift targets by ensuring our own libc++ is not.
  • Adds a default empty list for swiftflags to source_set targets. This list is used by for Swift source_set targets by the swift tool in the gn toolchain.
  • Adds a //build/config/ios:compiler config to engine/src/build/config/ios/BUILD.gn. This sets default swiftflags for iOS targets. This attribute is (only) used by the new swift tool in the toolchain.
  • Adds -g to swiftflags for debug (unopt) builds in engine/src/build/config/compiler/BUILD.gn.
  • Adds a swift tool to the gn toolchain that invokes swiftc.py to perform compilation and generate a bridging header. This tool is invoked automatically by gn for Swift source_set targets.
  • Adds //build/toolchain/apple/swiftc.py, a wrapper script around swiftc in Xcode's Swift toolchain. This script ensures builds are invoked hermetically using a new build cache directory for the emitted swiftmodule, precompiled header, and bridging header, for each compile. The outputs are then copied into the gn output directory. Also adds supporting script //build/toolchain/apple/get_tool_mtime.py and data //build/toolchain/apple/swift_const_gather_protocols.json, both used by swiftc.py.
  • Adds a cxx_module tool to the gn toolchain that supports clang module-based compiles. This is used for libc++ transitively via System.framework and others that rely on it.

gn variable modifications include:

  • Adds apple_host_toolchain_path variable in engine/src/build/config/apple/apple_sdk.gni. This is set using //build/mac/find_sdk.py to the path of Xcode's XcodeDefault.xctoolchain. This is where Xcode's swiftc tool and some Swift libraries are located. This will be used to create a symlink in the //flutter/prebuilts/SDKs directory to locate Swift tooling during builds.
  • Updates enging/src/tools/gn to pre-populate that path as we do with other Xcode SDK path symlinks, to improve performance.
  • Adds ios_swift_lib_paths in engine/src/build/config/ios/ios_sdk.gni which holds the path of Swift shared libraries for either iOS physical device or simulator targets. This is within the appropriate iphone or iphonesimulator SDK directory within Xcode.

verify_exported.dart changes:

  • Allow exported symbols that match regexp ^_\$s\d+InternalFlutterSwift. To allow Swift symbols to be exported in an Objective-C bridging header, they must be public or open. We only ever use these types internally within the framework and never publish these types in a public header. Like _InternalFlutter Obj-C symbols, we allow InternalFlutterSwift symbols, as they are clearly marked as internal and an end user would need to reverse engineer out their own header to use them.
  • Allow Obj-C symbols in the (__DATA,__data) and (__DATA_CONST,__const) in addition to the existing Mach-O sections, so long as it matches the existing criteria.

Finally, this patch adds Swift code to the embedder and embedder tests as proof of concept and to prevent regressions. This ports FlutterUIPressProxy and its subclass FakeUIPressProxy to Swift in order to verify both:

  • Objective-C imports of Swift via a bridging header
  • Swift imports of Swift via a bridging header

Issue: #144791

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@cbracken cbracken requested review from a team and vashworth as code owners April 22, 2025 04:30
@github-actions github-actions Bot added platform-ios iOS applications specifically engine flutter/engine related. See also e: labels. team-ios Owned by iOS platform team labels Apr 22, 2025
@cbracken cbracken force-pushed the add-swift-toolchain branch 6 times, most recently from 2b0c064 to f8841c0 Compare April 22, 2025 20:16
@cbracken cbracken requested a review from hellohuanlin April 22, 2025 20:33
@cbracken cbracken force-pushed the add-swift-toolchain branch 2 times, most recently from 73ed14a to 2f44201 Compare April 22, 2025 21:28

@zanderso zanderso left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Comment thread engine/src/build/config/ios/BUILD.gn Outdated
Comment thread engine/src/build/config/ios/BUILD.gn Outdated
Comment thread engine/src/build/toolchain/apple/get_tool_mtime.py
Comment thread engine/src/build/toolchain/apple/swiftc.py
Comment thread engine/src/build/config/ios/ios_sdk.gni Outdated
@cbracken cbracken force-pushed the add-swift-toolchain branch 3 times, most recently from f102b89 to d384568 Compare April 23, 2025 16:26
Comment thread engine/src/build/config/apple/apple_sdk.gni Outdated
Comment thread engine/src/build/config/mac/mac_sdk.gni Outdated
Comment thread engine/src/build/config/ios/BUILD.gn Outdated
Comment thread engine/src/build/toolchain/apple/swiftc.py Outdated
Comment thread engine/src/build/toolchain/apple/swiftc.py
Comment thread engine/src/build/toolchain/apple/swiftc.py Outdated
Comment thread engine/src/build/toolchain/apple/swiftc.py Outdated
_tool = rebase_path("//build/toolchain/apple/swiftc.py", root_build_dir)

depfile = "{{target_out_dir}}/{{module_name}}.d"
depsformat = "gcc"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For those who haven't been sufficiently traumatised by gn, the reason for the seemingly random alternation between variables prefixed/unprefixed in _ is that the unprefixed ones are special tool attributes that gn knows about whereas the prefixed ones are locals to make this less painful to read.

@cbracken cbracken requested a review from matanlurey as a code owner April 23, 2025 20:51
@github-actions github-actions Bot added the tool Affects the "flutter" command-line tool. See also t: labels. label Apr 23, 2025
@cbracken cbracken force-pushed the add-swift-toolchain branch from bf46015 to 1503f02 Compare April 23, 2025 22:03
@github-actions github-actions Bot removed the tool Affects the "flutter" command-line tool. See also t: labels. label Apr 23, 2025
@cbracken cbracken force-pushed the add-swift-toolchain branch from 1503f02 to 111da32 Compare April 23, 2025 22:04
@github-actions github-actions Bot added a: tests "flutter test", flutter_test, or one of our tests tool Affects the "flutter" command-line tool. See also t: labels. framework flutter/packages/flutter repository. See also f: labels. d: examples Sample code and demos f: integration_test The flutter/packages/integration_test plugin labels Apr 24, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 29, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 29, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 29, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 30, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 30, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 1, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 1, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 1, 2025
# This is here so that all files get recompiled after an Xcode update.
# (defines are passed via the command line, and build system rebuild things
# when their commandline changes). Nothing should ever read this define.
#defines = [ "CR_XCODE_VERSION=$xcode_version" ]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cbracken Oh i just remembered I came across this a while back when trying to support swift 6.

From the comment it looks like you intended to pass it in below to handle xcode update scenario, but it's commented out. Wondering what's the current state (can it be removed or do we still want it?)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

engine flutter/engine related. See also e: labels. platform-ios iOS applications specifically team-ios Owned by iOS platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants