Skip to content

Commit 2059e18

Browse files
committed
Add SwiftBuild coverage support
Ensure the SwiftBuild build systam has feature parity with the Native build system as it relates to coverage. Fixes: #9077 Fixes: #9197 Issue: rdar://159461439
1 parent 8889a96 commit 2059e18

File tree

21 files changed

+1114
-569
lines changed

21 files changed

+1114
-569
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
xcuserdata/
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// swift-tools-version: 6.2
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "Simple",
8+
products: [
9+
// Products define the executables and libraries a package produces, making them visible to other packages.
10+
.library(
11+
name: "Simple",
12+
targets: ["Simple"]
13+
),
14+
],
15+
targets: [
16+
// Targets are the basic building blocks of a package, defining a module or a test suite.
17+
// Targets can depend on other targets in this package and products from dependencies.
18+
.target(
19+
name: "Simple"
20+
),
21+
.testTarget(
22+
name: "SimpleTests",
23+
dependencies: ["Simple"]
24+
),
25+
]
26+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// The Swift Programming Language
2+
// https://docs.swift.org/swift-book
3+
4+
public func greet(name: String = "world") -> String {
5+
return "Hello, \(name)!"
6+
}
7+
8+
public func libA() -> String {
9+
return "libA"
10+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import Testing
2+
import XCTest
3+
@testable import Simple
4+
5+
@Test(
6+
arguments: [
7+
"Bob",
8+
"Alice",
9+
"",
10+
]
11+
)
12+
func testGreet(
13+
name: String
14+
) async throws {
15+
let actual = greet(name: name)
16+
17+
#expect(actual == "Hello, \(name)!")
18+
}
19+
20+
final class SimpleTests: XCTestCase {
21+
func testExample() throws {
22+
XCTAssertEqual(libA(), "libA", "Actual is not as expected")
23+
}
24+
}

Sources/Basics/FileSystem/AbsolutePath.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,19 @@ public struct AbsolutePath: Hashable, Sendable {
5353
/// The input string will be normalized if needed, as described in the
5454
/// documentation for AbsolutePath.
5555
public init(validating pathString: String) throws {
56-
self.underlying = try .init(validating: pathString)
56+
self.underlying = try .init(
57+
validating: pathString.trimmingCharacters(in: .whitespacesAndNewlines),
58+
)
5759
}
5860

5961
/// Initializes an AbsolutePath from a string that may be either absolute
6062
/// or relative; if relative, `basePath` is used as the anchor; if absolute,
6163
/// it is used as is, and in this case `basePath` is ignored.
6264
public init(validating pathString: String, relativeTo basePath: AbsolutePath) throws {
63-
self.underlying = try .init(validating: pathString, relativeTo: basePath.underlying)
65+
self.underlying = try .init(
66+
validating: pathString.trimmingCharacters(in: .whitespacesAndNewlines),
67+
relativeTo: basePath.underlying,
68+
)
6469
}
6570

6671
/// Initializes the AbsolutePath by concatenating a relative path to an

Sources/Basics/FileSystem/RelativePath.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12-
12+
import Foundation
1313
import struct TSCBasic.RelativePath
1414

1515
// public for transition
@@ -40,7 +40,9 @@ public struct RelativePath: Hashable, Sendable {
4040

4141
/// Convenience initializer that verifies that the path is relative.
4242
public init(validating pathString: String) throws {
43-
self.underlying = try .init(validating: pathString)
43+
self.underlying = try .init(
44+
validating: pathString.trimmingCharacters(in: .whitespacesAndNewlines),
45+
)
4446
}
4547

4648
/// Directory component. For a relative path without any path separators,

Sources/Commands/SwiftTestCommand.swift

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import ArgumentParser
1414

1515
@_spi(SwiftPMInternal)
1616
import Basics
17+
import struct Basics.Triple
1718

1819
import _Concurrency
1920

@@ -597,7 +598,11 @@ public struct SwiftTestCommand: AsyncSwiftCommand {
597598
for product in testProducts {
598599
// Export the codecov data as JSON.
599600
let jsonPath = productsBuildParameters.codeCovAsJSONPath(packageName: rootManifest.displayName)
600-
try await exportCodeCovAsJSON(to: jsonPath, testBinary: product.binaryPath, swiftCommandState: swiftCommandState)
601+
try await exportCodeCovAsJSON(
602+
to: jsonPath,
603+
testBinary: product.binaryPath,
604+
swiftCommandState: swiftCommandState,
605+
)
601606
}
602607
}
603608

@@ -619,7 +624,6 @@ public struct SwiftTestCommand: AsyncSwiftCommand {
619624
}
620625
}
621626
args += ["-o", productsBuildParameters.codeCovDataFile.pathString]
622-
623627
try await AsyncProcess.checkNonZeroExit(arguments: args)
624628
}
625629

@@ -632,11 +636,18 @@ public struct SwiftTestCommand: AsyncSwiftCommand {
632636
// Export using the llvm-cov tool.
633637
let llvmCov = try swiftCommandState.getTargetToolchain().getLLVMCov()
634638
let (productsBuildParameters, _) = try swiftCommandState.buildParametersForTest(options: self.options)
639+
let archArgs: [String] = if let arch = productsBuildParameters.triple.llvmCovArchArgument {
640+
// let archArgs: [String] = if let arch = productsBuildParameters.triple.arch {
641+
["--arch", "\(arch)"]
642+
} else {
643+
[]
644+
}
635645
let args = [
636646
llvmCov.pathString,
637647
"export",
638648
"-instr-profile=\(productsBuildParameters.codeCovDataFile)",
639-
testBinary.pathString
649+
] + archArgs + [
650+
testBinary.pathString,
640651
]
641652
let result = try await AsyncProcess.popen(arguments: args)
642653

@@ -709,6 +720,21 @@ extension SwiftTestCommand {
709720
}
710721
}
711722

723+
fileprivate extension Triple {
724+
var llvmCovArchArgument: String? {
725+
guard let arch = self.arch else {
726+
return nil
727+
}
728+
switch arch {
729+
case .aarch64:
730+
// macOS uses arm64, Linux might use aarch64
731+
return ProcessInfo.hostOperatingSystem == .macOS ? "arm64" : "aarch64"
732+
default:
733+
return "\(arch)"
734+
}
735+
}
736+
}
737+
712738
extension SwiftTestCommand {
713739
struct Last: SwiftCommand {
714740
@OptionGroup(visibility: .hidden)

Sources/SwiftBuildSupport/SwiftBuildSystem.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,8 +1077,8 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
10771077

10781078
private static func constructTestingSettingsOverrides(from parameters: BuildParameters.Testing) -> [String: String] {
10791079
var settings: [String: String] = [:]
1080-
// TODO: enableCodeCoverage
1081-
// explicitlyEnabledTestability
1080+
1081+
settings["CLANG_COVERAGE_MAPPING"] = parameters.enableCodeCoverage ? "YES" : "NO"
10821082

10831083
switch parameters.explicitlyEnabledTestability {
10841084
case true:

Sources/_InternalTestSupport/SwiftTesting+TraitsBug.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ extension Trait where Self == Testing.Bug {
5454
)
5555
}
5656

57+
public static var IssueWindowsPathTestsFailures: Self {
58+
.issue(
59+
"https://github.com/swiftlang/swift-package-manager/issues/8511",
60+
relationship: .defect,
61+
)
62+
}
63+
5764
public static var IssueWindowsCannotSaveAttachment: Self {
5865
// error: unable to write file 'C:\Users\ContainerAdministrator\AppData\Local\Temp\CFamilyTargets_CDynamicLookup.hNxGHC\CFamilyTargets_CDynamicLookup\.build\x86_64-unknown-windows-msvc\Intermediates.noindex\CDynamicLookup.build\Release-windows\CDynamicLookup.build\Objects-normal\x86_64\CDynamicLookup.LinkFileList': No such file or directory (2)
5966
.issue(

0 commit comments

Comments
 (0)