Skip to content

Introduce new defines to enable #bundle in Swift Packages #8556

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

Merged
merged 6 commits into from
Apr 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,12 @@ public final class SwiftModuleBuildDescription {
break
}

if bundlePath != nil {
compilationConditions += ["-DSWIFT_MODULE_RESOURCE_BUNDLE_AVAILABLE"]
} else {
compilationConditions += ["-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE"]
}

return compilationConditions
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,20 @@ extension PackagePIFProjectBuilder {
settings[.COREML_COMPILER_CONTAINER] = "swift-package"
}

if sourceModule.usesSwift {
// Leave an explicit indicator regarding whether we are generating a Bundle.module accessor.
// This will be read by the #bundle macro defined in Foundation.
if !shouldGenerateBundleAccessor {
// No resources, so explicitly indicate that.
// #bundle will then produce an error about there being no resources.
settings[.SWIFT_ACTIVE_COMPILATION_CONDITIONS].lazilyInitializeAndMutate(initialValue: ["$(inherited)"]) { $0.append("SWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE") }
} else if !(resourceBundleName?.isEmpty ?? true) {
// We have an explicit resource bundle via Bundle.module.
// #bundle should call into that.
settings[.SWIFT_ACTIVE_COMPILATION_CONDITIONS].lazilyInitializeAndMutate(initialValue: ["$(inherited)"]) { $0.append("SWIFT_MODULE_RESOURCE_BUNDLE_AVAILABLE") }
} // else we won't set either of those and just let #bundle point to the same bundle as the source code.
}

