Skip to content

iOS: clean up swiftc.py after migration to target triples#189240

Merged
auto-submit[bot] merged 1 commit into
flutter:masterfrom
cbracken:target-triple-args
Jul 11, 2026
Merged

iOS: clean up swiftc.py after migration to target triples#189240
auto-submit[bot] merged 1 commit into
flutter:masterfrom
cbracken:target-triple-args

Conversation

@cbracken

Copy link
Copy Markdown
Member

In #189174, we migrated back to using target triples in swiftc.py in order to more closely mirror the commandline interface to swiftc itself.

This is a followup that cleans up some extra function parameters that are no longer necessary now that we're getting the target triple in args.

This cleans up a few remaining diffs from the reversion of the target triple splitting from https://github.com/flutter/flutter/pull/185712/changes#diff-d57f937ed2d743b17635dd069689072eba124f649f307228915c25d55b19ed62.

No test changes since this is a refactor with no semantic change. The test is the build (and transitively, all the tests it builds and runs).

Issue: #185741

Pre-launch Checklist

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

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

@cbracken
cbracken requested a review from LongCatIsLooong July 10, 2026 02:05
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jul 10, 2026
@github-actions github-actions Bot added the engine flutter/engine related. See also e: labels. label Jul 10, 2026
@flutter-dashboard

Copy link
Copy Markdown

It looks like this pull request may not have tests. Please make sure to add tests or get an explicit test exemption before merging.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. If you believe this PR qualifies for a test exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!). The test exemption team is a small volunteer group, so all reviewers should feel empowered to ask for tests, without delegating that responsibility entirely to the test exemption group.

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request refactors the Swift compiler invocation script by removing the 'target_triple' parameter from the 'invoke_swift_compiler' and 'compile_module' function signatures, accessing it directly from the 'args' object instead. However, a critical issue was found where 'invoke_swift_compiler' is still called with the 'target_triple' keyword argument, which will result in a TypeError at runtime.

Comment thread engine/src/build/toolchain/darwin/swiftc.py Outdated
@cbracken
cbracken force-pushed the target-triple-args branch from 35ed00f to 5f63773 Compare July 10, 2026 02:14
In flutter#189174, we migrated back to
using target triples in swiftc.py in order to more closely mirror the
commandline interface to `swiftc` itself.

This is a followup that cleans up some extra function parameters that
are no longer necessary now that we're getting the target triple in
args.

This cleans up a few remaining diffs from the reversion of the target
triple splitting from https://github.com/flutter/flutter/pull/185712/changes#diff-d57f937ed2d743b17635dd069689072eba124f649f307228915c25d55b19ed62.

Issue: flutter#185741
@cbracken
cbracken force-pushed the target-triple-args branch from 5f63773 to 734176e Compare July 10, 2026 03:21
@cbracken cbracken added the autosubmit Merge PR when tree becomes green via auto submit App label Jul 10, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Jul 11, 2026
Merged via the queue into flutter:master with commit f9cc6b0 Jul 11, 2026
202 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jul 11, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Jul 12, 2026
flutter/flutter@f7b66f3...cf9e8af

