|
7 | 7 | * Implementation: [swiftlang/swift-package-manager#8315](https://github.com/swiftlang/swift-package-manager/pull/8315)
|
8 | 8 | * Review: ([pitch](https://forums.swift.org/t/pitch-warning-control-settings-for-swiftpm/78666)) ([review](https://forums.swift.org/t/se-0480-warning-control-settings-for-swiftpm/79475)) ([returned for revision](https://forums.swift.org/t/se-0480-warning-control-settings-for-swiftpm/79475/8))
|
9 | 9 | * Previous Proposal: [SE-0443](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0443-warning-control-flags.md)
|
| 10 | +* Previous revisions: [1](https://github.com/swiftlang/swift-evolution/blob/eed1fed8339f3919cf5c0f36b804431022d44720/proposals/0480-swiftpm-warning-control.md) |
10 | 11 |
|
11 | 12 | ## Introduction
|
12 | 13 |
|
@@ -38,32 +39,36 @@ public enum WarningLevel: String {
|
38 | 39 | case error
|
39 | 40 | }
|
40 | 41 |
|
41 |
| -public static func treatAllWarnings( |
42 |
| - as level: WarningLevel, |
43 |
| - _ condition: BuildSettingCondition? = nil |
44 |
| -) -> SwiftSetting // or CSetting or CXXSetting |
45 |
| - |
46 |
| -public static func treatWarning( |
47 |
| - _ name: String, |
48 |
| - as level: WarningLevel, |
49 |
| - _ condition: BuildSettingCondition? = nil |
50 |
| -) -> SwiftSetting // or CSetting or CXXSetting |
| 42 | +extension SwiftSetting { // Same for CSetting and CXXSetting |
| 43 | + public static func treatAllWarnings( |
| 44 | + as level: WarningLevel, |
| 45 | + _ condition: BuildSettingCondition? = nil |
| 46 | + ) -> SwiftSetting // or CSetting or CXXSetting |
| 47 | + |
| 48 | + public static func treatWarning( |
| 49 | + _ name: String, |
| 50 | + as level: WarningLevel, |
| 51 | + _ condition: BuildSettingCondition? = nil |
| 52 | + ) -> SwiftSetting // or CSetting or CXXSetting |
| 53 | +} |
51 | 54 | ```
|
52 | 55 |
|
53 | 56 | #### C/C++-specific API
|
54 | 57 |
|
55 | 58 | In C/C++ targets, we can also enable or disable specific warning groups, in addition to controlling their severity.
|
56 | 59 |
|
57 | 60 | ```swift
|
58 |
| -public static func enableWarning( |
59 |
| - _ name: String, |
60 |
| - _ condition: BuildSettingCondition? = nil |
61 |
| -) -> CSetting // or CXXSetting |
62 |
| - |
63 |
| -public static func disableWarning( |
64 |
| - _ name: String, |
65 |
| - _ condition: BuildSettingCondition? = nil |
66 |
| -) -> CSetting // or CXXSetting |
| 61 | +extension CSetting { // Same for CXXSetting |
| 62 | + public static func enableWarning( |
| 63 | + _ name: String, |
| 64 | + _ condition: BuildSettingCondition? = nil |
| 65 | + ) -> CSetting // or CXXSetting |
| 66 | + |
| 67 | + public static func disableWarning( |
| 68 | + _ name: String, |
| 69 | + _ condition: BuildSettingCondition? = nil |
| 70 | + ) -> CSetting // or CXXSetting |
| 71 | +} |
67 | 72 | ```
|
68 | 73 | _The necessity of these functions is also explained below in the Alternatives considered section._
|
69 | 74 |
|
@@ -280,6 +285,53 @@ This necessitates separate functions to enable and disable warnings. Therefore,
|
280 | 285 |
|
281 | 286 | It has been noted that warning control settings are often similar across all targets. It makes sense to declare them at the package level while allowing target-level customizations. However, many other settings would also likely benefit from such inheritance, and SwiftPM doesn't currently provide such an option. Therefore, it was decided to factor this improvement out and look at all the settings holistically in the future.
|
282 | 287 |
|
| 288 | +### Support for other C/C++ Compilers |
| 289 | + |
| 290 | +The C/C++ warning control settings introduced in this proposal are initially implemented with Clang's warning flag syntax as the primary target. However, the API itself is largely compiler-agnostic, and there's potential to extend support to other C/C++ compilers in the future. |
| 291 | + |
| 292 | +For instance, many of the proposed functions could be mapped to flags for other compilers like MSVC: |
| 293 | + |
| 294 | +| SwiftPM Setting | Clang | MSVC (Potential Mapping) | |
| 295 | +| :-------------------------------- | :---------------- | :----------------------- | |
| 296 | +| `.treatAllWarnings(as: .error)` | `-Werror` | `/WX` | |
| 297 | +| `.treatAllWarnings(as: .warning)` | `-Wno-error` | `/WX-` | |
| 298 | +| `.treatWarning("name", as: .error)`| `-Werror=name` | `/we####` (where `####` is MSVC warning code) | |
| 299 | +| `.treatWarning("name", as: .warning)`| `-Wno-error=name` | No direct equivalent | |
| 300 | +| `.enableWarning("name")` | `-Wname` | `/wL####` (e.g., `/w4####` to enable at level 4) | |
| 301 | +| `.disableWarning("name")` | `-Wno-name` | `/wd####` | |
| 302 | + |
| 303 | +Where direct mappings are incomplete (like `.treatWarning(as: .warning)` for MSVC, which doesn't have a per-warning equivalent to Clang's `-Wno-error=XXXX`), SwiftPM could emit diagnostics indicating the setting is not fully supported by the current compiler. If more fine-grained control is needed for a specific compiler (e.g., MSVC's warning levels `0-4` for `enableWarning`), future enhancements could introduce compiler-specific settings or extend the existing API. |
| 304 | + |
| 305 | +A key consideration is the handling of warning names or codes (the `"name"` parameter in the API). SwiftPM does not maintain a comprehensive list of all possible warning identifiers and their mapping across different compilers. Instead, package authors would be responsible for providing the correct warning name or code for the intended compiler. |
| 306 | + |
| 307 | +To facilitate this, if support for other C/C++ compilers is added, the existing `BuildSettingCondition` API could be extended to allow settings to be applied conditionally based on the active C/C++ compiler. For example: |
| 308 | + |
| 309 | +```swift |
| 310 | +cxxSettings: [ |
| 311 | + // Clang-specific warning |
| 312 | + .enableWarning("unused-variable", .when(cxxCompiler: .clang)), |
| 313 | + // MSVC-specific warning (using its numeric code) |
| 314 | + .enableWarning("4101", .when(cxxCompiler: .msvc)), |
| 315 | + // Common setting that maps well |
| 316 | + .treatAllWarnings(as: .error) |
| 317 | +] |
| 318 | +``` |
| 319 | + |
| 320 | +This approach, combined with the existing behavior where remote (dependency) packages have their warning control flags stripped and replaced with suppression flags, would allow projects to adopt new compilers. Even if a dependency uses Clang-specific warning flags, it would not cause build failures when the main project is built with a different compiler like MSVC, as those flags would be ignored. |
| 321 | + |
| 322 | +### Formalizing "Development-Only" Build Settings |
| 323 | + |
| 324 | +The warning control settings introduced by this proposal only apply when a package is built directly and are suppressed when the package is consumed as a remote dependency. |
| 325 | + |
| 326 | +During the review of this proposal, it was suggested that this "development-only" characteristic could be made more explicit, perhaps by introducing a distinct category of settings (e.g., `devSwiftSettings`). This is an interesting avenue for future exploration. SwiftPM already has a few other settings that exhibit similar behavior. A dedicated future proposal for "development-only" settings could address all such use cases holistically, providing a clearer and more general mechanism for package authors to distinguish between "dev-only" settings and those that propagate to consumers. |
| 327 | + |
| 328 | +## Revision History |
| 329 | + |
| 330 | +Revisions based on review feedback: |
| 331 | + |
| 332 | +- Added a future direction discussing potential support for C/C++ compilers beyond Clang. |
| 333 | +- Added a future direction to explore formalizing "dev-only" build settings. |
| 334 | + |
283 | 335 | ## Acknowledgments
|
284 | 336 |
|
285 | 337 | Thank you to [Doug Gregor](https://github.com/douggregor) for the motivation, and to both [Doug Gregor](https://github.com/douggregor) and [Holly Borla](https://github.com/hborla) for their guidance during the implementation of this API.
|
0 commit comments