What changed
- Added
PackageInfo decoding and encoding support for SwiftPM warning-control target build settings: treatAllWarnings, treatWarning, and enableWarning.
- Mapped the decoded settings into Tuist’s generated Xcode settings using the same build setting declarations and flags that SwiftPM uses.
- Updated the package dependency extraction switches so linker-only dependency collection ignores these warning-control settings instead of becoming non-exhaustive.
- Added focused tests for decoding the new SwiftPM
kind JSON payloads and for mapping every supported Swift, C, and C++ warning-control level.
Fixes #8543.
Why
Point-Free’s swift-dependencies 1.13.0 started using newer SwiftPM warning-control APIs in Package.swift. With recent SwiftPM output, those APIs appear in swift package dump-package as kind payloads such as treatAllWarnings, treatWarning, and enableWarning.
Tuist already understands the Xcode 14+ kind format for many target build settings, but it did not know these newer warning-control cases. As a result, loading packages that emit them failed during PackageInfo decoding before Tuist could map the package graph into Xcode projects.
Root cause
The decoder in PackageInfo.Target.TargetBuildSettingDescription.Setting only modeled the existing SwiftPM build setting cases. When SwiftPM emitted a target setting like:
{
"kind": {
"treatAllWarnings": {
"_0": "error"
}
},
"tool": "swift"
}
Tuist could not decode it into a known SettingName, which surfaced as a target build setting decoding failure.
Why this approach
I checked SwiftPM’s current PackageBuilder implementation and its warning-control tests, then mirrored that behavior in Tuist instead of inventing separate Xcode settings. SwiftPM deliberately lowers these APIs into OTHER_*FLAGS, including Swift warning controls, so Tuist now does the same.
| SwiftPM setting |
Tool |
Xcode setting |
Flags |
treatAllWarnings(.error/.warning) |
Swift |
OTHER_SWIFT_FLAGS |
-warnings-as-errors / -no-warnings-as-errors |
treatAllWarnings(.error/.warning) |
C/C++ |
OTHER_CFLAGS / OTHER_CPLUSPLUSFLAGS |
-Werror / -Wno-error |
treatWarning(name, .error/.warning) |
Swift |
OTHER_SWIFT_FLAGS |
-Werror name / -Wwarning name |
treatWarning(name, .error/.warning) |
C/C++ |
OTHER_CFLAGS / OTHER_CPLUSPLUSFLAGS |
-Werror=name / -Wno-error=name |
enableWarning(name) |
C/C++ only |
OTHER_CFLAGS / OTHER_CPLUSPLUSFLAGS |
-Wname |
The main alternative would have been to map all-warning controls to broad Xcode warning build settings where possible, but that would diverge from SwiftPM and would not represent the per-warning Swift cases correctly. Keeping the mapping flag-based also preserves the exact warning names coming from package manifests.
Impact
Users can load packages that use SwiftPM’s newer warning-control APIs, including swift-dependencies 1.13.0, without Tuist failing during package decoding. The generated Xcode projects preserve the package author’s warning behavior for supported Swift, C, and C++ settings.
Unsupported combinations remain explicit. For example, linker warning-control settings and Swift enableWarning are still rejected because SwiftPM itself does not support those combinations.
Testing
swiftformat cli/Sources/TuistLoader/SwiftPackageManager/SettingsMapper.swift cli/Tests/TuistLoaderTests/SwiftPackageManager/SettingsMapperTests.swift
git diff --check
xcodebuild test -workspace Tuist.xcworkspace -scheme TuistUnitTests '-only-testing:XcodeGraphTests/PackageInfoTests/packageInfo_decodesWarningControlSettings()' '-only-testing:TuistLoaderTests/SettingsMapperTests/test_set_warning_control_settings' CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY=""