@@ -73,6 +73,12 @@ struct BuildCommandOptions: ParsableArguments {
7373 @Flag ( help: " Build both source and test targets " )
7474 var buildTests : Bool = false
7575
76+ /// Whether to enable code coverage.
77+ @Flag ( name: . customLong( " code-coverage " ) ,
78+ inversion: . prefixedEnableDisable,
79+ help: " Enable code coverage " )
80+ var enableCodeCoverage : Bool = false
81+
7682 /// If the binary output path should be printed.
7783 @Flag ( name: . customLong( " show-bin-path " ) , help: " Print the binary output path " )
7884 var shouldPrintBinPath : Bool = false
@@ -148,9 +154,20 @@ package struct SwiftBuildCommand: AsyncSwiftCommand {
148154 guard let subset = options. buildSubset ( observabilityScope: swiftCommandState. observabilityScope) else {
149155 throw ExitCode . failure
150156 }
157+
158+ var productsBuildParameters = try swiftCommandState. productsBuildParameters
159+ var toolsBuildParameters = try swiftCommandState. toolsBuildParameters
160+
161+ // Clean out the code coverage directory that may contain stale
162+ // profraw files from a previous run of the code coverage tool.
163+ if self . options. enableCodeCoverage {
164+ try swiftCommandState. fileSystem. removeFileTree ( swiftCommandState. productsBuildParameters. codeCovPath)
165+ productsBuildParameters. testingParameters. enableCodeCoverage = true
166+ toolsBuildParameters. testingParameters. enableCodeCoverage = true
167+ }
168+
151169 if case . allIncludingTests = subset {
152- var buildParameters = try swiftCommandState. productsBuildParameters
153- for library in try options. testLibraryOptions. enabledTestingLibraries ( swiftCommandState: swiftCommandState) {
170+ func updateTestingParameters( of buildParameters: inout BuildParameters , library: BuildParameters . Testing . Library ) {
154171 buildParameters. testingParameters = . init(
155172 configuration: buildParameters. configuration,
156173 targetTriple: buildParameters. triple,
@@ -161,18 +178,28 @@ package struct SwiftBuildCommand: AsyncSwiftCommand {
161178 testEntryPointPath: globalOptions. build. testEntryPointPath,
162179 library: library
163180 )
164- try build ( swiftCommandState, subset: subset, buildParameters: buildParameters)
181+ }
182+ for library in try options. testLibraryOptions. enabledTestingLibraries ( swiftCommandState: swiftCommandState) {
183+ updateTestingParameters ( of: & productsBuildParameters, library: library)
184+ updateTestingParameters ( of: & toolsBuildParameters, library: library)
185+ try build ( swiftCommandState, subset: subset, productsBuildParameters: productsBuildParameters, toolsBuildParameters: toolsBuildParameters)
165186 }
166187 } else {
167- try build ( swiftCommandState, subset: subset)
188+ try build ( swiftCommandState, subset: subset, productsBuildParameters : productsBuildParameters , toolsBuildParameters : toolsBuildParameters )
168189 }
169190 }
170191
171- private func build( _ swiftCommandState: SwiftCommandState , subset: BuildSubset , buildParameters: BuildParameters ? = nil ) throws {
192+ private func build(
193+ _ swiftCommandState: SwiftCommandState ,
194+ subset: BuildSubset ,
195+ productsBuildParameters: BuildParameters ,
196+ toolsBuildParameters: BuildParameters
197+ ) throws {
172198 let buildSystem = try swiftCommandState. createBuildSystem (
173199 explicitProduct: options. product,
174200 shouldLinkStaticSwiftStdlib: options. shouldLinkStaticSwiftStdlib,
175- productsBuildParameters: buildParameters,
201+ productsBuildParameters: productsBuildParameters,
202+ toolsBuildParameters: toolsBuildParameters,
176203 // command result output goes on stdout
177204 // ie "swift build" should output to stdout
178205 outputStream: TSCBasic . stdoutStream
0 commit comments