in Sources/SPMBuildCore/PluginInvocation.swift [830:943]
mutating func serialize(target: ResolvedTarget) throws -> PluginScriptRunnerInput.Target.Id? {
// If we've already seen the target, just return the wire ID we already assigned to it.
if let id = targetsToIds[target] { return id }
// Construct the FileList
var targetFiles: [PluginScriptRunnerInput.Target.TargetInfo.File] = []
targetFiles.append(contentsOf: try target.underlyingTarget.sources.paths.map {
.init(basePathId: try serialize(path: $0.parentDirectory), name: $0.basename, type: .source)
})
targetFiles.append(contentsOf: try target.underlyingTarget.resources.map {
.init(basePathId: try serialize(path: $0.path.parentDirectory), name: $0.path.basename, type: .resource)
})
targetFiles.append(contentsOf: try target.underlyingTarget.ignored.map {
.init(basePathId: try serialize(path: $0.parentDirectory), name: $0.basename, type: .unknown)
})
targetFiles.append(contentsOf: try target.underlyingTarget.others.map {
.init(basePathId: try serialize(path: $0.parentDirectory), name: $0.basename, type: .unknown)
})
// Create a scope for evaluating build settings.
let scope = BuildSettings.Scope(target.underlyingTarget.buildSettings, environment: buildEnvironment)
// Look at the target and decide what to serialize. At this point we may decide to not serialize it at all.
let targetInfo: PluginScriptRunnerInput.Target.TargetInfo
switch target.underlyingTarget {
case let target as SwiftTarget:
targetInfo = .swiftSourceModuleInfo(
moduleName: target.c99name,
sourceFiles: targetFiles,
compilationConditions: scope.evaluate(.SWIFT_ACTIVE_COMPILATION_CONDITIONS),
linkedLibraries: scope.evaluate(.LINK_LIBRARIES),
linkedFrameworks: scope.evaluate(.LINK_FRAMEWORKS))
case let target as ClangTarget:
targetInfo = .clangSourceModuleInfo(
moduleName: target.c99name,
sourceFiles: targetFiles,
preprocessorDefinitions: scope.evaluate(.GCC_PREPROCESSOR_DEFINITIONS),
headerSearchPaths: scope.evaluate(.HEADER_SEARCH_PATHS),
publicHeadersDirId: try serialize(path: target.includeDir),
linkedLibraries: scope.evaluate(.LINK_LIBRARIES),
linkedFrameworks: scope.evaluate(.LINK_FRAMEWORKS))
case let target as SystemLibraryTarget:
var cFlags: [String] = []
var ldFlags: [String] = []
// FIXME: What do we do with any diagnostics here?
let observabilityScope = ObservabilitySystem({ _, _ in }).topScope
for result in pkgConfigArgs(for: target, fileSystem: localFileSystem, observabilityScope: observabilityScope) {
if let error = result.error {
observabilityScope.emit(
warning: "\(error)",
metadata: .pkgConfig(pcFile: result.pkgConfigName, targetName: target.name)
)
}
else {
cFlags += result.cFlags
ldFlags += result.libs
}
}
targetInfo = .systemLibraryInfo(
pkgConfig: target.pkgConfig,
compilerFlags: cFlags,
linkerFlags: ldFlags)
case let target as BinaryTarget:
let artifactKind: PluginScriptRunnerInput.Target.TargetInfo.BinaryArtifactKind
switch target.kind {
case .artifactsArchive:
artifactKind = .artifactsArchive
case .xcframework:
artifactKind = .xcframework
case .unknown:
artifactKind = .unknown
}
let artifactOrigin: PluginScriptRunnerInput.Target.TargetInfo.BinaryArtifactOrigin
switch target.origin {
case .local:
artifactOrigin = .local
case .remote(let url):
artifactOrigin = .remote(url: url)
}
targetInfo = .binaryArtifactInfo(
kind: artifactKind,
origin: artifactOrigin,
artifactId: try serialize(path: target.artifactPath))
default:
// It's not a type of target that we pass through to the plugin.
return nil
}
// We only get this far if we are serializing the target. If so we also serialize its dependencies. This needs to be done before assigning the next wire ID for the target we're serializing, to make sure we end up with the correct one.
let dependencies: [PluginScriptRunnerInput.Target.Dependency] = try target.dependencies(satisfying: buildEnvironment).compactMap {
switch $0 {
case .target(let target, _):
return try serialize(target: target).map { .target(targetId: $0) }
case .product(let product, _):
return try serialize(product: product).map { .product(productId: $0) }
}
}
// Finally assign the next wire ID to the target and append a serialized Target record.
let id = targets.count
targets.append(.init(
name: target.name,
directoryId: try serialize(path: target.sources.root),
dependencies: dependencies,
info: targetInfo))
targetsToIds[target] = id
return id
}