You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On Xcode 26.3 + InjectionNext 2.0.0RC5, hot-reload from a pure xcodebuild-CLI workflow is broken at an architectural level. Even with Patch Compiler correctly applied AND all three documented build flags set, the feedcommands call inside the swift-frontend wrapper is never reached, so the compile-command cache (/tmp/InjectionNext_iPhoneSimulator_builds.json.gz) never updates for the current build. Saves never produce /tmp/injectionNext_*.o and the RC5 console reports Could not locate command for <file>. InjectionNext is not compatible with "Whole Module" Compilation Mode. (the warning text is misleading — SWIFT_COMPILATION_MODE is singlefile).
Build succeeds. 513 swift-frontend command lines emitted to log, ~358 of them -frontend -c -primary-file …. swift-frontend.save subprocesses are observable in ps during build.
Result: json.gz mtime DID NOT advance. New .swift files (e.g. a freshly-created MyView.swift) are NOT in the cache. Saving any file produces no /tmp/injectionNext_*.o. RC5 console shows the "Could not locate command" warning.
Re-points the swift- symlinks (swift, swiftc, swift-api-digester, swift-cache-tool, swift-symbolgraph-extract) to → swift-frontend.save* (the original), deliberately bypassing the wrapper.
(That last one is the only symlink still routing through the wrapper.)
This was sensible pre-Xcode-26 when Xcode invoked swift-frontend directly. But Xcode 26.3 uses builtin-SwiftDriver, which invokes swiftc directly. Through the symlink, that resolves straight to swift-frontend.save — the wrapper is never executed and feedcommands is never called. The compile cache never learns about the current build.
The xcactivitylog fallback path in InjectionLite/Sources/InjectionLite/LogParser.swift also fails on this configuration: xcodebuild from CLI on Xcode 26.3 emits a ~479-byte effectively-empty xcactivitylog, with no -primary-file lines and no builtin-Swift-Compilation lines that the v26.3 fallback grep can match.
What I tried (didn't work)
SWIFT_USE_INTEGRATED_DRIVER=NO — Xcode rejects it on this project: "Enabling Swift explicit modules also requires: SWIFT_USE_INTEGRATED_DRIVER". Targets require explicit modules; circular dependency.
Setting all three documented flags (COMPILATION_CACHE_ENABLE_CACHING=NO, CLANG_CACHE_FINE_GRAINED_OUTPUTS=NO, EMIT_FRONTEND_COMMAND_LINES=YES) — flags applied successfully but the wrapper still isn't reached because the bypass is at symlink-resolution time, not at cache time.
Re-applying Patch Compiler (multiple times) — the wrapper is correctly installed each time; the symlink-bypass is by design.
Downgrading to InjectionNext 1.6.0 — same compile-discovery code (PR Xcode26.3 #125 shipped in both), so same gap.
feedcommands.log is not a useful diagnostic for this issue, by the way — feedcommands is silent on both success and most failure paths. The reliable diagnostic is /tmp/InjectionNext_iPhoneSimulator_builds.json.gz mtime: if it doesn't advance after a build, the wrapper isn't reaching feedcommands.
Question for maintainers
What's the intended xcodeless flow on Xcode 26.3? Specifically:
Is the swiftc → swift-frontend.save symlink redirect intentional on Xcode 26+? If so, how is feedcommands supposed to capture commands when builtin-SwiftDriver invokes swiftc instead of swift-frontend?
Would re-pointing swiftc → swift-frontend (the wrapper) and creating a swiftc.save → swift-frontend.save symlink be a viable patch shape, or does it break driver-mode invocations? (Specifically for cases where swiftc is invoked without -frontend.)
Is the LogParser.swiftxCode26_3 fallback expected to handle CLI xcodebuild builds? Empirically the xcactivitylog from CLI builds is ~479 bytes with no usable per-file lines — happy to attach a sample if useful.
I'm happy to test patch candidates on this project — it's a real-world large workspace (CocoaPods + SPM, ~500 swift-frontend invocations per clean build) and reliably reproduces the gap. cc @maatheusgois-dd@johnno1962
Summary
On Xcode 26.3 + InjectionNext 2.0.0RC5, hot-reload from a pure
xcodebuild-CLI workflow is broken at an architectural level. Even with Patch Compiler correctly applied AND all three documented build flags set, thefeedcommandscall inside the swift-frontend wrapper is never reached, so the compile-command cache (/tmp/InjectionNext_iPhoneSimulator_builds.json.gz) never updates for the current build. Saves never produce/tmp/injectionNext_*.oand the RC5 console reportsCould not locate command for <file>. InjectionNext is not compatible with "Whole Module" Compilation Mode.(the warning text is misleading —SWIFT_COMPILATION_MODEissinglefile).Environment
@ObserveInjection+.enableInjection())xcodebuildCLI, app launched on simulator withSIMCTL_CHILD_DYLD_INSERT_LIBRARIESpointing atiOSInjection.bundle.SWIFT_ENABLE_EXPLICIT_MODULES=YES(required by targets).Reproduction
/tmp/feedcommands.logand note the mtime/size of/tmp/InjectionNext_iPhoneSimulator_builds.json.gz.xcodebuildwith all three flags:swift-frontendcommand lines emitted to log, ~358 of them-frontend -c -primary-file ….swift-frontend.savesubprocesses are observable inpsduring build.json.gzmtime DID NOT advance. New.swiftfiles (e.g. a freshly-createdMyView.swift) are NOT in the cache. Saving any file produces no/tmp/injectionNext_*.o. RC5 console shows the "Could not locate command" warning.Root cause (verified empirically)
RC5's "Patch Compiler" performs three actions:
swift-frontend(binary) →swift-frontend.save.swift-frontend.shas newswift-frontend.swift,swiftc,swift-api-digester,swift-cache-tool,swift-symbolgraph-extract) to →swift-frontend.save* (the original), deliberately bypassing the wrapper.Confirmed by
ls -la:(That last one is the only symlink still routing through the wrapper.)
This was sensible pre-Xcode-26 when Xcode invoked
swift-frontenddirectly. But Xcode 26.3 usesbuiltin-SwiftDriver, which invokesswiftcdirectly. Through the symlink, that resolves straight toswift-frontend.save— the wrapper is never executed andfeedcommandsis never called. The compile cache never learns about the current build.The xcactivitylog fallback path in
InjectionLite/Sources/InjectionLite/LogParser.swiftalso fails on this configuration:xcodebuildfrom CLI on Xcode 26.3 emits a ~479-byte effectively-empty xcactivitylog, with no-primary-filelines and nobuiltin-Swift-Compilationlines that the v26.3 fallback grep can match.What I tried (didn't work)
SWIFT_USE_INTEGRATED_DRIVER=NO— Xcode rejects it on this project: "Enabling Swift explicit modules also requires: SWIFT_USE_INTEGRATED_DRIVER". Targets require explicit modules; circular dependency.COMPILATION_CACHE_ENABLE_CACHING=NO,CLANG_CACHE_FINE_GRAINED_OUTPUTS=NO,EMIT_FRONTEND_COMMAND_LINES=YES) — flags applied successfully but the wrapper still isn't reached because the bypass is at symlink-resolution time, not at cache time.feedcommands.logis not a useful diagnostic for this issue, by the way — feedcommands is silent on both success and most failure paths. The reliable diagnostic is/tmp/InjectionNext_iPhoneSimulator_builds.json.gzmtime: if it doesn't advance after a build, the wrapper isn't reaching feedcommands.Question for maintainers
What's the intended xcodeless flow on Xcode 26.3? Specifically:
swiftc → swift-frontend.savesymlink redirect intentional on Xcode 26+? If so, how isfeedcommandssupposed to capture commands when builtin-SwiftDriver invokesswiftcinstead ofswift-frontend?swiftc → swift-frontend(the wrapper) and creating aswiftc.save → swift-frontend.savesymlink be a viable patch shape, or does it break driver-mode invocations? (Specifically for cases whereswiftcis invoked without-frontend.)LogParser.swiftxCode26_3fallback expected to handle CLIxcodebuildbuilds? Empirically the xcactivitylog from CLI builds is ~479 bytes with no usable per-file lines — happy to attach a sample if useful.I'm happy to test patch candidates on this project — it's a real-world large workspace (CocoaPods + SPM, ~500 swift-frontend invocations per clean build) and reliably reproduces the gap. cc @maatheusgois-dd @johnno1962