if desiredModuleType == .macro {
settings[.SWIFT_IMPLEMENTS_MACROS_FOR_MODULE_NAMES] = [sourceModule.c99name]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ extension PackagePIFProjectBuilder {

if result.shouldGenerateBundleAccessor {
settings[.GENERATE_RESOURCE_ACCESSORS] = "YES"

// Do not set `SWIFT_MODULE_RESOURCE_BUNDLE_AVAILABLE` here since it is just going to point to the same bundle as code.
// #bundle can use its default implementation for that.
}
if result.shouldGenerateEmbedInCodeAccessor {
settings[.GENERATE_EMBED_IN_CODE_ACCESSORS] = "YES"
Expand All @@ -264,6 +267,12 @@ extension PackagePIFProjectBuilder {

if result.shouldGenerateBundleAccessor {
settings[.GENERATE_RESOURCE_ACCESSORS] = "YES"

if mainModule.usesSwift {
settings[.SWIFT_ACTIVE_COMPILATION_CONDITIONS].lazilyInitializeAndMutate(initialValue: ["$(inherited)"]) { $0.append("SWIFT_MODULE_RESOURCE_BUNDLE_AVAILABLE") }
}
} else if mainModule.usesSwift {
settings[.SWIFT_ACTIVE_COMPILATION_CONDITIONS].lazilyInitializeAndMutate(initialValue: ["$(inherited)"]) { $0.append("SWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE") }
}
if result.shouldGenerateEmbedInCodeAccessor {
settings[.GENERATE_EMBED_IN_CODE_ACCESSORS] = "YES"
Expand Down Expand Up @@ -305,6 +314,9 @@ extension PackagePIFProjectBuilder {
settings[.GENERATE_RESOURCE_ACCESSORS] = "YES"
settings[.GENERATE_EMBED_IN_CODE_ACCESSORS] = "NO"

// Do not set `SWIFT_MODULE_RESOURCE_BUNDLE_AVAILABLE` here since it is just going to point to the same bundle as code.
// #bundle can use its default implementation for that.

// If we did not create a resource bundle target,
// we still need to add build tool commands for any generated files.
addBuildToolCommands(
Expand Down
15 changes: 15 additions & 0 deletions Sources/XCBuildSupport/PIFBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -488,19 +488,27 @@ final class PackagePIFProjectBuilder: PIFProjectBuilder {
settings[.GENERATE_INFOPLIST_FILE] = "YES"
}

var isSwiftModule = false
if let clangTarget = mainTarget.underlying as? ClangModule {
// Let the target itself find its own headers.
settings[.HEADER_SEARCH_PATHS, default: ["$(inherited)"]].append(clangTarget.includeDir.pathString)
settings[.GCC_C_LANGUAGE_STANDARD] = clangTarget.cLanguageStandard
settings[.CLANG_CXX_LANGUAGE_STANDARD] = clangTarget.cxxLanguageStandard
} else if let swiftTarget = mainTarget.underlying as? SwiftModule {
isSwiftModule = true
try settings.addSwiftVersionSettings(target: swiftTarget, parameters: self.parameters)
settings.addCommonSwiftSettings(package: self.package, target: mainTarget, parameters: self.parameters)
}

if let resourceBundle = addResourceBundle(for: mainTarget, in: pifTarget) {
settings[.PACKAGE_RESOURCE_BUNDLE_NAME] = resourceBundle
settings[.GENERATE_RESOURCE_ACCESSORS] = "YES"

if isSwiftModule {
settings[.SWIFT_ACTIVE_COMPILATION_CONDITIONS, default: ["$(inherited)"]].append("SWIFT_MODULE_RESOURCE_BUNDLE_AVAILABLE")
}
} else if isSwiftModule {
settings[.SWIFT_ACTIVE_COMPILATION_CONDITIONS, default: ["$(inherited)"]].append("SWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE")
}

// For targets, we use the common build settings for both the "Debug" and the "Release" configurations (all
Expand Down Expand Up @@ -654,6 +662,7 @@ final class PackagePIFProjectBuilder: PIFProjectBuilder {
let moduleMapFileContents: String?
let shouldImpartModuleMap: Bool

var isSwiftModule = false
if let clangTarget = target.underlying as? ClangModule {
// Let the target itself find its own headers.
settings[.HEADER_SEARCH_PATHS, default: ["$(inherited)"]].append(clangTarget.includeDir.pathString)
Expand All @@ -680,6 +689,7 @@ final class PackagePIFProjectBuilder: PIFProjectBuilder {
shouldImpartModuleMap = false
}
} else if let swiftTarget = target.underlying as? SwiftModule {
isSwiftModule = true
try settings.addSwiftVersionSettings(target: swiftTarget, parameters: self.parameters)

// Generate ObjC compatibility header for Swift library targets.
Expand Down Expand Up @@ -729,7 +739,12 @@ final class PackagePIFProjectBuilder: PIFProjectBuilder {
if let resourceBundle = addResourceBundle(for: target, in: pifTarget) {
settings[.PACKAGE_RESOURCE_BUNDLE_NAME] = resourceBundle
settings[.GENERATE_RESOURCE_ACCESSORS] = "YES"
if isSwiftModule {
settings[.SWIFT_ACTIVE_COMPILATION_CONDITIONS, default: ["$(inherited)"]].append("SWIFT_MODULE_RESOURCE_BUNDLE_AVAILABLE")
}
impartedSettings[.EMBED_PACKAGE_RESOURCE_BUNDLE_NAMES, default: ["$(inherited)"]].append(resourceBundle)
} else if isSwiftModule {
settings[.SWIFT_ACTIVE_COMPILATION_CONDITIONS, default: ["$(inherited)"]].append("SWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE")
}

// For targets, we use the common build settings for both the "Debug" and the "Release" configurations (all
Expand Down
16 changes: 15 additions & 1 deletion Tests/BuildTests/BuildPlanTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
.equal(self.j),
"-DSWIFT_PACKAGE",
"-DDEBUG",
"-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE",
"-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))",
.anySequence,
"-swift-version", "4",
Expand All @@ -811,6 +812,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
.equal(self.j),
"-DSWIFT_PACKAGE",
"-DDEBUG",
"-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE",
"-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))",
.anySequence,
"-swift-version", "4",
Expand Down Expand Up @@ -1224,6 +1226,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
"-O",
.equal(self.j),
"-DSWIFT_PACKAGE",
"-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE",
"-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))",
.anySequence,
"-swift-version", "4",
Expand Down Expand Up @@ -1318,6 +1321,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
"-O",
.equal(self.j),
"-DSWIFT_PACKAGE",
"-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE",
"-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))",
.anySequence,
"-swift-version", "4",
Expand Down Expand Up @@ -1863,6 +1867,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
.equal(self.j),
"-DSWIFT_PACKAGE",
"-DDEBUG",
"-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE",
"-Xcc",
"-fmodule-map-file=\(buildPath.appending(components: "lib.build", "module.modulemap"))",
"-Xcc", "-I", "-Xcc", "\(Pkg.appending(components: "Sources", "lib", "include"))",
Expand Down Expand Up @@ -2365,6 +2370,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
.equal(self.j),
"-DSWIFT_PACKAGE",
"-DDEBUG",
"-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE",
"-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))",
.anySequence,
"-swift-version", "4",
Expand All @@ -2387,6 +2393,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
.equal(self.j),
"-DSWIFT_PACKAGE",
"-DDEBUG",
"-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE",
"-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))",
.anySequence,
"-swift-version", "4",
Expand Down Expand Up @@ -2499,6 +2506,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
"-O",
.equal(self.j),
"-DSWIFT_PACKAGE",
"-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE",
"-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))",
.anySequence,
"-swift-version", "4",
Expand Down Expand Up @@ -2864,6 +2872,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
.equal(self.j),
"-DSWIFT_PACKAGE",
"-DDEBUG",
"-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE",
"-Xcc", "-fmodule-map-file=\(Clibgit.appending(components: "module.modulemap"))",
"-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))",
.anySequence,
Expand Down Expand Up @@ -3166,6 +3175,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
.equal(self.j),
"-DSWIFT_PACKAGE",
"-DDEBUG",
"-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE",
"-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))",
.anySequence,
"-swift-version", "4",
Expand All @@ -3185,6 +3195,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
.equal(self.j),
"-DSWIFT_PACKAGE",
"-DDEBUG",
"-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE",
"-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))",
.anySequence,
"-swift-version", "4",
Expand Down Expand Up @@ -3824,7 +3835,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
"-Onone",
"-enable-testing",
.equal(self.j),
"-DSWIFT_PACKAGE", "-DDEBUG",
"-DSWIFT_PACKAGE", "-DDEBUG", "-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE",
"-Xcc", "-fmodule-map-file=\(buildPath.appending(components: "lib.build", "module.modulemap"))",
"-Xcc", "-I", "-Xcc", "\(Pkg.appending(components: "Sources", "lib", "include"))",
"-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))",
Expand Down Expand Up @@ -5888,6 +5899,9 @@ class BuildPlanTestCase: BuildSystemProviderTestCase {
XCTAssertEqual(try barTarget.objects.map(\.pathString), [
buildPath.appending(components: "Bar.build", "Bar.swift.o").pathString,
])

XCTAssertTrue(try fooTarget.compileArguments().contains(["-DSWIFT_MODULE_RESOURCE_BUNDLE_AVAILABLE"]))
XCTAssertTrue(try barTarget.compileArguments().contains(["-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE"]))
}

func testSwiftWASIBundleAccessor() async throws {
Expand Down
2 changes: 1 addition & 1 deletion Tests/BuildTests/CrossCompilationBuildPlanTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ final class CrossCompilationBuildPlanTests: XCTestCase {
exe,
[
"-enable-batch-mode", "-serialize-diagnostics", "-Onone", "-enable-testing",
"-j3", "-DSWIFT_PACKAGE", "-DDEBUG", "-Xcc",
"-j3", "-DSWIFT_PACKAGE", "-DDEBUG", "-DSWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE", "-Xcc",
"-fmodule-map-file=\(buildPath.appending(components: "lib.build", "module.modulemap"))",
"-Xcc", "-I", "-Xcc", "\(pkgPath.appending(components: "Sources", "lib", "include"))",
"-module-cache-path", "\(buildPath.appending(components: "ModuleCache"))", .anySequence,
Expand Down
Loading