diff --git a/Runtimes/cmake/modules/ResourceEmbedding.cmake b/Runtimes/cmake/modules/ResourceEmbedding.cmake index a45d6a788e4eb..385a8584c9b28 100644 --- a/Runtimes/cmake/modules/ResourceEmbedding.cmake +++ b/Runtimes/cmake/modules/ResourceEmbedding.cmake @@ -1,3 +1,9 @@ + +if(WIN32) + option(SWIFT_ASSEMBLY_VERSION "Assembly Version" "${PROJECT_VERSION}") + option(SWIFT_PUBLIC_KEY_TOKEN "Code Signing Identity" "0000000000000000") +endif() + function(generate_plist project_name project_version target) set(PLIST_INFO_PLIST "Info.plist") set(PLIST_INFO_NAME "${project_name}") @@ -62,7 +68,7 @@ function(embed_version_info target) get_target_property(_EVI_NAME ${target} NAME) # Pad the project version to a four-part `MAJOR.MINOR.PATCH.TWEAK` - string(REGEX MATCHALL "[0-9]+" version_parts "${PROJECT_VERSION}") + string(REGEX MATCHALL "[0-9]+" version_parts "${SWIFT_ASSEMBLY_VERSION}") list(LENGTH version_parts version_part_count) while(version_part_count LESS 4) list(APPEND version_parts "0") @@ -77,6 +83,8 @@ function(embed_version_info target) file(CONFIGURE OUTPUT ${_EVI_BINARY_DIR}/${_EVI_NAME}.rc.in CONTENT [[ +#include + 1 VERSIONINFO FILEVERSION @_EVI_VERSION_MAJOR@,@_EVI_VERSION_MINOR@,@_EVI_VERSION_PATCH@,@_EVI_VERSION_TWEAK@ PRODUCTVERSION @_EVI_VERSION_MAJOR@,@_EVI_VERSION_MINOR@,@_EVI_VERSION_PATCH@,@_EVI_VERSION_TWEAK@ @@ -143,7 +151,7 @@ function(embed_manifest target) get_target_property(_EM_NAME ${target} NAME) # Pad the project version to a four-part `MAJOR.MINOR.PATCH.TWEAK` - string(REGEX MATCHALL "[0-9]+" version_parts "${PROJECT_VERSION}") + string(REGEX MATCHALL "[0-9]+" version_parts "${SWIFT_ASSEMBLY_VERSION}") list(LENGTH version_parts version_part_count) while(version_part_count LESS 4) list(APPEND version_parts "0") @@ -155,6 +163,8 @@ function(embed_manifest target) list(GET version_parts 3 _EM_VERSION_TWEAK) set(_EM_VERSION_STRING "${_EM_VERSION_MAJOR}.${_EM_VERSION_MINOR}.${_EM_VERSION_PATCH}.${_EM_VERSION_TWEAK}") + string(TOLOWER "${SWIFT_PUBLIC_KEY_TOKEN}" _EM_PUBLIC_KEY_TOKEN) + # Evaluate variables file(CONFIGURE OUTPUT ${_EM_BINARY_DIR}/${_EM_NAME}-${_EM_VERSION_STRING}.1.manifest.in @@ -163,6 +173,7 @@ function(embed_manifest target) @@ -175,6 +186,8 @@ function(embed_manifest target) file(CONFIGURE OUTPUT ${_EM_BINARY_DIR}/${_EM_NAME}.rc.in CONTENT [[ +#include + 1 VERSIONINFO FILEVERSION @_EM_VERSION_MAJOR@,@_EM_VERSION_MINOR@,@_EM_VERSION_PATCH@,@_EM_VERSION_TWEAK@ PRODUCTVERSION @_EM_VERSION_MAJOR@,@_EM_VERSION_MINOR@,@_EM_VERSION_PATCH@,@_EM_VERSION_TWEAK@ diff --git a/utils/build.ps1 b/utils/build.ps1 index bbe612169bf44..4970eedba35b3 100644 --- a/utils/build.ps1 +++ b/utils/build.ps1 @@ -49,6 +49,11 @@ tracking. The product version to be used when building the installer. Supports semantic version strings (e.g., "1.0.0"). Default: "0.0.0" +.PARAMETER WindowsSxSAssemblyPublicKeyToken +The public key token to embed in Windows side-by-side assembly manifests. +This is identity metadata only; it does not sign binaries or catalogs. +Default: "0000000000000000" + .PARAMETER ToolchainIdentifier The toolchain version identifier for the toolchain being built. Default: Uses TOOLCHAIN_VERSION environment variable or "$USERNAME.development" @@ -152,6 +157,8 @@ param # Toolchain Version Info [string] $ProductVersion = "0.0.0", + [ValidatePattern("^[A-Fa-f0-9]{16}$")] + [string] $WindowsSxSAssemblyPublicKeyToken = "0000000000000000", [string] $ToolchainIdentifier = $(if ($env:TOOLCHAIN_VERSION) { $env:TOOLCHAIN_VERSION } else { "$env:USERNAME.development" }), # Toolchain Cross-compilation @@ -204,6 +211,7 @@ param $ErrorActionPreference = "Stop" Set-StrictMode -Version 3.0 +$WindowsSxSAssemblyPublicKeyToken = $WindowsSxSAssemblyPublicKeyToken.ToLowerInvariant() # Avoid being run in a "Developer" shell since this script launches its own sub-shells targeting # different architectures, and these variables cause confusion. @@ -1015,6 +1023,7 @@ function ConvertTo-FourPartVersion([string] $Version) { function Set-WindowsAssemblyManifest([string] $ImagePath, [string] $AssemblyVersion, [string] $ProcessorArchitecture, + [string] $PublicKeyToken, [string] $LogPrefix) { if (-not (Test-Path $ImagePath)) { throw "${LogPrefix}: '$ImagePath' does not exist" @@ -1032,8 +1041,12 @@ function Set-WindowsAssemblyManifest([string] $ImagePath, $ManifestXml = @" - + "@ @@ -1054,7 +1067,8 @@ function Set-WindowsAssemblyManifest([string] $ImagePath, function Test-WindowsAssemblyManifestMatchesImage([string] $ManifestPath, [string] $ImagePath, [string] $AssemblyVersion, - [string] $ProcessorArchitecture) { + [string] $ProcessorArchitecture, + [string] $PublicKeyToken) { $Doc = New-Object System.Xml.XmlDocument $Doc.Load($ManifestPath) @@ -1076,6 +1090,7 @@ function Test-WindowsAssemblyManifestMatchesImage([string] $ManifestPath, ($AssemblyIdentity.GetAttribute("name") -eq $AssemblyName) -and ($AssemblyIdentity.GetAttribute("version") -eq $AssemblyVersion) -and ($AssemblyIdentity.GetAttribute("processorArchitecture") -ieq $ProcessorArchitecture) -and + ($AssemblyIdentity.GetAttribute("publicKeyToken") -ieq $PublicKeyToken) -and ($File.GetAttribute("name") -eq $FileName) ) } @@ -1083,6 +1098,7 @@ function Test-WindowsAssemblyManifestMatchesImage([string] $ManifestPath, function Ensure-WindowsAssemblyManifest([string] $ImagePath, [string] $AssemblyVersion, [string] $ProcessorArchitecture, + [string] $PublicKeyToken, [string] $LogPrefix) { if (-not (Test-Path $ImagePath)) { throw "${LogPrefix}: '$ImagePath' does not exist" @@ -1100,7 +1116,8 @@ function Ensure-WindowsAssemblyManifest([string] $ImagePath, -ManifestPath $ExistingManifestPath ` -ImagePath $ImagePath ` -AssemblyVersion $AssemblyVersion ` - -ProcessorArchitecture $ProcessorArchitecture + -ProcessorArchitecture $ProcessorArchitecture ` + -PublicKeyToken $PublicKeyToken } catch { $KeepExistingManifest = $true throw "${LogPrefix}: '$ImagePath' has an unparsable RT_MANIFEST #1 (extracted to '$ExistingManifestPath')" @@ -1123,6 +1140,7 @@ function Ensure-WindowsAssemblyManifest([string] $ImagePath, -ImagePath $ImagePath ` -AssemblyVersion $AssemblyVersion ` -ProcessorArchitecture $ProcessorArchitecture ` + -PublicKeyToken $PublicKeyToken ` -LogPrefix $LogPrefix } finally { if (-not $KeepExistingManifest) { @@ -1133,11 +1151,13 @@ function Ensure-WindowsAssemblyManifest([string] $ImagePath, function New-WindowsManifestDependency([string] $Name, [string] $AssemblyVersion, - [string] $ProcessorArchitecture) { + [string] $ProcessorArchitecture, + [string] $PublicKeyToken) { return [pscustomobject]@{ Name = $Name Version = $AssemblyVersion ProcessorArchitecture = $ProcessorArchitecture + PublicKeyToken = $PublicKeyToken } } @@ -1197,6 +1217,7 @@ function Set-WindowsExecutableManifestDependencies([string] $ToolPath, $AsmId.SetAttribute("name", $Dependency.Name) $AsmId.SetAttribute("version", $Dependency.Version) $AsmId.SetAttribute("processorArchitecture", $Dependency.ProcessorArchitecture) + $AsmId.SetAttribute("publicKeyToken", $Dependency.PublicKeyToken) $AsmId.SetAttribute("language", "*") [void]$DepAsm.AppendChild($AsmId) [void]$Dep.AppendChild($DepAsm) @@ -2997,7 +3018,8 @@ function Set-WindowsSxSToolchainRuntime { [string] $AssemblyName = "swiftToolchainRuntime", # Windows SxS requires the canonical four-part `a.b.c.d` form. [string] $AssemblyVersion = "1.0.0.0", - [Parameter(Mandatory)] [string] $ProcessorArchitecture + [Parameter(Mandatory)] [string] $ProcessorArchitecture, + [string] $PublicKeyToken = $WindowsSxSAssemblyPublicKeyToken ) if (-not (Test-Path $BinaryDir)) { @@ -3046,8 +3068,12 @@ function Set-WindowsSxSToolchainRuntime { $BundleManifest = @" - + $FilesXml "@ @@ -3059,6 +3085,7 @@ $FilesXml Name = $AssemblyName Version = $AssemblyVersion ProcessorArchitecture = $ProcessorArchitecture + PublicKeyToken = $PublicKeyToken } foreach ($Tool in $Tools) { $ToolPath = if ([System.IO.Path]::IsPathRooted($Tool)) { @@ -3177,7 +3204,8 @@ function Set-WindowsSxSToolchainRuntimePerDLL { [Parameter(Mandatory)] [Hashtable] $EXEDependencies, [Parameter(Mandatory)] [string[]] $DLLsToInject, [Parameter(Mandatory)] [string] $AssemblyVersion, - [Parameter(Mandatory)] [string] $ProcessorArchitecture + [Parameter(Mandatory)] [string] $ProcessorArchitecture, + [string] $PublicKeyToken = $WindowsSxSAssemblyPublicKeyToken ) if (-not (Test-Path $BinaryDir)) { @@ -3211,6 +3239,7 @@ function Set-WindowsSxSToolchainRuntimePerDLL { -ImagePath $StagedDLL ` -AssemblyVersion $AssemblyVersion ` -ProcessorArchitecture $ProcessorArchitecture ` + -PublicKeyToken $PublicKeyToken ` -LogPrefix "Set-WindowsSxSToolchainRuntimePerDLL" Assert-WindowsManifestResourcesAreSxSSafe $StagedDLL "Set-WindowsSxSToolchainRuntimePerDLL" $Length = (Get-Item $StagedDLL).Length @@ -3244,7 +3273,7 @@ function Set-WindowsSxSToolchainRuntimePerDLL { $Dependencies = @( foreach ($DLLName in ($DirectRuntimeDeps | Sort-Object)) { - New-WindowsManifestDependency $DLLName $AssemblyVersion $ProcessorArchitecture + New-WindowsManifestDependency $DLLName $AssemblyVersion $ProcessorArchitecture $PublicKeyToken } ) Set-WindowsExecutableManifestDependencies $ToolPath $Dependencies "Set-WindowsSxSToolchainRuntimePerDLL" @@ -4133,6 +4162,7 @@ function Repair-WindowsSDKAssemblyManifests([Hashtable] $Platform, [string] $Run $Targets = New-Object System.Collections.Generic.List[string] foreach ($DLL in @( + "BlocksRuntime", "dispatch", "swiftDispatch", "Foundation", @@ -4157,6 +4187,7 @@ function Repair-WindowsSDKAssemblyManifests([Hashtable] $Platform, [string] $Run -ImagePath $Path ` -AssemblyVersion (ConvertTo-FourPartVersion $ProductVersion) ` -ProcessorArchitecture $Platform.Architecture.VSName ` + -PublicKeyToken $WindowsSxSAssemblyPublicKeyToken ` -LogPrefix "Repair-WindowsSDKAssemblyManifests" Assert-WindowsManifestResourcesAreSxSSafe $Path "Repair-WindowsSDKAssemblyManifests" } @@ -4232,6 +4263,8 @@ function Build-SDK([Hashtable] $Platform, [Hashtable] $Context) { BUILD_SHARED_LIBS = $BUILD_SHARED_LIBS; CMAKE_NINJA_FORCE_RESPONSE_FILE = "YES"; CMAKE_STATIC_LIBRARY_PREFIX_Swift = "lib"; + SWIFT_ASSEMBLY_VERSION = "$ProductVersion"; + SWIFT_PUBLIC_KEY_TOKEN = "$WindowsSxSAssemblyPublicKeyToken"; dispatch_DIR = (Get-ProjectCMakeModules $Platform ([Project]"${Variant}CDispatch")); @@ -4267,6 +4300,8 @@ function Build-SDK([Hashtable] $Platform, [Hashtable] $Context) { -Defines ($SDKInstallDefines + @{ BUILD_SHARED_LIBS = $BUILD_SHARED_LIBS; CMAKE_STATIC_LIBRARY_PREFIX_Swift = "lib"; + SWIFT_ASSEMBLY_VERSION = "$ProductVersion"; + SWIFT_PUBLIC_KEY_TOKEN = "$WindowsSxSAssemblyPublicKeyToken"; SwiftCore_DIR = "$RuntimeBinaryCache\cmake\SwiftCore"; @@ -4292,6 +4327,8 @@ function Build-SDK([Hashtable] $Platform, [Hashtable] $Context) { -Defines ($SDKInstallDefines + @{ BUILD_SHARED_LIBS = $BUILD_SHARED_LIBS; CMAKE_STATIC_LIBRARY_PREFIX_Swift = "lib"; + SWIFT_ASSEMBLY_VERSION = "$ProductVersion"; + SWIFT_PUBLIC_KEY_TOKEN = "$WindowsSxSAssemblyPublicKeyToken"; SwiftCore_DIR = "$RuntimeBinaryCache\cmake\SwiftCore"; @@ -4316,6 +4353,8 @@ function Build-SDK([Hashtable] $Platform, [Hashtable] $Context) { -Defines ($SDKInstallDefines + @{ BUILD_SHARED_LIBS = $BUILD_SHARED_LIBS; CMAKE_STATIC_LIBRARY_PREFIX_Swift = "lib"; + SWIFT_ASSEMBLY_VERSION = "$ProductVersion"; + SWIFT_PUBLIC_KEY_TOKEN = "$WindowsSxSAssemblyPublicKeyToken"; SwiftCore_DIR = "$RuntimeBinaryCache\cmake\SwiftCore"; SwiftOverlay_DIR = "$OverlayBinaryCache\cmake\SwiftOverlay"; @@ -4343,6 +4382,8 @@ function Build-SDK([Hashtable] $Platform, [Hashtable] $Context) { # FIXME(#83449): avoid using `SwiftCMakeConfig.h` CMAKE_CXX_FLAGS = @("-I$RuntimeBinaryCache\include"); CMAKE_STATIC_LIBRARY_PREFIX_Swift = "lib"; + SWIFT_ASSEMBLY_VERSION = "$ProductVersion"; + SWIFT_PUBLIC_KEY_TOKEN = "$WindowsSxSAssemblyPublicKeyToken"; SwiftCore_DIR = "$RuntimeBinaryCache\cmake\SwiftCore"; SwiftOverlay_DIR = "$OverlayBinaryCache\cmake\SwiftOverlay"; @@ -4369,6 +4410,8 @@ function Build-SDK([Hashtable] $Platform, [Hashtable] $Context) { # FIXME(#83449): avoid using `SwiftCMakeConfig.h` CMAKE_CXX_FLAGS = @("-I$RuntimeBinaryCache\include"); CMAKE_STATIC_LIBRARY_PREFIX_Swift = "lib"; + SWIFT_ASSEMBLY_VERSION = "$ProductVersion"; + SWIFT_PUBLIC_KEY_TOKEN = "$WindowsSxSAssemblyPublicKeyToken"; SwiftCore_DIR = "$RuntimeBinaryCache\cmake\SwiftCore"; SwiftOverlay_DIR = "$OverlayBinaryCache\cmake\SwiftOverlay"; @@ -4394,6 +4437,8 @@ function Build-SDK([Hashtable] $Platform, [Hashtable] $Context) { -Defines ($SDKInstallDefines + @{ BUILD_SHARED_LIBS = $BUILD_SHARED_LIBS; CMAKE_STATIC_LIBRARY_PREFIX_Swift = "lib"; + SWIFT_ASSEMBLY_VERSION = "$ProductVersion"; + SWIFT_PUBLIC_KEY_TOKEN = "$WindowsSxSAssemblyPublicKeyToken"; SwiftCore_DIR = "$RuntimeBinaryCache\cmake\SwiftCore"; SwiftOverlay_DIR = "$OverlayBinaryCache\cmake\SwiftOverlay"; @@ -4419,6 +4464,8 @@ function Build-SDK([Hashtable] $Platform, [Hashtable] $Context) { BUILD_SHARED_LIBS = $BUILD_SHARED_LIBS; CMAKE_FIND_PACKAGE_PREFER_CONFIG = "YES"; CMAKE_STATIC_LIBRARY_PREFIX_Swift = "lib"; + SWIFT_ASSEMBLY_VERSION = "$ProductVersion"; + SWIFT_PUBLIC_KEY_TOKEN = "$WindowsSxSAssemblyPublicKeyToken"; SwiftCore_DIR = "$RuntimeBinaryCache\cmake\SwiftCore"; SwiftOverlay_DIR = "$OverlayBinaryCache\cmake\SwiftOverlay"; @@ -4445,6 +4492,8 @@ function Build-SDK([Hashtable] $Platform, [Hashtable] $Context) { BUILD_SHARED_LIBS = $BUILD_SHARED_LIBS; CMAKE_FIND_PACKAGE_PREFER_CONFIG = "YES"; CMAKE_STATIC_LIBRARY_PREFIX_Swift = "lib"; + SWIFT_ASSEMBLY_VERSION = "$ProductVersion"; + SWIFT_PUBLIC_KEY_TOKEN = "$WindowsSxSAssemblyPublicKeyToken"; SwiftCore_DIR = "$RuntimeBinaryCache\cmake\SwiftCore"; SwiftOverlay_DIR = "$OverlayBinaryCache\cmake\SwiftOverlay"; @@ -5431,15 +5480,9 @@ function Stage-WindowsToolchainSxS([Hashtable] $Platform, # Build basename -> direct Swift runtime imports. Keep only edges within # the runtime DLL set; system and CRT DLLs are not part of the SxS graph. - # - # BlocksRuntime stays flat; the Swift runtime DLLs use private SxS. - $NonSxSRuntimeDLLs = New-Object System.Collections.Generic.HashSet[string] - [void]$NonSxSRuntimeDLLs.Add("BlocksRuntime") - $RuntimeBaseNames = @( $RuntimeDLLs | - ForEach-Object { [IO.Path]::GetFileNameWithoutExtension($_.Name) } | - Where-Object { -not $NonSxSRuntimeDLLs.Contains($_) } + ForEach-Object { [IO.Path]::GetFileNameWithoutExtension($_.Name) } ) $RuntimeSet = New-Object System.Collections.Generic.HashSet[string] foreach ($D in $RuntimeBaseNames) { [void]$RuntimeSet.Add($D) }