|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 |
|
13 | 13 | import Foundation
|
| 14 | +import TSCBasic |
14 | 15 | import TSCUtility
|
15 | 16 |
|
16 | 17 | import struct Basics.AbsolutePath
|
@@ -128,6 +129,8 @@ extension PackagePIFProjectBuilder {
|
128 | 129 | settings[.GENERATE_INFOPLIST_FILE] = "YES"
|
129 | 130 | settings[.SKIP_INSTALL] = "NO"
|
130 | 131 | settings[.SWIFT_ACTIVE_COMPILATION_CONDITIONS].lazilyInitialize { ["$(inherited)"] }
|
| 132 | + // Enable index-while building for Swift compilations to facilitate discovery of XCTest tests. |
| 133 | + settings[.SWIFT_INDEX_STORE_ENABLE] = "YES" |
131 | 134 | } else if mainModule.type == .executable {
|
132 | 135 | // Setup install path for executables if it's in root of a pure Swift package.
|
133 | 136 | if pifBuilder.delegate.hostsOnlyPackages && pifBuilder.delegate.isRootPackage {
|
@@ -502,9 +505,13 @@ extension PackagePIFProjectBuilder {
|
502 | 505 | linkedPackageBinaries: linkedPackageBinaries,
|
503 | 506 | swiftLanguageVersion: mainModule.packageSwiftLanguageVersion(manifest: packageManifest),
|
504 | 507 | declaredPlatforms: self.declaredPlatforms,
|
505 |
| - deploymentTargets: self.deploymentTargets |
| 508 | + deploymentTargets: mainTargetDeploymentTargets |
506 | 509 | )
|
507 | 510 | self.builtModulesAndProducts.append(moduleOrProduct)
|
| 511 | + |
| 512 | + if moduleOrProductType == .unitTest { |
| 513 | + try makeTestRunnerProduct(for: moduleOrProduct) |
| 514 | + } |
508 | 515 | }
|
509 | 516 |
|
510 | 517 | private mutating func handleProduct(
|
@@ -995,6 +1002,102 @@ extension PackagePIFProjectBuilder {
|
995 | 1002 | )
|
996 | 1003 | self.builtModulesAndProducts.append(pluginProductMetadata)
|
997 | 1004 | }
|
| 1005 | + |
| 1006 | + // MARK: - Test Runners |
| 1007 | + mutating func makeTestRunnerProduct(for unitTestProduct: PackagePIFBuilder.ModuleOrProduct) throws { |
| 1008 | + // Only generate a test runner for root packages with tests. |
| 1009 | + guard pifBuilder.delegate.isRootPackage else { |
| 1010 | + return |
| 1011 | + } |
| 1012 | + |
| 1013 | + guard let unitTestModuleName = unitTestProduct.moduleName else { |
| 1014 | + throw StringError("Unit test product '\(unitTestProduct.name)' is missing a module name") |
| 1015 | + } |
| 1016 | + |
| 1017 | + let name = "\(unitTestProduct.name)-test-runner" |
| 1018 | + let moduleName = "\(unitTestModuleName)_test_runner" |
| 1019 | + let guid = PackagePIFBuilder.targetGUID(forModuleName: moduleName) |
| 1020 | + |
| 1021 | + let testRunnerTargetKeyPath = try self.project.addTarget { _ in |
| 1022 | + ProjectModel.Target ( |
| 1023 | + id: guid, |
| 1024 | + productType: .swiftpmTestRunner, |
| 1025 | + name: name, |
| 1026 | + productName: name |
| 1027 | + ) |
| 1028 | + } |
| 1029 | + |
| 1030 | + var settings: BuildSettings = self.package.underlying.packageBaseBuildSettings |
| 1031 | + let impartedSettings = BuildSettings() |
| 1032 | + |
| 1033 | + settings[.TARGET_NAME] = name |
| 1034 | + settings[.PACKAGE_RESOURCE_TARGET_KIND] = "regular" |
| 1035 | + settings[.PRODUCT_NAME] = "$(TARGET_NAME)" |
| 1036 | + settings[.PRODUCT_MODULE_NAME] = moduleName |
| 1037 | + settings[.PRODUCT_BUNDLE_IDENTIFIER] = "\(self.package.identity).\(name)" |
| 1038 | + .spm_mangledToBundleIdentifier() |
| 1039 | + settings[.EXECUTABLE_NAME] = name |
| 1040 | + settings[.SKIP_INSTALL] = "NO" |
| 1041 | + settings[.SWIFT_VERSION] = "5.0" |
| 1042 | + // This should eventually be set universally for all package targets/products. |
| 1043 | + settings[.LINKER_DRIVER] = "swiftc" |
| 1044 | + |
| 1045 | + let deploymentTargets = unitTestProduct.deploymentTargets |
| 1046 | + settings[.MACOSX_DEPLOYMENT_TARGET] = deploymentTargets?[.macOS] ?? nil |
| 1047 | + settings[.IPHONEOS_DEPLOYMENT_TARGET] = deploymentTargets?[.iOS] ?? nil |
| 1048 | + if let deploymentTarget_macCatalyst = deploymentTargets?[.macCatalyst] ?? nil { |
| 1049 | + settings.platformSpecificSettings[.macCatalyst]![.IPHONEOS_DEPLOYMENT_TARGET] = [deploymentTarget_macCatalyst] |
| 1050 | + } |
| 1051 | + settings[.TVOS_DEPLOYMENT_TARGET] = deploymentTargets?[.tvOS] ?? nil |
| 1052 | + settings[.WATCHOS_DEPLOYMENT_TARGET] = deploymentTargets?[.watchOS] ?? nil |
| 1053 | + settings[.DRIVERKIT_DEPLOYMENT_TARGET] = deploymentTargets?[.driverKit] ?? nil |
| 1054 | + settings[.XROS_DEPLOYMENT_TARGET] = deploymentTargets?[.visionOS] ?? nil |
| 1055 | + |
| 1056 | + // Add an empty sources phase so derived sources are compiled |
| 1057 | + self.project[keyPath: testRunnerTargetKeyPath].common.addSourcesBuildPhase { id in |
| 1058 | + ProjectModel.SourcesBuildPhase(id: id) |
| 1059 | + } |
| 1060 | + |
| 1061 | + guard let unitTestGUID = unitTestProduct.pifTarget?.id else { |
| 1062 | + throw StringError("Unit test product '\(unitTestProduct.name)' is missing a PIF GUID") |
| 1063 | + } |
| 1064 | + self.project[keyPath: testRunnerTargetKeyPath].common.addDependency( |
| 1065 | + on: unitTestGUID, |
| 1066 | + platformFilters: [], |
| 1067 | + linkProduct: true |
| 1068 | + ) |
| 1069 | + |
| 1070 | + self.project[keyPath: testRunnerTargetKeyPath].common.addBuildConfig { id in |
| 1071 | + BuildConfig( |
| 1072 | + id: id, |
| 1073 | + name: "Debug", |
| 1074 | + settings: settings, |
| 1075 | + impartedBuildSettings: impartedSettings |
| 1076 | + ) |
| 1077 | + } |
| 1078 | + self.project[keyPath: testRunnerTargetKeyPath].common.addBuildConfig { id in |
| 1079 | + BuildConfig( |
| 1080 | + id: id, |
| 1081 | + name: "Release", |
| 1082 | + settings: settings, |
| 1083 | + impartedBuildSettings: impartedSettings |
| 1084 | + ) |
| 1085 | + } |
| 1086 | + |
| 1087 | + let testRunner = PackagePIFBuilder.ModuleOrProduct( |
| 1088 | + type: .unitTestRunner, |
| 1089 | + name: name, |
| 1090 | + moduleName: moduleName, |
| 1091 | + pifTarget: .target(self.project[keyPath: testRunnerTargetKeyPath]), |
| 1092 | + indexableFileURLs: [], |
| 1093 | + headerFiles: [], |
| 1094 | + linkedPackageBinaries: [], |
| 1095 | + swiftLanguageVersion: nil, |
| 1096 | + declaredPlatforms: self.declaredPlatforms, |
| 1097 | + deploymentTargets: self.deploymentTargets |
| 1098 | + ) |
| 1099 | + self.builtModulesAndProducts.append(testRunner) |
| 1100 | + } |
998 | 1101 | }
|
999 | 1102 |
|
1000 | 1103 | // MARK: - Helper Types
|
|
0 commit comments