Skip to content

Commit 7e2db85

Browse files
authored
Support module aliasing for PIF gen with xcode build system in SwiftPM (#4196)
rdar://87363580
1 parent 2d04d7e commit 7e2db85

File tree

4 files changed

+234
-0
lines changed

4 files changed

+234
-0
lines changed

Sources/XCBuildSupport/PIF.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,7 @@ public enum PIF {
963963
case SPECIALIZATION_SDK_OPTIONS
964964
case SUPPORTED_PLATFORMS
965965
case SWIFT_ACTIVE_COMPILATION_CONDITIONS
966+
case SWIFT_MODULE_ALIASES
966967
}
967968

968969
public enum Platform: String, CaseIterable, Codable {

Sources/XCBuildSupport/PIFBuilder.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,9 @@ final class PackagePIFProjectBuilder: PIFProjectBuilder {
582582
// Disable code coverage linker flags since we're producing .o files. Otherwise, we will run into duplicated
583583
// symbols when there are more than one targets that produce .o as their product.
584584
settings[.CLANG_COVERAGE_MAPPING_LINKER_ARGS] = "NO"
585+
if let aliases = target.moduleAliases {
586+
settings[.SWIFT_MODULE_ALIASES] = aliases.map{ $0.key + "=" + $0.value }
587+
}
585588

586589
// Create a set of build settings that will be imparted to any target that depends on this one.
587590
var impartedSettings = PIF.BuildSettings()

Sources/Xcodeproj/XcodeProjectModel.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ public struct Xcode {
391391
public var SWIFT_ACTIVE_COMPILATION_CONDITIONS: [String]?
392392
public var SWIFT_FORCE_STATIC_LINK_STDLIB: String?
393393
public var SWIFT_FORCE_DYNAMIC_LINK_STDLIB: String?
394+
public var SWIFT_MODULE_ALIASES: [String: String]?
394395
public var SWIFT_OPTIMIZATION_LEVEL: String?
395396
public var SWIFT_VERSION: String?
396397
public var TARGET_NAME: String?
@@ -440,6 +441,7 @@ public struct Xcode {
440441
SWIFT_ACTIVE_COMPILATION_CONDITIONS: [String]? = nil,
441442
SWIFT_FORCE_STATIC_LINK_STDLIB: String? = nil,
442443
SWIFT_FORCE_DYNAMIC_LINK_STDLIB: String? = nil,
444+
SWIFT_MODULE_ALIASES: [String: String]? = nil,
443445
SWIFT_OPTIMIZATION_LEVEL: String? = nil,
444446
SWIFT_VERSION: String? = nil,
445447
TARGET_NAME: String? = nil,
@@ -488,6 +490,7 @@ public struct Xcode {
488490
self.SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_ACTIVE_COMPILATION_CONDITIONS
489491
self.SWIFT_FORCE_STATIC_LINK_STDLIB = SWIFT_FORCE_STATIC_LINK_STDLIB
490492
self.SWIFT_FORCE_DYNAMIC_LINK_STDLIB = SWIFT_FORCE_DYNAMIC_LINK_STDLIB
493+
self.SWIFT_MODULE_ALIASES = SWIFT_MODULE_ALIASES
491494
self.SWIFT_OPTIMIZATION_LEVEL = SWIFT_OPTIMIZATION_LEVEL
492495
self.SWIFT_VERSION = SWIFT_VERSION
493496
self.TARGET_NAME = TARGET_NAME

Tests/XCBuildSupportTests/PIFBuilderTests.swift

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,6 +1460,233 @@ class PIFBuilderTests: XCTestCase {
14601460
}
14611461
}
14621462

1463+
func testPIFGenWithModuleAliases() throws {
1464+
#if !os(macOS)
1465+
try XCTSkipIf(true, "test is only supported on macOS")
1466+
#endif
1467+
let fs = InMemoryFileSystem(emptyFiles:
1468+
"/App/Sources/App/main.swift",
1469+
"/App/Sources/Logging/lib.swift",
1470+
"/App/Sources/Utils/lib.swift",
1471+
"/Bar/Sources/Lib/lib.swift",
1472+
"/Bar/Sources/Logging/lib.swift"
1473+
)
1474+
1475+
let observability = ObservabilitySystem.makeForTesting()
1476+
let graph = try loadPackageGraph(
1477+
fs: fs,
1478+
manifests: [
1479+
Manifest.createRootManifest(
1480+
name: "App",
1481+
path: .init("/App"),
1482+
dependencies: [
1483+
.localSourceControl(path: .init("/Bar"), requirement: .branch("main")),
1484+
],
1485+
targets: [
1486+
.init(name: "App", dependencies: ["Logging", "Utils"], type: .executable),
1487+
.init(name: "Logging", dependencies: []),
1488+
.init(name: "Utils", dependencies: [
1489+
.product(name: "BarLib", package: "Bar", moduleAliases: ["Logging": "BarLogging"]),
1490+
]),
1491+
]),
1492+
Manifest.createLocalSourceControlManifest(
1493+
name: "Bar",
1494+
path: .init("/Bar"),
1495+
products: [
1496+
.init(name: "BarLib", type: .library(.dynamic), targets: ["Lib"]),
1497+
],
1498+
targets: [
1499+
.init(name: "Lib", dependencies: ["Logging"]),
1500+
.init(name: "Logging", dependencies: []),
1501+
]),
1502+
],
1503+
observabilityScope: observability.topScope
1504+
)
1505+
1506+
var pif: PIF.TopLevelObject!
1507+
try! withCustomEnv(["PKG_CONFIG_PATH": inputsDir.pathString]) {
1508+
let builder = PIFBuilder(
1509+
graph: graph,
1510+
parameters: .mock(),
1511+
fileSystem: localFileSystem,
1512+
observabilityScope: observability.topScope
1513+
)
1514+
pif = try builder.construct()
1515+
}
1516+
1517+
XCTAssertNoDiagnostics(observability.diagnostics)
1518+
1519+
PIFTester(pif) { workspace in
1520+
workspace.checkProject("PACKAGE:/App") { project in
1521+
project.checkTarget("PACKAGE-PRODUCT:App") { target in
1522+
XCTAssertEqual(target.name, "App_1DA2DD44_PackageProduct")
1523+
XCTAssertEqual(target.productType, .executable)
1524+
XCTAssertEqual(target.productName, "App")
1525+
XCTAssertEqual(target.dependencies, [
1526+
"PACKAGE-TARGET:Utils",
1527+
"PACKAGE-TARGET:Logging",
1528+
"PACKAGE-PRODUCT:BarLib",
1529+
])
1530+
XCTAssertEqual(target.frameworks, [
1531+
"PACKAGE-TARGET:Utils",
1532+
"PACKAGE-TARGET:Logging",
1533+
"PACKAGE-PRODUCT:BarLib",
1534+
])
1535+
1536+
target.checkBuildConfiguration("Debug") { configuration in
1537+
XCTAssertEqual(configuration.guid, "PACKAGE-PRODUCT:App::BUILDCONFIG_Debug")
1538+
XCTAssertEqual(configuration.name, "Debug")
1539+
configuration.checkBuildSettings { settings in
1540+
XCTAssertNil(settings[.SWIFT_MODULE_ALIASES])
1541+
}
1542+
}
1543+
1544+
target.checkBuildConfiguration("Release") { configuration in
1545+
XCTAssertEqual(configuration.guid, "PACKAGE-PRODUCT:App::BUILDCONFIG_Release")
1546+
XCTAssertEqual(configuration.name, "Release")
1547+
configuration.checkBuildSettings { settings in
1548+
XCTAssertNil(settings[.SWIFT_MODULE_ALIASES])
1549+
}
1550+
}
1551+
}
1552+
1553+
project.checkTarget("PACKAGE-TARGET:Utils") { target in
1554+
XCTAssertEqual(target.name, "Utils")
1555+
XCTAssertEqual(target.productType, .objectFile)
1556+
XCTAssertEqual(target.productName, "Utils.o")
1557+
XCTAssertEqual(target.dependencies, [
1558+
"PACKAGE-PRODUCT:BarLib",
1559+
])
1560+
1561+
target.checkBuildConfiguration("Debug") { configuration in
1562+
XCTAssertEqual(configuration.guid, "PACKAGE-TARGET:Utils::BUILDCONFIG_Debug")
1563+
XCTAssertEqual(configuration.name, "Debug")
1564+
configuration.checkBuildSettings { settings in
1565+
XCTAssertNil(settings[.SWIFT_MODULE_ALIASES])
1566+
}
1567+
}
1568+
1569+
target.checkBuildConfiguration("Release") { configuration in
1570+
XCTAssertEqual(configuration.guid, "PACKAGE-TARGET:Utils::BUILDCONFIG_Release")
1571+
XCTAssertEqual(configuration.name, "Release")
1572+
configuration.checkBuildSettings { settings in
1573+
XCTAssertNil(settings[.SWIFT_MODULE_ALIASES])
1574+
}
1575+
}
1576+
1577+
}
1578+
project.checkTarget("PACKAGE-TARGET:Logging") { target in
1579+
XCTAssertEqual(target.name, "Logging")
1580+
XCTAssertEqual(target.productType, .objectFile)
1581+
XCTAssertEqual(target.productName, "Logging.o")
1582+
XCTAssertEqual(target.dependencies, [])
1583+
1584+
target.checkBuildConfiguration("Debug") { configuration in
1585+
XCTAssertEqual(configuration.guid, "PACKAGE-TARGET:Logging::BUILDCONFIG_Debug")
1586+
XCTAssertEqual(configuration.name, "Debug")
1587+
configuration.checkBuildSettings { settings in
1588+
XCTAssertNil(settings[.SWIFT_MODULE_ALIASES])
1589+
}
1590+
}
1591+
1592+
target.checkBuildConfiguration("Release") { configuration in
1593+
XCTAssertEqual(configuration.guid, "PACKAGE-TARGET:Logging::BUILDCONFIG_Release")
1594+
XCTAssertEqual(configuration.name, "Release")
1595+
configuration.checkBuildSettings { settings in
1596+
XCTAssertNil(settings[.SWIFT_MODULE_ALIASES])
1597+
}
1598+
}
1599+
}
1600+
}
1601+
1602+
workspace.checkProject("PACKAGE:/Bar") { project in
1603+
project.checkTarget("PACKAGE-PRODUCT:BarLib") { target in
1604+
XCTAssertEqual(target.name, "BarLib_175D063FAE17B2_PackageProduct")
1605+
XCTAssertEqual(target.productType, .framework)
1606+
XCTAssertEqual(target.productName, "BarLib.framework")
1607+
XCTAssertEqual(target.dependencies, ["PACKAGE-TARGET:BarLogging", "PACKAGE-TARGET:Lib"])
1608+
XCTAssertEqual(target.frameworks, ["PACKAGE-TARGET:BarLogging", "PACKAGE-TARGET:Lib"])
1609+
1610+
target.checkBuildConfiguration("Debug") { configuration in
1611+
XCTAssertEqual(configuration.guid, "PACKAGE-PRODUCT:BarLib::BUILDCONFIG_Debug")
1612+
XCTAssertEqual(configuration.name, "Debug")
1613+
configuration.checkBuildSettings { settings in
1614+
XCTAssertNil(settings[.SWIFT_MODULE_ALIASES])
1615+
XCTAssertEqual(settings[.PRODUCT_MODULE_NAME], "BarLib")
1616+
XCTAssertEqual(settings[.PRODUCT_NAME], "BarLib")
1617+
XCTAssertEqual(settings[.TARGET_NAME], "BarLib")
1618+
}
1619+
}
1620+
1621+
target.checkBuildConfiguration("Release") { configuration in
1622+
XCTAssertEqual(configuration.guid, "PACKAGE-PRODUCT:BarLib::BUILDCONFIG_Release")
1623+
XCTAssertEqual(configuration.name, "Release")
1624+
configuration.checkBuildSettings { settings in
1625+
XCTAssertNil(settings[.SWIFT_MODULE_ALIASES])
1626+
XCTAssertEqual(settings[.PRODUCT_MODULE_NAME], "BarLib")
1627+
XCTAssertEqual(settings[.PRODUCT_NAME], "BarLib")
1628+
XCTAssertEqual(settings[.TARGET_NAME], "BarLib")
1629+
}
1630+
}
1631+
}
1632+
project.checkTarget("PACKAGE-TARGET:BarLogging") { target in
1633+
XCTAssertEqual(target.name, "BarLogging")
1634+
XCTAssertEqual(target.productType, .objectFile)
1635+
XCTAssertEqual(target.productName, "BarLogging.o")
1636+
XCTAssertEqual(target.dependencies, [])
1637+
XCTAssertEqual(target.frameworks, [])
1638+
1639+
target.checkBuildConfiguration("Debug") { configuration in
1640+
XCTAssertEqual(configuration.guid, "PACKAGE-TARGET:BarLogging::BUILDCONFIG_Debug")
1641+
XCTAssertEqual(configuration.name, "Debug")
1642+
configuration.checkBuildSettings { settings in
1643+
XCTAssertEqual(settings[.SWIFT_MODULE_ALIASES], ["Logging=BarLogging"])
1644+
XCTAssertEqual(settings[.PRODUCT_NAME], "BarLogging.o")
1645+
XCTAssertEqual(settings[.TARGET_NAME], "BarLogging")
1646+
}
1647+
}
1648+
1649+
target.checkBuildConfiguration("Release") { configuration in
1650+
XCTAssertEqual(configuration.guid, "PACKAGE-TARGET:BarLogging::BUILDCONFIG_Release")
1651+
XCTAssertEqual(configuration.name, "Release")
1652+
configuration.checkBuildSettings { settings in
1653+
XCTAssertEqual(settings[.SWIFT_MODULE_ALIASES], ["Logging=BarLogging"])
1654+
XCTAssertEqual(settings[.PRODUCT_NAME], "BarLogging.o")
1655+
XCTAssertEqual(settings[.TARGET_NAME], "BarLogging")
1656+
}
1657+
}
1658+
}
1659+
project.checkTarget("PACKAGE-TARGET:Lib") { target in
1660+
XCTAssertEqual(target.name, "Lib")
1661+
XCTAssertEqual(target.productType, .objectFile)
1662+
XCTAssertEqual(target.productName, "Lib.o")
1663+
XCTAssertEqual(target.dependencies, ["PACKAGE-TARGET:BarLogging"])
1664+
XCTAssertEqual(target.frameworks, [])
1665+
1666+
target.checkBuildConfiguration("Debug") { configuration in
1667+
XCTAssertEqual(configuration.guid, "PACKAGE-TARGET:Lib::BUILDCONFIG_Debug")
1668+
XCTAssertEqual(configuration.name, "Debug")
1669+
configuration.checkBuildSettings { settings in
1670+
XCTAssertEqual(settings[.SWIFT_MODULE_ALIASES], ["Logging=BarLogging"])
1671+
XCTAssertEqual(settings[.PRODUCT_NAME], "Lib.o")
1672+
XCTAssertEqual(settings[.TARGET_NAME], "Lib")
1673+
}
1674+
}
1675+
1676+
target.checkBuildConfiguration("Release") { configuration in
1677+
XCTAssertEqual(configuration.guid, "PACKAGE-TARGET:Lib::BUILDCONFIG_Release")
1678+
XCTAssertEqual(configuration.name, "Release")
1679+
configuration.checkBuildSettings { settings in
1680+
XCTAssertEqual(settings[.SWIFT_MODULE_ALIASES], ["Logging=BarLogging"])
1681+
XCTAssertEqual(settings[.PRODUCT_NAME], "Lib.o")
1682+
XCTAssertEqual(settings[.TARGET_NAME], "Lib")
1683+
}
1684+
}
1685+
}
1686+
}
1687+
}
1688+
}
1689+
14631690
func testLibraryTargetsAsDylib() throws {
14641691
#if !os(macOS)
14651692
try XCTSkipIf(true, "test is only supported on macOS")

0 commit comments

Comments
 (0)