Skip to content
Draft
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d408e5f
WIP - I made a test and it passed
mattmassicotte May 6, 2026
6f567fa
WIP - concept for actually resolving default settings
mattmassicotte May 7, 2026
19d4135
WIP - fill out public manifest API
mattmassicotte May 12, 2026
bd10172
WIP - migrate tests to dedicated file
mattmassicotte May 12, 2026
a6776b8
WIP - header search path test
mattmassicotte May 12, 2026
b99608a
WIP - store all settings in one array
mattmassicotte May 12, 2026
bfa3781
WIP - define tests
mattmassicotte May 12, 2026
e6c890f
WIP - linked lib tests
mattmassicotte May 12, 2026
e012316
WIP - linked framework tests
mattmassicotte May 12, 2026
911e698
WIP - interoperability tests
mattmassicotte May 12, 2026
c98df06
WIP - enableUpcomingFeature tests
mattmassicotte May 12, 2026
ac908f2
WIP - remove some leftover prints
mattmassicotte May 12, 2026
4c1ae70
WIP - enableExperimentalFeature tests
mattmassicotte May 12, 2026
97d259e
WIP - strictMemorySafety tests
mattmassicotte May 12, 2026
2d2670e
WIP - unsafeFlags tests
mattmassicotte May 12, 2026
39d7138
WIP - parse the rest of the default setting types
mattmassicotte May 12, 2026
fdf205a
WIP - swiftLanguageMode tests
mattmassicotte May 12, 2026
fc2c828
WIP - treatAllWarnings tests
mattmassicotte May 12, 2026
b300c59
WIP - treatWarning tests
mattmassicotte May 12, 2026
18dd205
WIP - enableWarning tests
mattmassicotte May 12, 2026
ece5e08
WIP - disableWarning tests
mattmassicotte May 12, 2026
16d0263
WIP - move defaultIsolation tests to the end
mattmassicotte May 12, 2026
80fa6ea
WIP - working on manifest loading
mattmassicotte May 12, 2026
c0631d0
WIP - fix up correctly parsing all default settings
mattmassicotte May 13, 2026
0f6abcc
WIP - experiment with unconditional overrides
mattmassicotte May 13, 2026
2899598
WIP - implement inheritance
mattmassicotte May 14, 2026
da2f568
WIP - some missing comments
mattmassicotte May 14, 2026
d68e423
WIP - introduce some subexpressions to help with parsing
mattmassicotte May 14, 2026
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
8 changes: 8 additions & 0 deletions Sources/PackageLoading/ManifestJSONParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ enum ManifestJSONParser {
struct Result {
var name: String
var defaultLocalization: String?
var defaultSwiftSettings: [TargetBuildSettingDescription.Setting]? = []
var defaultCSettings: [TargetBuildSettingDescription.Setting]? = []
var defaultCXXSettings: [TargetBuildSettingDescription.Setting]? = []
var defaultLinkerSettings: [TargetBuildSettingDescription.Setting]? = []
var platforms: [PlatformDescription] = []
var targets: [TargetDescription] = []
var pkgConfig: String?
Expand Down Expand Up @@ -107,6 +111,10 @@ enum ManifestJSONParser {
return Result(
name: input.package.name,
defaultLocalization: input.package.defaultLocalization?.tag,
defaultSwiftSettings: try input.package.defaultSwiftSettings?.map { try .init($0) },
defaultCSettings: try input.package.defaultCSettings?.map { try .init($0) },
defaultCXXSettings: try input.package.defaultCXXSettings?.map { try .init($0) },
defaultLinkerSettings: try input.package.defaultLinkerSettings?.map { try .init($0) },
platforms: try input.package.platforms.map { try Self.parsePlatforms($0) } ?? [],
targets: try input.package.targets.map { try Self.parseTarget(target: $0, identityResolver: identityResolver) },
pkgConfig: input.package.pkgConfig,
Expand Down
27 changes: 26 additions & 1 deletion Sources/PackageLoading/PackageBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,31 @@ public final class PackageBuilder {
}
}

private func resolvedSettings(for target: TargetDescription) -> [TargetBuildSettingDescription.Setting] {
var resolved = target.settings

let defaultSettings = manifest.defaultSettings ?? []

for defaultSetting in defaultSettings {
var eligible = true

// Look for an existing target setting that takes precedence. If none are found,
// the default is accepted.
for setting in resolved {
if setting.overridesDefault(defaultSetting) {
eligible = false
break
}
}

if eligible {
resolved.append(defaultSetting)
}
}

return resolved
}

/// Creates build setting assignment table for the given target.
func buildSettings(
for target: TargetDescription?,
Expand All @@ -1103,7 +1128,7 @@ public final class PackageBuilder {
table.add(versionAssignment, for: .SWIFT_VERSION)

// Process each setting.
for setting in target.settings {
for setting in resolvedSettings(for: target) {
if let traits = setting.condition?.traits, traits.intersection(self.enabledTraits.names).isEmpty {
// The setting is currently not enabled so we should skip it
continue
Expand Down
11 changes: 10 additions & 1 deletion Sources/PackageModel/Manifest/Manifest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ public final class Manifest: Sendable {
/// The declared package dependencies.
public let dependencies: [PackageDependency]

public let defaultSwiftSettings: [TargetBuildSettingDescription.Setting]?

/// The targets declared in the manifest.
public let targets: [TargetDescription]

Expand Down Expand Up @@ -116,6 +118,7 @@ public final class Manifest: Sendable {
packageKind: PackageReference.Kind,
packageLocation: String,
defaultLocalization: String?,
defaultSwiftSettings: [TargetBuildSettingDescription.Setting] = [],
platforms: [PlatformDescription],
version: TSCUtility.Version?,
revision: String?,
Expand All @@ -137,6 +140,7 @@ public final class Manifest: Sendable {
self.packageKind = packageKind
self.packageLocation = packageLocation
self.defaultLocalization = defaultLocalization
self.defaultSwiftSettings = defaultSwiftSettings
self.platforms = platforms
self.version = version
self.revision = revision
Expand Down Expand Up @@ -610,6 +614,10 @@ public final class Manifest: Sendable {
}
return self.targetsWithCommonSourceRoot(type: type).count == 1
}

public var defaultSettings: [TargetBuildSettingDescription.Setting] {
defaultSwiftSettings ?? []
}
}

extension Manifest: Hashable {
Expand All @@ -633,7 +641,7 @@ extension Manifest: Encodable {
case name, path, url, version, targetMap, toolsVersion,
pkgConfig, providers, cLanguageStandard, cxxLanguageStandard, swiftLanguageVersions,
dependencies, products, targets, traits, platforms, packageKind, revision,
defaultLocalization
defaultLocalization, defaultSwiftSettings
}

/// Coding user info key for dump-package command.
Expand All @@ -656,6 +664,7 @@ extension Manifest: Encodable {

try container.encode(self.toolsVersion, forKey: .toolsVersion)
try container.encode(self.defaultLocalization, forKey: .defaultLocalization)
try container.encode(self.defaultSwiftSettings, forKey: .defaultSwiftSettings)
try container.encode(self.pkgConfig, forKey: .pkgConfig)
try container.encode(self.providers, forKey: .providers)
try container.encode(self.cLanguageStandard, forKey: .cLanguageStandard)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,34 @@ public enum TargetBuildSettingDescription {
self.kind = kind
self.condition = condition
}

public func overridesDefault(_ defaultSetting: Setting) -> Bool {
guard tool == defaultSetting.tool else {
return false
}

switch (kind, defaultSetting.kind) {
case (.defaultIsolation, .defaultIsolation):
return true
case (.interoperabilityMode, .interoperabilityMode):
return true
case (.swiftLanguageMode, .swiftLanguageMode):
return true
case (.treatAllWarnings, .treatAllWarnings):
return true
case (.unsafeFlags, .unsafeFlags):
return true
case (.define, .define):
return true
case (.treatWarning(let value, _), .treatWarning(let defaultValue, _)):
return value == defaultValue
case (.enableWarning(let value), .disableWarning(let defaultValue)):
return value == defaultValue
case (.disableWarning(let value), .enableWarning(let defaultValue)):
return value == defaultValue
default:
return false
}
}
}
}
33 changes: 31 additions & 2 deletions Sources/Runtimes/PackageDescription/PackageDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,19 @@ public final class Package {
set { swiftLanguageModes = newValue }
}

/// The default Swift language settings merged with all per-target settings.
@available(_PackageDescription, introduced: 6.5)
public var defaultSwiftSettings: [SwiftSetting]?

@available(_PackageDescription, introduced: 6.5)
public var defaultCSettings: [CSetting]?

@available(_PackageDescription, introduced: 6.5)
public var defaultCXXSettings: [CXXSetting]?

@available(_PackageDescription, introduced: 6.5)
public var defaultLinkerSettings: [LinkerSetting]?

/// The C language standard to use for all C targets in this package.
public var cLanguageStandard: CLanguageStandard?

Expand Down Expand Up @@ -315,8 +328,12 @@ public final class Package {
dependencies: [Dependency] = [],
targets: [Target] = [],
swiftLanguageModes: [SwiftLanguageMode]? = nil,
defaultSwiftSettings: [SwiftSetting]? = nil,
cLanguageStandard: CLanguageStandard? = nil,
cxxLanguageStandard: CXXLanguageStandard? = nil
defaultCSettings: [CSetting]? = nil,
cxxLanguageStandard: CXXLanguageStandard? = nil,
defaultCXXSettings: [CXXSetting]? = nil,
defaultLinkerSettings: [LinkerSetting]? = nil
) {
self.name = name
self.defaultLocalization = defaultLocalization
Expand All @@ -328,8 +345,12 @@ public final class Package {
self.targets = targets
self.traits = []
self.swiftLanguageModes = swiftLanguageModes
self.defaultSwiftSettings = defaultSwiftSettings
self.cLanguageStandard = cLanguageStandard
self.defaultCSettings = defaultCSettings
self.cxxLanguageStandard = cxxLanguageStandard
self.defaultCXXSettings = defaultCXXSettings
self.defaultLinkerSettings = defaultLinkerSettings
registerExitHandler()
}

Expand Down Expand Up @@ -362,8 +383,12 @@ public final class Package {
dependencies: [Dependency] = [],
targets: [Target] = [],
swiftLanguageModes: [SwiftLanguageMode]? = nil,
defaultSwiftSettings: [SwiftSetting]? = nil,
cLanguageStandard: CLanguageStandard? = nil,
cxxLanguageStandard: CXXLanguageStandard? = nil
defaultCSettings: [CSetting]? = nil,
cxxLanguageStandard: CXXLanguageStandard? = nil,
defaultCXXSettings: [CXXSetting]? = nil,
defaultLinkerSettings: [LinkerSetting]? = nil
) {
self.name = name
self.defaultLocalization = defaultLocalization
Expand All @@ -375,8 +400,12 @@ public final class Package {
self.dependencies = dependencies
self.targets = targets
self.swiftLanguageModes = swiftLanguageModes
self.defaultSwiftSettings = defaultSwiftSettings
self.cLanguageStandard = cLanguageStandard
self.defaultCSettings = defaultCSettings
self.cxxLanguageStandard = cxxLanguageStandard
self.defaultCXXSettings = defaultCXXSettings
self.defaultLinkerSettings = defaultLinkerSettings
registerExitHandler()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,10 @@ enum Serialization {
let name: String
let platforms: [SupportedPlatform]?
let defaultLocalization: LanguageTag?
let defaultSwiftSettings: [SwiftSetting]?
let defaultCSettings: [CSetting]?
let defaultCXXSettings: [CXXSetting]?
let defaultLinkerSettings: [LinkerSetting]?
let pkgConfig: String?
let providers: [SystemPackageProvider]?
let targets: [Target]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,10 @@ extension Serialization.Package {
self.name = package.name
self.platforms = package.platforms?.map { .init($0) }
self.defaultLocalization = package.defaultLocalization.map { .init($0) }
self.defaultSwiftSettings = package.defaultSwiftSettings?.map { .init($0) }
self.defaultCSettings = package.defaultCSettings?.map { .init($0) }
self.defaultCXXSettings = package.defaultCXXSettings?.map { .init($0) }
self.defaultLinkerSettings = package.defaultLinkerSettings?.map { .init($0) }
self.pkgConfig = package.pkgConfig
self.providers = package.providers?.map { .init($0) }
self.targets = package.targets.map { .init($0) }
Expand Down
4 changes: 4 additions & 0 deletions Sources/_InternalTestSupport/ManifestExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ extension Manifest {
displayName: String,
path: AbsolutePath = .root,
defaultLocalization: String? = nil,
defaultSettings: [TargetBuildSettingDescription.Setting] = [],
platforms: [PlatformDescription] = [],
version: TSCUtility.Version? = nil,
toolsVersion: ToolsVersion = .v4,
Expand All @@ -42,6 +43,7 @@ extension Manifest {
packageIdentity: .plain(displayName.lowercased()),
packageLocation: path.pathString,
defaultLocalization: defaultLocalization,
defaultSettings: defaultSettings,
platforms: platforms,
version: version,
toolsVersion: toolsVersion,
Expand Down Expand Up @@ -226,6 +228,7 @@ extension Manifest {
packageIdentity: PackageIdentity,
packageLocation: String? = nil,
defaultLocalization: String? = nil,
defaultSettings: [TargetBuildSettingDescription.Setting] = [],
platforms: [PlatformDescription] = [],
version: TSCUtility.Version? = nil,
toolsVersion: ToolsVersion,
Expand All @@ -247,6 +250,7 @@ extension Manifest {
packageKind: packageKind,
packageLocation: packageLocation ?? path.pathString,
defaultLocalization: defaultLocalization,
defaultSwiftSettings: defaultSettings,
platforms: platforms,
version: version,
revision: .none,
Expand Down
Loading
Loading