2026-07-12 [email protected] Flip from deprecated strict analysis modes to lint rules (flutter/flutter#187692)
2026-07-12 [email protected] Roll Skia from 6ecffccd32d5 to 8bf65996caba (5 revisions) (flutter/flutter#189333)
2026-07-11 [email protected] Roll Fuchsia Linux SDK from czpzDg9ABY2oKLAOY... to vhIlDkWIy21IrlB9E... (flutter/flutter#189309)
2026-07-11 [email protected] iOS: clean up swiftc.py after migration to target triples (flutter/flutter#189240)
2026-07-10 [email protected] Increase number of 'Mac tool_integration_tests' subshards from 5 to 10 (flutter/flutter#189040)
2026-07-10 [email protected] Fix PopupWindowControllerLinux missing WindowControllerLinux implementation (flutter/flutter#189189)
2026-07-10 [email protected] [android_hardware_smoke_test] Synchronize platform view compositing (flutter/flutter#189151)
2026-07-10 [email protected] UberSDF thin roundrect handling (flutter/flutter#189224)
2026-07-10 [email protected] Roll Skia from ab3a7b98c94d to 6ecffccd32d5 (15 revisions) (flutter/flutter#189270)
2026-07-10 [email protected] [skwasm][canvaskit] Honor Paint.filterQuality in Canvas.drawAtlas (flutter/flutter#186108)
2026-07-10 [email protected] Android_hardware_smoke_test: Cache flutter engine when running vulkan backend instrumented tests (flutter/flutter#189026)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
cbracken added a commit to cbracken/flutter that referenced this pull request Jul 18, 2026
GN's `--export-compile-commands` only understands its built-in
`cc`/`cxx`/`objc`/`objcxx` tool types, so the custom `swift` tool we use to
invoke `swiftc.py` never shows up in `compile_commands.json`. Swift code
under `flutter/shell/platform/darwin` was therefore invisible to any
tooling that reads that file, including SourceKit-LSP, which is what
drives Swift diagnostics/completion/go-to-definition in VS Code and other
editors.

This adds a post-processing step to `gn gen` that fixes this up. Since
GN's own compdb export omits the swift targets entirely, we now shell out
to `ninja -t compdb` to get the full compilation database instead (falling
back to the existing `compile_commands.json` on disk if that fails), then
rewrite the result in two passes:

* `stripCompilerWrappers` strips the `rewrapper`/`ccache` prefix off
  `clang`/`clang++` invocations, same as before, so `clangd` doesn't choke
  on RBE wrapper commands (flutter#147767).
* `expandSwiftcCommands` turns each `swiftc.py`-wrapped entry into one or
  more native `swiftc` invocations, one per compiled Swift file, with all
  relative paths resolved to absolute against the entry's `directory`.
  This mirrors the argument translation `swiftc.py` itself does
  (`-import-objc-header`, `-whole-module-optimization`,
  `-I`/`-isystem`/`-F`/`-Fsystem`/`-D` mirrored to `-Xcc`, etc.) so
  SourceKit-LSP sees the same flags the real build uses.

Also wires up `.sourcekit-lsp/config.json` and the
`swift.sourcekit-lsp.supported-languages` setting in
`engine.code-workspace`/`engine-workspace.yaml` so VS Code's Swift
extension picks up the generated compdb automatically.

Both regexes in `update_compdb.dart` scan the raw ninja output directly
rather than decoding the full `compile_commands.json`, which can run past
20MB and is slow to parse in Dart; we only `jsonDecode` the handful of
matched `swiftc.py` entries. While tightening this up I found the
`clang`/`clang++` wrapper-stripping regex could match a `clang` substring
anywhere later on the line -- e.g. an `-Xclang` flag, or a source file
whose name happens to contain "clang" -- rather than the actual compiler
token, silently truncating the command. Anchored the match to require
`clang`/`clang++` be preceded by `/` (or start-of-word) and followed by a
word boundary, and added regression tests for both cases.

Pre-factored in flutter#189174 and flutter#189240.
cbracken added a commit to cbracken/flutter that referenced this pull request Jul 18, 2026
GN's `--export-compile-commands` only understands its built-in
`cc`/`cxx`/`objc`/`objcxx` tool types, so the custom `swift` tool we use to
invoke `swiftc.py` never shows up in `compile_commands.json`. Swift code
under `flutter/shell/platform/darwin` was therefore invisible to any
tooling that reads that file, including SourceKit-LSP, which is what
drives Swift diagnostics/completion/go-to-definition in VS Code and other
editors.

This adds a post-processing step to `gn gen` that fixes this up. Since
GN's own compdb export omits the swift targets entirely, we now shell out
to `ninja -t compdb` to get the full compilation database instead (falling
back to the existing `compile_commands.json` on disk if that fails), then
rewrite the result in two passes:

* `stripCompilerWrappers` strips the `rewrapper`/`ccache` prefix off
  `clang`/`clang++` invocations, same as before, so `clangd` doesn't choke
  on RBE wrapper commands (flutter#147767).
* `expandSwiftcCommands` turns each `swiftc.py`-wrapped entry into one or
  more native `swiftc` invocations, one per compiled Swift file, with all
  relative paths resolved to absolute against the entry's `directory`.
  This mirrors the argument translation `swiftc.py` itself does
  (`-import-objc-header`, `-whole-module-optimization`,
  `-I`/`-isystem`/`-F`/`-Fsystem`/`-D` mirrored to `-Xcc`, etc.) so
  SourceKit-LSP sees the same flags the real build uses.

Also wires up `.sourcekit-lsp/config.json` and the
`swift.sourcekit-lsp.supported-languages` setting in
`engine.code-workspace`/`engine-workspace.yaml` so VS Code's Swift
extension picks up the generated compdb automatically.

Both regexes in `update_compdb.dart` scan the raw ninja output directly
rather than decoding the full `compile_commands.json`, which can run past
20MB and is slow to parse in Dart; we only `jsonDecode` the handful of
matched `swiftc.py` entries. While tightening this up I found the
`clang`/`clang++` wrapper-stripping regex could match a `clang` substring
anywhere later on the line -- e.g. an `-Xclang` flag, or a source file
whose name happens to contain "clang" -- rather than the actual compiler
token, silently truncating the command. Anchored the match to require
`clang`/`clang++` be preceded by `/` (or start-of-word) and followed by a
word boundary, and added regression tests for both cases.

A design pass on `update_compdb.dart` also cleaned up a few things:

* Dropped `update_compdb.dart` from the package's public barrel export
  (`engine_build_configs.dart`). Nothing needs it there -- `_postGn()`
  imports it directly as a sibling file, and the tests import
  `package:engine_build_configs/src/update_compdb.dart` rather than the
  barrel -- so exporting it only widened the package's public API for no
  reason.
* `swiftc.py` args now flow as `List<String>` end to end and get quoted
  into a shell command exactly once, at the very end, instead of being
  joined into a string and immediately re-split back into a list to
  resolve paths.
* Replaced the `CommandString` utility class (private constructor, only
  static members) with top-level functions `splitShellWords` and
  `quoteShellWord`.
* `expandSwiftEntry` no longer mutates the `entry` map it's given; it and
  its helpers (`_absolutizeEntryFile`, `_duplicateEntryPerSwiftFile`)
  build fresh maps via spread syntax instead.
* Collapsed `_SwiftCommand`/`_ParsedSwiftCommand`/`_CommandPathResolver`
  -- three classes, each with exactly one call site -- into two
  functions, `_translateSwiftcArgs` and `_resolveCommandPaths`, linked by
  a `_SwiftcTranslation` record typedef instead of a dedicated value
  class.

Pre-factored in flutter#189174 and flutter#189240.
cbracken added a commit to cbracken/flutter that referenced this pull request Jul 18, 2026
GN's `--export-compile-commands` only understands its built-in
`cc`/`cxx`/`objc`/`objcxx` tool types, so the custom `swift` tool we use to
invoke `swiftc.py` never shows up in `compile_commands.json`. Swift code
under `flutter/shell/platform/darwin` was therefore invisible to any
tooling that reads that file, including SourceKit-LSP, which is what
drives Swift diagnostics/completion/go-to-definition in VS Code and other
editors.

This adds a post-processing step to `gn gen` that fixes this up. Since
GN's own compdb export omits the swift targets entirely, we now shell out
to `ninja -t compdb` to get the full compilation database instead (falling
back to the existing `compile_commands.json` on disk if that fails), then
rewrite the result in two passes:

* `stripCompilerWrappers` strips the `rewrapper`/`ccache` prefix off
  `clang`/`clang++` invocations, same as before, so `clangd` doesn't choke
  on RBE wrapper commands (flutter#147767).
* `expandSwiftcCommands` turns each `swiftc.py`-wrapped entry into one or
  more native `swiftc` invocations, one per compiled Swift file, with all
  relative paths resolved to absolute against the entry's `directory`.
  This mirrors the argument translation `swiftc.py` itself does
  (`-import-objc-header`, `-whole-module-optimization`,
  `-I`/`-isystem`/`-F`/`-Fsystem`/`-D` mirrored to `-Xcc`, etc.) so
  SourceKit-LSP sees the same flags the real build uses.

Also wires up `.sourcekit-lsp/config.json` and the
`swift.sourcekit-lsp.supported-languages` setting in
`engine.code-workspace`/`engine-workspace.yaml` so VS Code's Swift
extension picks up the generated compdb automatically.

Both regexes in `update_compdb.dart` scan the raw ninja output directly
rather than decoding the full `compile_commands.json`, which can run past
20MB and is slow to parse in Dart; we only `jsonDecode` the handful of
matched `swiftc.py` entries. While tightening this up I found the
`clang`/`clang++` wrapper-stripping regex could match a `clang` substring
anywhere later on the line -- e.g. an `-Xclang` flag, or a source file
whose name happens to contain "clang" -- rather than the actual compiler
token, silently truncating the command. Anchored the match to require
`clang`/`clang++` be preceded by `/` (or start-of-word) and followed by a
word boundary, and added regression tests for both cases.

A design pass on `update_compdb.dart` also cleaned up a few things:

* Dropped `update_compdb.dart` from the package's public barrel export
  (`engine_build_configs.dart`). Nothing needs it there -- `_postGn()`
  imports it directly as a sibling file, and the tests import
  `package:engine_build_configs/src/update_compdb.dart` rather than the
  barrel -- so exporting it only widened the package's public API for no
  reason.
* `swiftc.py` args now flow as `List<String>` end to end and get quoted
  into a shell command exactly once, at the very end, instead of being
  joined into a string and immediately re-split back into a list to
  resolve paths.
* Replaced the `CommandString` utility class (private constructor, only
  static members) with top-level functions `splitShellWords` and
  `quoteShellWord`.
* `expandSwiftEntry` no longer mutates the `entry` map it's given; it and
  its helpers (`_absolutizeEntryFile`, `_duplicateEntryPerSwiftFile`)
  build fresh maps via spread syntax instead.
* Collapsed `_SwiftCommand`/`_ParsedSwiftCommand`/`_CommandPathResolver`
  -- three classes, each with exactly one call site -- into two
  functions, `_translateSwiftcArgs` and `_resolveCommandPaths`, linked by
  a `_SwiftcTranslation` record typedef instead of a dedicated value
  class.

A correctness pass traced the flag translation against `swiftc.py`'s
actual `ArgumentForwarder` logic (`build/toolchain/darwin/swiftc.py`) and
found two mismatches, both currently dormant since no target in this repo
wires `{{defines}}` or `{{system_include_dirs}}` into the swift tool's GN
command template today, but worth fixing for fidelity:

* `-isystem` was forwarded to `swiftc` itself as a bare flag in addition
  to the `-Xcc -isystem -Xcc <path>` mirror. `swiftc.py`'s
  `IncludeArgumentForwarder` excludes `-isystem` from the swift-side
  forward entirely (`to_swift=lambda _: arg_name != '-isystem'`) -- it's
  clang-only. Fixed in `_resolveCommandPaths` for both the attached and
  separated forms.
* `-D key=value` was forwarded to `swiftc`'s `-D`, which only accepts
  bare conditional-compilation flags. `swiftc.py`'s
  `DefineArgumentForwarder` only forwards to swift when the value has no
  `=`; value-defines go to clang only. Fixed in `_translateSwiftcArgs`.
  Bare flags like `-D FOO` are unaffected.

Also dropped a dead `--fix-module-imports` branch (not an actual
swiftc.py argparse flag -- only `--fix-generated-header` is; the name
only ever existed in a stale docstring), and fixed `splitShellWords` to
preserve an empty quoted argument (`""`/`''`) as an empty-string token
instead of dropping it, which had been silently swallowing the following
flag whenever `-import-objc-header ""` appeared on a real command line.

Pre-factored in flutter#189174 and flutter#189240.
cbracken added a commit to cbracken/flutter that referenced this pull request Jul 18, 2026
GN's `--export-compile-commands` only understands its built-in
`cc`/`cxx`/`objc`/`objcxx` tool types, so the custom `swift` tool we use to
invoke `swiftc.py` never shows up in `compile_commands.json`. Swift code
under `flutter/shell/platform/darwin` was therefore invisible to any
tooling that reads that file, including SourceKit-LSP, which is what
drives Swift diagnostics/completion/go-to-definition in VS Code and other
editors.

This adds a post-processing step to `gn gen` that fixes this up. Since
GN's own compdb export omits the swift targets entirely, we now shell out
to `ninja -t compdb` to get the full compilation database instead (falling
back to the existing `compile_commands.json` on disk if that fails), then
rewrite the result in two passes:

* `stripCompilerWrappers` strips the `rewrapper`/`ccache` prefix off
  `clang`/`clang++` invocations, same as before, so `clangd` doesn't choke
  on RBE wrapper commands (flutter#147767).
* `expandSwiftcCommands` turns each `swiftc.py`-wrapped entry into one or
  more native `swiftc` invocations, one per compiled Swift file, with all
  relative paths resolved to absolute against the entry's `directory`.
  This mirrors the argument translation `swiftc.py` itself does
  (`-import-objc-header`, `-whole-module-optimization`,
  `-I`/`-isystem`/`-F`/`-Fsystem`/`-D` mirrored to `-Xcc`, etc.) so
  SourceKit-LSP sees the same flags the real build uses.

Also wires up `.sourcekit-lsp/config.json` and the
`swift.sourcekit-lsp.supported-languages` setting in
`engine.code-workspace`/`engine-workspace.yaml` so VS Code's Swift
extension picks up the generated compdb automatically.

Both regexes in `update_compdb.dart` scan the raw ninja output directly
rather than decoding the full `compile_commands.json`, which can run past
20MB and is slow to parse in Dart; we only `jsonDecode` the handful of
matched `swiftc.py` entries. While tightening this up I found the
`clang`/`clang++` wrapper-stripping regex could match a `clang` substring
anywhere later on the line -- e.g. an `-Xclang` flag, or a source file
whose name happens to contain "clang" -- rather than the actual compiler
token, silently truncating the command. Anchored the match to require
`clang`/`clang++` be preceded by `/` (or start-of-word) and followed by a
word boundary, and added regression tests for both cases.

A design pass on `update_compdb.dart` also cleaned up a few things:

* Dropped `update_compdb.dart` from the package's public barrel export
  (`engine_build_configs.dart`). Nothing needs it there -- `_postGn()`
  imports it directly as a sibling file, and the tests import
  `package:engine_build_configs/src/update_compdb.dart` rather than the
  barrel -- so exporting it only widened the package's public API for no
  reason.
* `swiftc.py` args now flow as `List<String>` end to end and get quoted
  into a shell command exactly once, at the very end, instead of being
  joined into a string and immediately re-split back into a list to
  resolve paths.
* Replaced the `CommandString` utility class (private constructor, only
  static members) with top-level functions `splitShellWords` and
  `quoteShellWord`.
* `expandSwiftEntry` no longer mutates the `entry` map it's given; it and
  its helpers (`_absolutizeEntryFile`, `_duplicateEntryPerSwiftFile`)
  build fresh maps via spread syntax instead.
* Collapsed `_SwiftCommand`/`_ParsedSwiftCommand`/`_CommandPathResolver`
  -- three classes, each with exactly one call site -- into two
  functions, `_translateSwiftcArgs` and `_resolveCommandPaths`, linked by
  a `_SwiftcTranslation` record typedef instead of a dedicated value
  class.

A correctness pass traced the flag translation against `swiftc.py`'s
actual `ArgumentForwarder` logic (`build/toolchain/darwin/swiftc.py`) and
found two mismatches, both currently dormant since no target in this repo
wires `{{defines}}` or `{{system_include_dirs}}` into the swift tool's GN
command template today, but worth fixing for fidelity:

* `-isystem` was forwarded to `swiftc` itself as a bare flag in addition
  to the `-Xcc -isystem -Xcc <path>` mirror. `swiftc.py`'s
  `IncludeArgumentForwarder` excludes `-isystem` from the swift-side
  forward entirely (`to_swift=lambda _: arg_name != '-isystem'`) -- it's
  clang-only. Fixed in `_resolveCommandPaths` for both the attached and
  separated forms, and consolidated into a single named `isClangOnly()`
  check instead of three separate comparisons, so the same class of bug
  (a special case duplicated instead of centralized) can't creep back in.
* `-D key=value` was forwarded to `swiftc`'s `-D`, which only accepts
  bare conditional-compilation flags. `swiftc.py`'s
  `DefineArgumentForwarder` only forwards to swift when the value has no
  `=`; value-defines go to clang only. Fixed in `_translateSwiftcArgs`.
  Bare flags like `-D FOO` are unaffected.

Also dropped a dead `--fix-module-imports` branch (not an actual
swiftc.py argparse flag -- only `--fix-generated-header` is; the name
only ever existed in a stale docstring), and fixed `splitShellWords` to
preserve an empty quoted argument (`""`/`''`) as an empty-string token
instead of dropping it, which had been silently swallowing the following
flag whenever `-import-objc-header ""` appeared on a real command line.

Ran `dart format` for the first time (fixed a missing blank line between
import groups) and grouped the test file's 15 tests by the function they
exercise now that it's grown past being easy to scan as a flat list.

Pre-factored in flutter#189174 and flutter#189240.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD engine flutter/engine related. See also e: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants