-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add support for generating more C files with Swift Build. #9252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -156,7 +156,7 @@ public final class ClangModuleBuildDescription { | |
if toolsVersion >= .v5_9 { | ||
self.buildToolPluginInvocationResults = buildToolPluginInvocationResults | ||
|
||
(self.pluginDerivedSources, self.pluginDerivedResources) = ModulesGraph.computePluginGeneratedFiles( | ||
let pluginGeneratedFiles = ModulesGraph.computePluginGeneratedFiles( | ||
target: target, | ||
toolsVersion: toolsVersion, | ||
additionalFileRules: additionalFileRules, | ||
|
@@ -165,6 +165,23 @@ public final class ClangModuleBuildDescription { | |
prebuildCommandResults: prebuildCommandResults, | ||
observabilityScope: observabilityScope | ||
) | ||
|
||
self.pluginDerivedSources = Sources( | ||
paths: pluginGeneratedFiles.sources.map(\.self), | ||
root: buildParameters.dataPath | ||
) | ||
self.pluginDerivedResources = pluginGeneratedFiles.resources.values.map(\.self) | ||
|
||
// With Swift Build on the horizon, we won't add support for generated headers, modulemaps, and apinotes here | ||
for absPath in pluginGeneratedFiles.headers { | ||
observabilityScope.emit(warning: "Module maps generated by plugins are not supported at this time: \(absPath)") | ||
} | ||
for absPath in pluginGeneratedFiles.moduleMaps { | ||
observabilityScope.emit(warning: "API Notes generated by plugins are not supported at this time: \(absPath)") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should say module maps |
||
} | ||
for absPath in pluginGeneratedFiles.apiNotes { | ||
observabilityScope.emit(warning: "API Notes generated by plugins are not supported at this time: \(absPath)") | ||
} | ||
} else { | ||
self.buildToolPluginInvocationResults = [] | ||
self.pluginDerivedSources = Sources(paths: [], root: buildParameters.dataPath) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -306,7 +306,7 @@ public struct TargetSourcesBuilder { | |
/// Returns the `Resource` file associated with a file and a particular rule, if there is one. | ||
private static func resource(for path: Basics.AbsolutePath, with rule: FileRuleDescription.Rule, defaultLocalization: String?, targetName: String, targetPath: Basics.AbsolutePath, observabilityScope: ObservabilityScope) -> Resource? { | ||
switch rule { | ||
case .compile, .header, .none, .modulemap, .ignored: | ||
case .compile, .header, .none, .modulemap, .apinotes, .ignored: | ||
return nil | ||
case .processResource: | ||
let implicitLocalization: String? = { | ||
|
@@ -519,14 +519,21 @@ public struct TargetSourcesBuilder { | |
return contents | ||
} | ||
|
||
public static func computeContents(for generatedFiles: [Basics.AbsolutePath], toolsVersion: ToolsVersion, additionalFileRules: [FileRuleDescription], defaultLocalization: String?, targetName: String, targetPath: Basics.AbsolutePath, observabilityScope: ObservabilityScope) -> (sources: [Basics.AbsolutePath], resources: [Resource]) { | ||
var sources = [Basics.AbsolutePath]() | ||
var resources = [Resource]() | ||
public static func computeContents( | ||
for generatedFiles: [Basics.AbsolutePath], | ||
toolsVersion: ToolsVersion, | ||
additionalFileRules: [FileRuleDescription], | ||
defaultLocalization: String?, | ||
targetName: String, | ||
targetPath: Basics.AbsolutePath, | ||
observabilityScope: ObservabilityScope) -> GeneratedFiles | ||
{ | ||
var files = GeneratedFiles() | ||
|
||
generatedFiles.forEach { absPath in | ||
// 5.6 handled treated all generated files as sources. | ||
if toolsVersion <= .v5_6 { | ||
sources.append(absPath) | ||
files.sources.insert(absPath) | ||
return | ||
} | ||
|
||
|
@@ -539,27 +546,76 @@ public struct TargetSourcesBuilder { | |
|
||
switch rule { | ||
case .compile: | ||
if absPath.extension == "swift" { | ||
sources.append(absPath) | ||
if absPath.extension == "swift" || toolsVersion >= .v6_3 { | ||
files.sources.insert(absPath) | ||
} else { | ||
observabilityScope.emit(warning: "Only Swift is supported for generated plugin source files at this time: \(absPath)") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "at this time" is weird now; this should instead mention that it's not supported in the current tools version There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, it's a weird statement. I guess Boris was just trying to give users hope :). |
||
} | ||
case .copyResource, .processResource, .embedResourceInCode: | ||
if let resource = Self.resource(for: absPath, with: rule, defaultLocalization: defaultLocalization, targetName: targetName, targetPath: targetPath, observabilityScope: observabilityScope) { | ||
resources.append(resource) | ||
files.resources[resource.path] = resource | ||
} else { | ||
// If this is reached, `TargetSourcesBuilder` already emitted a diagnostic, so we can ignore this case here. | ||
} | ||
case .header: | ||
observabilityScope.emit(warning: "Headers generated by plugins are not supported at this time: \(absPath)") | ||
if toolsVersion >= .v6_3 { | ||
files.headers.insert(absPath) | ||
} else { | ||
observabilityScope.emit(warning: "Headers generated by plugins are not supported at this time: \(absPath)") | ||
} | ||
case .modulemap: | ||
observabilityScope.emit(warning: "Module maps generated by plugins are not supported at this time: \(absPath)") | ||
if toolsVersion >= .v6_3 { | ||
files.moduleMaps.insert(absPath) | ||
} else { | ||
observabilityScope.emit(warning: "Module maps generated by plugins are not supported at this time: \(absPath)") | ||
} | ||
case .apinotes: | ||
if toolsVersion >= .v6_3 { | ||
files.apiNotes.insert(absPath) | ||
} else { | ||
observabilityScope.emit(warning: "API Notes generated by plugins are not supported at this time: \(absPath)") | ||
} | ||
case .ignored, .none: | ||
break | ||
} | ||
} | ||
|
||
return (sources, resources) | ||
return files | ||
} | ||
} | ||
|
||
public struct GeneratedFiles { | ||
public var sources: Set<Basics.AbsolutePath> | ||
// Order matters with the header search paths | ||
public var headerSearchPaths: [Basics.AbsolutePath] | ||
public var headers: Set<Basics.AbsolutePath> | ||
public var moduleMaps: Set<Basics.AbsolutePath> | ||
public var apiNotes: Set<Basics.AbsolutePath> | ||
public var resources: [Basics.AbsolutePath: Resource] | ||
|
||
public init( | ||
sources: Set<Basics.AbsolutePath> = [], | ||
headerSearchPaths: [Basics.AbsolutePath] = [], | ||
headers: Set<Basics.AbsolutePath> = [], | ||
moduleMaps: Set<Basics.AbsolutePath> = [], | ||
apiNotes: Set<Basics.AbsolutePath> = [], | ||
resources: [Basics.AbsolutePath: Resource] = [:]) | ||
{ | ||
self.sources = sources | ||
self.headerSearchPaths = headerSearchPaths | ||
self.headers = headers | ||
self.moduleMaps = moduleMaps | ||
self.apiNotes = apiNotes | ||
self.resources = resources | ||
} | ||
|
||
public mutating func merge(_ other: GeneratedFiles) { | ||
sources.formUnion(other.sources) | ||
headerSearchPaths.append(contentsOf: other.headerSearchPaths) | ||
headers.formUnion(other.headers) | ||
moduleMaps.formUnion(other.moduleMaps) | ||
apiNotes.formUnion(other.apiNotes) | ||
resources.merge(other.resources, uniquingKeysWith: { winner, _ in winner }) | ||
} | ||
} | ||
|
||
|
@@ -589,6 +645,9 @@ public struct FileRuleDescription: Sendable { | |
/// A header file. | ||
case header | ||
|
||
/// An apinotes file, needs to be located in same directory as module map | ||
case apinotes | ||
|
||
/// Indicates that the file should be treated as ignored, without causing an unhandled-file warning. | ||
case ignored | ||
|
||
|
@@ -661,6 +720,15 @@ public struct FileRuleDescription: Sendable { | |
) | ||
}() | ||
|
||
/// the rule for detecting apinotes files. | ||
public static let apinotes: FileRuleDescription = { | ||
.init( | ||
rule: .apinotes, | ||
toolsVersion: .v6_3, | ||
fileTypes: ["apinotes"] | ||
) | ||
}() | ||
|
||
/// The rule for detecting header files. | ||
public static let header: FileRuleDescription = { | ||
.init( | ||
|
@@ -748,6 +816,7 @@ public struct FileRuleDescription: Sendable { | |
clang, | ||
asm, | ||
modulemap, | ||
apinotes, | ||
header, | ||
] | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should say headers