Replace single-package scaffolding with monorepo Package.swift generation
This commit is contained in:
parent
f6adf61167
commit
5278fe90c3
1 changed files with 117 additions and 0 deletions
|
|
@ -20,6 +20,7 @@ extension CodeGenerator {
|
|||
/// - repository: The parsed GIR repository containing namespace metadata,
|
||||
/// `<c:include>`, `<include>`, and `<package>` values.
|
||||
/// - Returns: A dictionary of relative path → file content.
|
||||
@available(*, deprecated, message: "Use generateMonorepoScaffolding(analysis:) for monorepo packages.")
|
||||
public static func generatePackageScaffolding(config: GenerationConfig, repository: Repository) -> [String: String] {
|
||||
var files: [String: String] = [:]
|
||||
let cName = "C\(config.library)"
|
||||
|
|
@ -114,6 +115,122 @@ extension CodeGenerator {
|
|||
return files
|
||||
}
|
||||
|
||||
// MARK: - Monorepo Package Scaffolding Generation
|
||||
|
||||
/// Generates all scaffolding files for the monorepo: Package.swift,
|
||||
/// C bridge module maps and umbrella headers, and re-export files.
|
||||
///
|
||||
/// - Parameter analysis: The resolved multi-package analysis.
|
||||
/// - Returns: A dictionary of relative path → file content.
|
||||
public static func generateMonorepoScaffolding(analysis: MultiPackageAnalysis) -> [String: String] {
|
||||
var files: [String: String] = [:]
|
||||
|
||||
// Re-export umbrella files
|
||||
let umbrellas = generateReexportUmbrellas(analysis: analysis)
|
||||
for (path, content) in umbrellas {
|
||||
files[path] = content
|
||||
}
|
||||
|
||||
// C bridge files
|
||||
for (moduleName, repo) in analysis.repositories {
|
||||
let cName = "C\(moduleName)"
|
||||
let ns = repo.namespaces.first { $0.name == moduleName } ?? repo.namespaces.first
|
||||
|
||||
let sharedLibrary = ns?.cSharedLibrary ?? ""
|
||||
let libraries = sharedLibrary.split(separator: ",").map(String.init)
|
||||
let allLinkNames = libraries.compactMap { extractLinkName(from: $0) }
|
||||
let lowerModName = moduleName.lowercased()
|
||||
let cHeader = repo.cHeaderPath
|
||||
let umbrellaHeader = cHeader.isEmpty
|
||||
? "#include <\(lowerModName)/\(lowerModName).h>"
|
||||
: "#include <\(cHeader)>"
|
||||
|
||||
// External C link names from GIR includes
|
||||
var externalLinks: [String] = []
|
||||
for include in repo.includedPackages {
|
||||
let el = include.name.lowercased()
|
||||
if !externalLinks.contains(el) {
|
||||
externalLinks.append(el)
|
||||
}
|
||||
}
|
||||
|
||||
let linkLines = (allLinkNames + externalLinks).map { " link \"\($0)\"" }.joined(separator: "\n")
|
||||
let moduleMap = """
|
||||
module \(cName) [system] {
|
||||
header "\(cName).h"
|
||||
\(linkLines)
|
||||
}
|
||||
"""
|
||||
files["Sources/\(cName)/module.modulemap"] = moduleMap
|
||||
files["Sources/\(cName)/\(cName).h"] = umbrellaHeader + "\n"
|
||||
}
|
||||
|
||||
// Monorepo Package.swift
|
||||
let packageSwift = generateMonorepoPackage(analysis: analysis)
|
||||
files["Package.swift"] = packageSwift
|
||||
|
||||
return files
|
||||
}
|
||||
|
||||
/// Generates the single monorepo Package.swift containing all targets.
|
||||
private static func generateMonorepoPackage(analysis: MultiPackageAnalysis) -> String {
|
||||
let moduleNames = analysis.repositories.keys.sorted()
|
||||
|
||||
// Products
|
||||
var products = ""
|
||||
for name in moduleNames {
|
||||
products += " .library(name: \"\(name)\", targets: [\"\(name)\"]),\n"
|
||||
}
|
||||
|
||||
// C system library targets
|
||||
var cTargets = ""
|
||||
for name in moduleNames {
|
||||
let cName = "C\(name)"
|
||||
cTargets += " .systemLibrary(name: \"\(cName)\", path: \"Sources/\(cName)\"),\n"
|
||||
}
|
||||
|
||||
// Swift wrapper targets
|
||||
var swiftTargets = ""
|
||||
for name in moduleNames {
|
||||
let cName = "C\(name)"
|
||||
let dirDeps = analysis.directDependencies[name] ?? []
|
||||
var depList = "\"\(cName)\""
|
||||
for dep in dirDeps.sorted() {
|
||||
depList += ", \"\(dep)\""
|
||||
}
|
||||
swiftTargets += """
|
||||
.target(
|
||||
name: "\(name)",
|
||||
dependencies: [\(depList)],
|
||||
swiftSettings: swiftSettings
|
||||
),
|
||||
|
||||
"""
|
||||
}
|
||||
|
||||
return """
|
||||
// swift-tools-version: 6.2
|
||||
import PackageDescription
|
||||
|
||||
let swiftSettings: [SwiftSetting] = [
|
||||
.enableExperimentalFeature("StrictConcurrency=complete"),
|
||||
.defaultIsolation(MainActor.self),
|
||||
.enableUpcomingFeature("NonisolatedNonsendingByDefault"),
|
||||
]
|
||||
|
||||
let package = Package(
|
||||
name: "gtk-swift",
|
||||
platforms: [.macOS(.v14)],
|
||||
products: [
|
||||
\(products) ],
|
||||
targets: [
|
||||
\(cTargets)
|
||||
\(swiftTargets) ]
|
||||
)
|
||||
|
||||
"""
|
||||
}
|
||||
|
||||
/// Extracts link name from a shared-library string like "libgtk-4.so.1" -> "gtk-4".
|
||||
private static func extractLinkName(from sharedLib: String) -> String? {
|
||||
guard sharedLib.hasPrefix("lib") else { return nil }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue