Skip to content

Commit 5c79ce1

Browse files
committed
SwiftBuild: Add index store support
Update the PIF builder to take into account of the `--[auto|disable|enable]-index-store` command line option. When set to `auto`, the PIF builder behaviour does the same as the Native build system. Fixes: swiftlang#9325 Issue: rdar://163961900
1 parent 2096cff commit 5c79ce1

File tree

16 files changed

+449
-46
lines changed

16 files changed

+449
-46
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: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// The Swift Programming Language
2+
// https://docs.swift.org/swift-book
3+
4+
public struct Person {
5+
public let name: String
6+
7+
public init(name: String) {
8+
self.name = name
9+
}
10+
}
11+
extension Person: CustomStringConvertible {
12+
public var description: String {
13+
return name
14+
}
15+
}
16+
17+
public func greet(person: Person? = nil) -> String {
18+
let name = if let person {
19+
person.name
20+
} else {
21+
"World"
22+
}
23+
24+
return "Hello, \(name)!"
25+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import Testing
2+
import XCTest
3+
4+
import Simple
5+
6+
7+
final public class XCTesting: XCTestCase {
8+
func testGreetWithEmptyArgument() {
9+
let actual = greet()
10+
XCTAssertEqual(actual, "Hello, World!")
11+
}
12+
13+
func testGreetWithNonEmptyArgument() {
14+
let name = "MyName"
15+
let person = Person(name: name)
16+
let actual = greet(person: person)
17+
XCTAssertEqual(actual, "Hello, \(name)!")
18+
}
19+
}
20+
21+
@Suite
22+
struct STTestTests {
23+
@Test("STTest tests")
24+
func testGreetWithEmptyArgument() {
25+
let actual = greet()
26+
#expect(actual == "Hello, World!")
27+
}
28+
29+
@Test("STTest tests")
30+
func testGreetWithNonEmptyArgument() {
31+
let name = "MyName"
32+
let person = Person(name: name)
33+
let actual = greet(person: person)
34+
#expect(actual == "Hello, \(name)!")
35+
}
36+
}

Sources/PackageModel/SwiftSDKs/SwiftSDK.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ public struct SwiftSDK: Equatable {
609609
extraCCFlags += ["-fPIC"]
610610
#endif
611611

612-
return SwiftSDK(
612+
let returnValue = SwiftSDK(
613613
toolset: .init(
614614
knownTools: [
615615
.cCompiler: .init(extraCLIOptions: extraCCFlags),
@@ -620,6 +620,7 @@ public struct SwiftSDK: Equatable {
620620
pathsConfiguration: .init(sdkRootPath: sdkPath),
621621
xctestSupport: xctestSupport
622622
)
623+
return returnValue
623624
}
624625

625626
/// Auxiliary platform frameworks and libraries.

Sources/SPMBuildCore/BuildParameters/BuildParameters.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public struct BuildParameters: Encodable {
2929
}
3030

3131
/// Mode for the indexing-while-building feature.
32-
public enum IndexStoreMode: String, Encodable {
32+
public enum IndexStoreMode: String, Encodable, CaseIterable {
3333
/// Index store should be enabled.
3434
case on
3535
/// Index store should be disabled.

Sources/SwiftBuildSupport/PIFBuilder.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,8 @@ public final class PIFBuilder {
415415
addLocalRpaths: self.parameters.addLocalRpaths,
416416
packageDisplayVersion: package.manifest.displayName,
417417
fileSystem: self.fileSystem,
418-
observabilityScope: self.observabilityScope
418+
observabilityScope: self.observabilityScope,
419+
buildParameters: buildParameters,
419420
)
420421

421422
try packagePIFBuilder.build()

Sources/SwiftBuildSupport/PackagePIFBuilder.swift

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import struct PackageGraph.ModulesGraph
3232
import struct PackageGraph.ResolvedModule
3333
import struct PackageGraph.ResolvedPackage
3434

35+
import struct SPMBuildCore.BuildParameters
36+
3537
import enum SwiftBuild.ProjectModel
3638

3739
typealias GUID = SwiftBuild.ProjectModel.GUID
@@ -179,6 +181,9 @@ public final class PackagePIFBuilder {
179181
/// The file system to read from.
180182
let fileSystem: FileSystem
181183

184+
/// The build parameters
185+
let buildParameters: BuildParameters
186+
182187
/// Whether to suppress warnings from compilers, linkers, and other build tools for package dependencies.
183188
private var suppressWarningsForPackageDependencies: Bool {
184189
UserDefaults.standard.bool(forKey: "SuppressWarningsForPackageDependencies", defaultValue: true)
@@ -203,7 +208,8 @@ public final class PackagePIFBuilder {
203208
addLocalRpaths: Bool = true,
204209
packageDisplayVersion: String?,
205210
fileSystem: FileSystem,
206-
observabilityScope: ObservabilityScope
211+
observabilityScope: ObservabilityScope,
212+
buildParameters: BuildParameters,
207213
) {
208214
self.package = resolvedPackage
209215
self.packageManifest = packageManifest
@@ -215,6 +221,7 @@ public final class PackagePIFBuilder {
215221
self.fileSystem = fileSystem
216222
self.observabilityScope = observabilityScope
217223
self.addLocalRpaths = addLocalRpaths
224+
self.buildParameters = buildParameters
218225
}
219226

220227
public init(
@@ -227,7 +234,8 @@ public final class PackagePIFBuilder {
227234
addLocalRpaths: Bool = true,
228235
packageDisplayVersion: String?,
229236
fileSystem: FileSystem,
230-
observabilityScope: ObservabilityScope
237+
observabilityScope: ObservabilityScope,
238+
buildParameters: BuildParameters,
231239
) {
232240
self.package = resolvedPackage
233241
self.packageManifest = packageManifest
@@ -239,6 +247,7 @@ public final class PackagePIFBuilder {
239247
self.packageDisplayVersion = packageDisplayVersion
240248
self.fileSystem = fileSystem
241249
self.observabilityScope = observabilityScope
250+
self.buildParameters = buildParameters
242251
}
243252

244253
/// Build an empty PIF project.
@@ -438,7 +447,7 @@ public final class PackagePIFBuilder {
438447
//
439448

440449
self.log(.debug, "Processing \(package.products.count) products:")
441-
450+
442451
// For each of the **products** in the package we create a corresponding `PIFTarget` of the appropriate type.
443452
for product in self.package.products {
444453
switch product.type {
@@ -461,7 +470,7 @@ public final class PackagePIFBuilder {
461470
}
462471

463472
case .executable, .test, .snippet:
464-
try projectBuilder.makeMainModuleProduct(product)
473+
try projectBuilder.makeMainModuleProduct(product, buildParameters: self.buildParameters)
465474

466475
case .plugin:
467476
try projectBuilder.makePluginProduct(product)
@@ -561,8 +570,8 @@ public final class PackagePIFBuilder {
561570
// We currently deliberately do not support Swift ObjC interface headers.
562571
settings[.SWIFT_INSTALL_OBJC_HEADER] = "NO"
563572
settings[.SWIFT_OBJC_INTERFACE_HEADER_NAME] = ""
564-
565-
// rdar://47937899 (Don't try to link frameworks to object files)
573+
574+
// rdar://47937899 (Don't try to link frameworks to object files)
566575
// - looks like this defaults to OTHER_LDFLAGS (via xcspec) which can result in linking frameworks to mh_objects which is unwanted.
567576
settings[.OTHER_LDRFLAGS] = []
568577

@@ -622,6 +631,7 @@ public final class PackagePIFBuilder {
622631
debugSettings[.ENABLE_TESTABILITY] = "YES"
623632
debugSettings[.SWIFT_ACTIVE_COMPILATION_CONDITIONS, default: []].append(contentsOf: ["DEBUG"])
624633
debugSettings[.GCC_PREPROCESSOR_DEFINITIONS, default: ["$(inherited)"]].append(contentsOf: ["DEBUG=1"])
634+
debugSettings[.SWIFT_INDEX_STORE_ENABLE] = "YES"
625635
builder.project.addBuildConfig { id in BuildConfig(id: id, name: "Debug", settings: debugSettings) }
626636

627637
// Add the build settings that are specific to release builds, and set those as the "Release" configuration.

Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Products.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,18 @@ import struct PackageGraph.ResolvedModule
2929
import struct PackageGraph.ResolvedPackage
3030
import struct PackageGraph.ResolvedProduct
3131

32+
import struct SPMBuildCore.BuildParameters
33+
3234
import enum SwiftBuild.ProjectModel
3335

3436
/// Extension to create PIF **products** for a given package.
3537
extension PackagePIFProjectBuilder {
3638
// MARK: - Main Module Products
3739

38-
mutating func makeMainModuleProduct(_ product: PackageGraph.ResolvedProduct) throws {
40+
mutating func makeMainModuleProduct(
41+
_ product: PackageGraph.ResolvedProduct,
42+
buildParameters: BuildParameters,
43+
) throws {
3944
precondition(product.isMainModuleProduct)
4045

4146
// We'll be infusing the product's main module into the one for the product itself.
@@ -477,7 +482,7 @@ extension PackagePIFProjectBuilder {
477482

478483
// Apply target-specific build settings defined in the manifest.
479484
let allBuildSettings = mainModule.computeAllBuildSettings(observabilityScope: pifBuilder.observabilityScope)
480-
485+
481486
// Apply settings using the convenience methods
482487
allBuildSettings.apply(to: &debugSettings, for: .debug)
483488
allBuildSettings.apply(to: &releaseSettings, for: .release)

Sources/SwiftBuildSupport/SwiftBuildSystem.swift

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct SessionFailedError: Error {
4343
var diagnostics: [SwiftBuild.SwiftBuildMessage.DiagnosticInfo]
4444
}
4545

46-
func withService<T>(
46+
package func withService<T>(
4747
connectionMode: SWBBuildServiceConnectionMode = .default,
4848
variant: SWBBuildServiceVariant = .default,
4949
serviceBundleURL: URL? = nil,
@@ -860,7 +860,11 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
860860
)
861861
}
862862

863-
private func makeBuildParameters(session: SWBBuildServiceSession, symbolGraphOptions: BuildOutput.SymbolGraphOptions?) async throws -> SwiftBuild.SWBBuildParameters {
863+
internal func makeBuildParameters(
864+
session: SWBBuildServiceSession,
865+
symbolGraphOptions: BuildOutput.SymbolGraphOptions?,
866+
setToolchainSetting: Bool = true,
867+
) async throws -> SwiftBuild.SWBBuildParameters {
864868
// Generate the run destination parameters.
865869
let runDestination = makeRunDestination()
866870

@@ -872,17 +876,19 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
872876
// Generate a table of any overriding build settings.
873877
var settings: [String: String] = [:]
874878

875-
// If the SwiftPM toolchain corresponds to a toolchain registered with the lower level build system, add it to the toolchain stack.
876-
// Otherwise, apply overrides for each component of the SwiftPM toolchain.
877-
if let toolchainID = try await session.lookupToolchain(at: buildParameters.toolchain.toolchainDir.pathString) {
878-
settings["TOOLCHAINS"] = "\(toolchainID.rawValue) $(inherited)"
879-
} else {
880-
// FIXME: This list of overrides is incomplete.
881-
// An error with determining the override should not be fatal here.
882-
settings["CC"] = try? buildParameters.toolchain.getClangCompiler().pathString
883-
// Always specify the path of the effective Swift compiler, which was determined in the same way as for the
884-
// native build system.
885-
settings["SWIFT_EXEC"] = buildParameters.toolchain.swiftCompilerPath.pathString
879+
if setToolchainSetting {
880+
// If the SwiftPM toolchain corresponds to a toolchain registered with the lower level build system, add it to the toolchain stack.
881+
// Otherwise, apply overrides for each component of the SwiftPM toolchain.
882+
if let toolchainID = try await session.lookupToolchain(at: buildParameters.toolchain.toolchainDir.pathString) {
883+
settings["TOOLCHAINS"] = "\(toolchainID.rawValue) $(inherited)"
884+
} else {
885+
// FIXME: This list of overrides is incomplete.
886+
// An error with determining the override should not be fatal here.
887+
settings["CC"] = try? buildParameters.toolchain.getClangCompiler().pathString
888+
// Always specify the path of the effective Swift compiler, which was determined in the same way as for the
889+
// native build system.
890+
settings["SWIFT_EXEC"] = buildParameters.toolchain.swiftCompilerPath.pathString
891+
}
886892
}
887893

888894
// FIXME: workaround for old Xcode installations such as what is in CI
@@ -985,6 +991,38 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
985991
settings["GENERATE_TEST_ENTRYPOINTS_FOR_BUNDLES"] = "YES"
986992
}
987993

994+
// Set the value of the index store
995+
struct IndexStoreSettings {
996+
let enableVariableName: String
997+
let pathVariable: String
998+
}
999+
1000+
let indexStoreSettingNames: [IndexStoreSettings] = [
1001+
IndexStoreSettings(
1002+
enableVariableName: "CLANG_INDEX_STORE_ENABLE",
1003+
pathVariable: "CLANG_INDEX_STORE_PATH",
1004+
),
1005+
IndexStoreSettings(
1006+
enableVariableName: "SWIFT_INDEX_STORE_ENABLE",
1007+
pathVariable: "SWIFT_INDEX_STORE_PATH",
1008+
),
1009+
]
1010+
1011+
switch self.buildParameters.indexStoreMode {
1012+
case .on:
1013+
for setting in indexStoreSettingNames {
1014+
settings[setting.enableVariableName] = "YES"
1015+
settings[setting.pathVariable] = self.buildParameters.indexStore.pathString
1016+
}
1017+
case .off:
1018+
for setting in indexStoreSettingNames {
1019+
settings[setting.enableVariableName] = "NO"
1020+
}
1021+
case .auto:
1022+
// The settings are handles in the PIF builder
1023+
break
1024+
}
1025+
9881026
func reportConflict(_ a: String, _ b: String) throws -> String {
9891027
throw StringError("Build parameters constructed conflicting settings overrides '\(a)' and '\(b)'")
9901028
}
@@ -1223,13 +1261,13 @@ fileprivate extension SwiftBuild.SwiftBuildMessage.DiagnosticInfo.Location {
12231261
case .none:
12241262
return path
12251263
}
1226-
1264+
12271265
case .buildSettings(let names):
12281266
return names.joined(separator: ", ")
1229-
1267+
12301268
case .buildFiles(let buildFiles, let targetGUID):
12311269
return "\(targetGUID): " + buildFiles.map { String(describing: $0) }.joined(separator: ", ")
1232-
1270+
12331271
case .unknown:
12341272
return nil
12351273
}

0 commit comments

Comments
 (0)