Skip to content

Commit b992469

Browse files
xedinfurby-tm
authored andcommitted
[PackageModel] Add a new target kind - provided library
This target points to a prebuilt library that comes from a certain location in a toolchain. It's going to be injected by the package manager into library manifests and shouldn't be accessible via user-facing APIs.
1 parent 73d20f1 commit b992469

File tree

16 files changed

+111
-6
lines changed

16 files changed

+111
-6
lines changed

Sources/Build/BuildDescription/ProductBuildDescription.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ package final class ProductBuildDescription: SPMBuildCore.ProductBuildDescriptio
4545
// Computed during build planning.
4646
var dylibs: [ProductBuildDescription] = []
4747

48+
/// The list of provided libraries that are going to be used by this product.
49+
var providedLibraries: [String: AbsolutePath] = [:]
50+
4851
/// Any additional flags to be added. These flags are expected to be computed during build planning.
4952
var additionalFlags: [String] = []
5053

@@ -156,6 +159,8 @@ package final class ProductBuildDescription: SPMBuildCore.ProductBuildDescriptio
156159
args += ["-F", self.buildParameters.buildPath.pathString]
157160
}
158161

162+
self.providedLibraries.forEach { args += ["-L", $1.pathString, "-l", $0] }
163+
159164
args += ["-L", self.buildParameters.buildPath.pathString]
160165
args += try ["-o", binaryPath.pathString]
161166
args += ["-module-name", self.product.name.spm_mangledToC99ExtendedIdentifier()]

Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,8 @@ extension LLBuildManifestBuilder {
424424
if target.underlying is BinaryTarget { return }
425425
// Ignore Plugin Targets.
426426
if target.underlying is PluginTarget { return }
427+
// Ignore Provided Libraries.
428+
if target.underlying is ProvidedLibraryTarget { return }
427429

428430
// Depend on the binary for executable targets.
429431
if target.type == .executable {

Sources/Build/BuildPlan/BuildPlan+Product.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ extension BuildPlan {
115115
}
116116
buildProduct.libraryBinaryPaths = dependencies.libraryBinaryPaths
117117

118+
buildProduct.providedLibraries = dependencies.providedLibraries
119+
118120
buildProduct.availableTools = dependencies.availableTools
119121
}
120122

@@ -127,6 +129,7 @@ extension BuildPlan {
127129
staticTargets: [ResolvedModule],
128130
systemModules: [ResolvedModule],
129131
libraryBinaryPaths: Set<AbsolutePath>,
132+
providedLibraries: [String: AbsolutePath],
130133
availableTools: [String: AbsolutePath]
131134
) {
132135
/* Prior to tools-version 5.9, we used to erroneously recursively traverse executable/plugin dependencies and statically include their
@@ -207,6 +210,7 @@ extension BuildPlan {
207210
var staticTargets = [ResolvedModule]()
208211
var systemModules = [ResolvedModule]()
209212
var libraryBinaryPaths: Set<AbsolutePath> = []
213+
var providedLibraries = [String: AbsolutePath]()
210214
var availableTools = [String: AbsolutePath]()
211215

212216
for dependency in allTargets {
@@ -260,6 +264,8 @@ extension BuildPlan {
260264
}
261265
case .plugin:
262266
continue
267+
case .providedLibrary:
268+
providedLibraries[target.name] = target.underlying.path
263269
}
264270

265271
case .product(let product, _):
@@ -277,7 +283,7 @@ extension BuildPlan {
277283
}
278284
}
279285

280-
return (linkLibraries, staticTargets, systemModules, libraryBinaryPaths, availableTools)
286+
return (linkLibraries, staticTargets, systemModules, libraryBinaryPaths, providedLibraries, availableTools)
281287
}
282288

283289
/// Extracts the artifacts from an artifactsArchive

Sources/Build/BuildPlan/BuildPlan+Swift.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import struct Basics.InternalError
1414
import class PackageModel.BinaryTarget
1515
import class PackageModel.ClangTarget
1616
import class PackageModel.SystemLibraryTarget
17+
import class PackageModel.ProvidedLibraryTarget
1718

1819
extension BuildPlan {
1920
func plan(swiftTarget: SwiftTargetBuildDescription) throws {
@@ -48,6 +49,10 @@ extension BuildPlan {
4849
swiftTarget.libraryBinaryPaths.insert(library.libraryPath)
4950
}
5051
}
52+
case let target as ProvidedLibraryTarget:
53+
swiftTarget.additionalFlags += [
54+
"-I", target.path.pathString
55+
]
5156
default:
5257
break
5358
}

Sources/Build/BuildPlan/BuildPlan.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ public class BuildPlan: SPMBuildCore.BuildPlan {
433433
toolsVersion: toolsVersion,
434434
fileSystem: fileSystem
435435
))
436-
case is SystemLibraryTarget, is BinaryTarget:
436+
case is SystemLibraryTarget, is BinaryTarget, is ProvidedLibraryTarget:
437437
break
438438
default:
439439
throw InternalError("unhandled \(target.underlying)")

Sources/Commands/Snippets/Cards/TopCard.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ fileprivate extension Target.Kind {
153153
return "snippets"
154154
case .macro:
155155
return "macros"
156+
case .providedLibrary:
157+
return "provided libraries"
156158
}
157159
}
158160
}

Sources/PackageLoading/PackageBuilder.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,16 @@ public final class PackageBuilder {
542542
throw ModuleError.artifactNotFound(targetName: target.name, expectedArtifactName: target.name)
543543
}
544544
return artifact.path
545+
} else if let targetPath = target.path, target.type == .providedLibrary {
546+
guard let path = try? AbsolutePath(validating: targetPath) else {
547+
throw ModuleError.invalidCustomPath(target: target.name, path: targetPath)
548+
}
549+
550+
if !self.fileSystem.isDirectory(path) {
551+
throw ModuleError.unsupportedTargetPath(targetPath)
552+
}
553+
554+
return path
545555
} else if let subpath = target.path { // If there is a custom path defined, use that.
546556
if subpath == "" || subpath == "." {
547557
return self.packagePath
@@ -865,6 +875,11 @@ public final class PackageBuilder {
865875
path: potentialModule.path,
866876
origin: artifactOrigin
867877
)
878+
} else if potentialModule.type == .providedLibrary {
879+
return ProvidedLibraryTarget(
880+
name: potentialModule.name,
881+
path: potentialModule.path
882+
)
868883
}
869884

870885
// Check for duplicate target dependencies

Sources/PackageModel/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ add_library(PackageModel
5151
Target/BinaryTarget.swift
5252
Target/ClangTarget.swift
5353
Target/PluginTarget.swift
54+
Target/ProvidedLibraryTarget.swift
5455
Target/SwiftTarget.swift
5556
Target/SystemLibraryTarget.swift
5657
Target/Target.swift

Sources/PackageModel/Manifest/TargetDescription.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public struct TargetDescription: Hashable, Encodable, Sendable {
2121
case binary
2222
case plugin
2323
case `macro`
24+
case providedLibrary
2425
}
2526

2627
/// Represents a target's dependency on another entity.
@@ -223,6 +224,19 @@ public struct TargetDescription: Hashable, Encodable, Sendable {
223224
if pkgConfig != nil { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "pkgConfig") }
224225
if providers != nil { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "providers") }
225226
if pluginCapability != nil { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "pluginCapability") }
227+
case .providedLibrary:
228+
if path == nil { throw Error.providedLibraryTargetRequiresPath(targetName: name) }
229+
if url != nil { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "url") }
230+
if !dependencies.isEmpty { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "dependencies") }
231+
if !exclude.isEmpty { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "exclude") }
232+
if sources != nil { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "sources") }
233+
if !resources.isEmpty { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "resources") }
234+
if publicHeadersPath != nil { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "publicHeadersPath") }
235+
if pkgConfig != nil { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "pkgConfig") }
236+
if providers != nil { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "providers") }
237+
if pluginCapability != nil { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "pluginCapability") }
238+
if !settings.isEmpty { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "settings") }
239+
if pluginUsages != nil { throw Error.disallowedPropertyInTarget(targetName: name, propertyName: "pluginUsages") }
226240
}
227241

228242
self.name = name
@@ -380,13 +394,16 @@ import protocol Foundation.LocalizedError
380394
private enum Error: LocalizedError, Equatable {
381395
case binaryTargetRequiresEitherPathOrURL(targetName: String)
382396
case disallowedPropertyInTarget(targetName: String, propertyName: String)
383-
397+
case providedLibraryTargetRequiresPath(targetName: String)
398+
384399
var errorDescription: String? {
385400
switch self {
386401
case .binaryTargetRequiresEitherPathOrURL(let targetName):
387402
return "binary target '\(targetName)' neither defines neither path nor URL for its artifacts"
388403
case .disallowedPropertyInTarget(let targetName, let propertyName):
389404
return "target '\(targetName)' contains a value for disallowed property '\(propertyName)'"
405+
case .providedLibraryTargetRequiresPath(let targetName):
406+
return "provided library target '\(targetName)' does not define a path to the library"
390407
}
391408
}
392409
}

Sources/PackageModel/ManifestSourceGeneration.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ fileprivate extension SourceCodeFragment {
317317
self.init(enum: "plugin", subnodes: params, multiline: true)
318318
case .macro:
319319
self.init(enum: "macro", subnodes: params, multiline: true)
320+
case .providedLibrary:
321+
self.init(enum: "providedLibrary", subnodes: params, multiline: true)
320322
}
321323
}
322324

0 commit comments

Comments
 (0)