-
Notifications
You must be signed in to change notification settings - Fork 40
Description
Multiple Runtime Issues with swift-subprocess on macOS 26 / Swift 6.2
Summary
Swift projects using swift-subprocess
encounter two distinct runtime issues on macOS 26 with Swift 6.2:
- Debug builds: Fail at runtime with dyld error about missing
libswiftCompatibilitySpan.dylib
- Release builds: Hang indefinitely during subprocess execution (even after fixing the dyld issue)
These issues occur with both the latest main branch and the stable 0.1.0 release of swift-subprocess.
Environment
- macOS: Tahoe 26 (Apple Silicon)
- Swift Version: 6.2 (multiple toolchains tested)
- Swiftly-provided:
Apple Swift version 6.2 (swift-6.2-RELEASE)
- Xcode-provided:
Apple Swift version 6.2 (swiftlang-6.2.0.19.9 clang-1700.3.19.1)
- Swiftly-provided:
- Xcode: 26.0.1
- Package Manager: Swift Package Manager 6.0
- Target Platform: macOS 13.0+
Error Details
Issue 1: Debug Build Runtime Error (SOLVED)
dyld[PID]: Library not loaded: @rpath/libswiftCompatibilitySpan.dylib
Referenced from: <UUID> /path/to/project/.build/arm64-apple-macosx/debug/ExecutableName
Reason: tried: '/path/to/project/.build/arm64-apple-macosx/debug/libswiftCompatibilitySpan.dylib' (no such file),
'/path/to/project/.build/arm64-apple-macosx/debug/libswiftCompatibilitySpan.dylib' (no such file),
'/usr/local/lib/libswiftCompatibilitySpan.dylib' (no such file),
'/usr/lib/libswiftCompatibilitySpan.dylib' (no such file, not in dyld cache)
Status: ✅ SOLVED - Fixed by setting Swift tools version to 6.2 and platform target to macOS(.v26)
Issue 2: Release Build Infinite Hang (UNSOLVED)
After fixing the dyld issue, release builds (swift build -c release
) hang indefinitely when executing subprocess commands. The executable never completes and must be force-killed.
Status: ❌ BLOCKING - This prevents deployment of release binaries
Build Behavior
- Compilation: Both debug and release builds compile successfully without errors
- Debug runtime: Works correctly after applying the platform target fix
- Release runtime: Hangs indefinitely during subprocess execution
Reproduction Steps
For Issue 1 (dyld error with debug builds):
- Create a new Swift package with Swift tools version 6.0 and platform
macOS(.v13)
- Add swift-subprocess as a dependency (either main branch or 0.1.0 release)
- Create a simple executable that uses Subprocess:
import Subprocess
@main
struct TestApp {
static func main() async throws {
let result = try await Subprocess.run(.name("echo"), arguments: ["hello"])
print(result.standardOutput ?? "")
}
}
- Build and run:
swift run TestApp
Expected: Program runs and prints "hello"
Actual: Runtime error about missing libswiftCompatibilitySpan.dylib
For Issue 2 (release build hang):
- Apply the fix for Issue 1: Set Swift tools version to 6.2 and platform to
macOS(.v26)
- Build in release mode:
swift build -c release
- Run the release binary:
./.build/release/TestApp
Expected: Program runs and prints "hello"
Actual: Program hangs indefinitely and never completes
Investigation
Package.swift Configurations Tested
Configuration causing Issue 1 (dyld error):
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "TestProject",
platforms: [.macOS(.v13)], // ❌ Causes dyld error
dependencies: [
.package(url: "https://github.com/swiftlang/swift-subprocess.git", branch: "main")
],
targets: [
.executableTarget(
name: "TestApp",
dependencies: [
.product(name: "Subprocess", package: "swift-subprocess")
]
)
]
)
Configuration that fixes Issue 1 but causes Issue 2:
// swift-tools-version: 6.2 // ✅ Required for macOS(.v26)
import PackageDescription
let package = Package(
name: "TestProject",
platforms: [.macOS(.v26)], // ✅ Fixes dyld, ❌ causes release hang
dependencies: [
.package(url: "https://github.com/swiftlang/swift-subprocess.git", branch: "main")
],
targets: [
.executableTarget(
name: "TestApp",
dependencies: [
.product(name: "Subprocess", package: "swift-subprocess")
]
)
]
)
Attempted Workarounds
For Issue 1 (dyld error):
- Different Swift toolchains: Tested both swiftly-managed and Xcode-provided Swift 6.2 toolchains - ❌ No effect
- Package versions: Tested both main branch and 0.1.0 stable release - ❌ No effect
- Custom defines: Attempted to disable Span with
DISABLE_SUBPROCESS_SPAN
compiler flag - ❌ No effect - Package traits: Attempted to specify traits (not available in SPM 6.0) - ❌ Not supported
- Platform target update: Changed from
macOS(.v13)
tomacOS(.v26)
- ✅ SOLVED Issue 1
For Issue 2 (release hang):
- Different subprocess commands: Tested with
echo
,ls
,tar
- ❌ All hang - Timeout configurations: Added custom timeouts to subprocess calls - ❌ Still hangs
- Different output configurations: Tested
.string()
,.data()
,.discarded
- ❌ Still hangs
No workaround found for Issue 2 - Release builds remain unusable.
Analysis
Issue 1 Analysis (SOLVED)
The dyld error occurs because swift-subprocess tries to use Swift 6.2's new Span APIs through a compatibility library (libswiftCompatibilitySpan.dylib
) when targeting older macOS versions. This was fixed in Swift Package Manager PR #9164, which adds proper rpaths for the span compatibility library when targeting macOS < 26.
Root cause: Platform target mismatch between Swift 6.2 toolchain and older macOS target
Solution: Use macOS(.v26)
platform target with Swift tools version 6.2
Issue 2 Analysis (UNSOLVED)
The release build hanging issue is exactly the same as described in swift-subprocess issue #182. Debug builds work correctly, but release builds hang indefinitely during subprocess execution.
Root cause: Unknown optimization-related issue in release builds
Impact: Prevents production deployment of applications using swift-subprocess
Span Trait Behavior
Based on the swift-subprocess documentation, the package offers two traits:
SubprocessFoundation
: Default, includes Foundation dependencySubprocessSpan
: Uses RawSpan-based APIs, enabled automatically when RawSpan is available
The library automatically enables SubprocessSpan
on Swift 6.2, which triggers both issues.
Expected Behavior
-
For Issue 1 (dyld error):
- ✅ RESOLVED - Developers should use
macOS(.v26)
platform target with Swift 6.2 - Documentation should clearly state this requirement
- ✅ RESOLVED - Developers should use
-
For Issue 2 (release hang):
- Release builds should work as reliably as debug builds
- Subprocess execution should complete successfully in all build configurations
- The package should provide guidance on release build compatibility
-
General expectations:
- Clear documentation about Swift 6.2 and macOS 26 requirements
- Explicit configuration options to disable Span support if needed
- Reliable behavior across debug and release builds
Current Status & Workarounds
Issue 1 (dyld error): ✅ SOLVED
Workaround: Update Package.swift to use Swift tools version 6.2 and platform target macOS(.v26)
Issue 2 (release hang): ❌ BLOCKING
No viable workaround - Options are:
- Use only debug builds (not suitable for production)
- Implement subprocess functionality using Foundation's
Process
class - Wait for a fix to issue Swift Subprocess hangs in release builds but works in debug builds #182
Related Issues
- swift-subprocess #182 - Identical release build hanging issue
- swift-subprocess #183 - Related testing failures with libswiftCompatibilitySpan
- swift-subprocess #189 - Same dyld error (resolved by platform target fix)
- swift-package-manager #9163 - SPM fix for Span compatibility (merged)
Additional Context
Issue 2 (release hang) blocks production deployment of swift-subprocess applications. While Issue 1 has been resolved, the release build hanging problem makes the library unsuitable for production use on macOS 26 with Swift 6.2.
This appears to be an optimization-related bug where release builds hang during subprocess execution, while debug builds work correctly. The issue affects all subprocess operations regardless of the command being executed or output configuration.
Immediate impact: Developers using swift-subprocess must either:
- Ship debug builds (poor performance, not production-ready)
- Switch to Foundation's Process class
- Delay deployment until the hanging issue is resolved
The automatic Span trait detection in Swift 6.2 environments may be contributing to both issues, suggesting the need for more explicit trait configuration options.