Hello, Swift Evolution!
I'd like us to consider the following addition to the Swift Package Manager APIs.
Introduction
The current Swift Package Manager build system is currently hardcoded to pass the -enable-testing
flag to the Swift compiler to enable @testable import
when building in debug mode.
Swift-evolution thread: Pitch: [SwiftPM] @testable build setting
Motivation
Not all targets in a given package make use of the @testable import
feature (or wish to use it at all), but all targets are presently forced to build their code with this support enabled regardless of whether it's needed.
Developers should be able to disable @testable import
when it's not needed or desired, just as they're able to do so in Xcode's build system.
On Windows in particular, where a shared library is limited to 65k exported symbols, disabling @testable import
provides developers an option to significantly reduce the exported symbol count of a library by hiding all of the unnecessary internal APIs. It can also improve debug build performance as fewer symbols exported from a binary can result in faster linking.
Proposed solution
Add a new Swift target setting API to specify whether testing should be enabled for the specified target, falling back to the current behavior by default.
Detailed design
Add a new enableTesting
API to SwiftSetting
limited to manifests >= 6.1:
public struct SwiftSetting {
// ... other settings
@available(_PackageDescription, introduced: 6.1)
public static func enableTesting(
_ enable: Bool,
_ condition: BuildSettingCondition? = nil
) -> SwiftSetting {
...
}
}
The existing --enable-testable-imports
/ --disable-testable-imports
command line flag to swift-test
currently defaults to --enable-testable-imports
. It will be changed to default to "unspecified" (respecting any target settings), and explicitly passing --enable-testable-imports
or --disable-testable-imports
will force all targets to enable or disable testing, respectively.
Security
New language version setting has no implications on security, safety or privacy.
Impact on existing packages
Since this is a new API, all existing packages will use the default behavior - testing will be enabled when building for the debug configuration, and disabled when building for the release configuration.
Alternatives considered
None.