mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-11 00:31:11 +00:00
Compare commits
49 Commits
release-1.
...
dev/lhecke
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e249b10977 | ||
|
|
8f83322322 | ||
|
|
c627991522 | ||
|
|
f0705fb7f7 | ||
|
|
0425ab0c1d | ||
|
|
e9de646e54 | ||
|
|
8aefc7a697 | ||
|
|
1bec08ec0a | ||
|
|
c9e993a38e | ||
|
|
cd6b0832e2 | ||
|
|
8611d901b6 | ||
|
|
a19d30a25a | ||
|
|
709189d471 | ||
|
|
aa8ed8c2d4 | ||
|
|
3c3b1aac02 | ||
|
|
6775300f42 | ||
|
|
f5a703c711 | ||
|
|
7650ecf658 | ||
|
|
0073e36d81 | ||
|
|
245b13b94e | ||
|
|
a9f34e3095 | ||
|
|
c589784b54 | ||
|
|
910c61b7e1 | ||
|
|
0ee2c74cd4 | ||
|
|
125026dbb6 | ||
|
|
ce60bf290a | ||
|
|
e269945a74 | ||
|
|
fbe45fafb5 | ||
|
|
62766db94d | ||
|
|
b00b77a7ac | ||
|
|
4628ceb295 | ||
|
|
9a4f4abaf2 | ||
|
|
f6e9f91504 | ||
|
|
457bc65d7e | ||
|
|
4c3d3d83a5 | ||
|
|
af5a6ea640 | ||
|
|
ba39db52d7 | ||
|
|
3d737214a4 | ||
|
|
1324a0148a | ||
|
|
1bf2fcb6e0 | ||
|
|
95944e5939 | ||
|
|
488de2d42c | ||
|
|
bf8ef638b7 | ||
|
|
6a26fd68c4 | ||
|
|
d6eb022975 | ||
|
|
d0f66b9668 | ||
|
|
5c08a86c49 | ||
|
|
99abb2a6b5 | ||
|
|
c6215c8b51 |
7
.github/actions/spelling/allow/allow.txt
vendored
7
.github/actions/spelling/allow/allow.txt
vendored
@@ -1,4 +1,3 @@
|
||||
aci
|
||||
admins
|
||||
allcolors
|
||||
Apc
|
||||
@@ -9,12 +8,10 @@ breadcrumbs
|
||||
bsd
|
||||
calt
|
||||
ccmp
|
||||
ccon
|
||||
changelog
|
||||
clickable
|
||||
clig
|
||||
CMMI
|
||||
consvc
|
||||
copyable
|
||||
CtrlDToClose
|
||||
cybersecurity
|
||||
@@ -81,8 +78,6 @@ ok'd
|
||||
overlined
|
||||
pipeline
|
||||
postmodern
|
||||
Powerline
|
||||
powerline
|
||||
ptys
|
||||
qof
|
||||
qps
|
||||
@@ -93,7 +88,6 @@ reserialize
|
||||
reserializes
|
||||
rlig
|
||||
runtimes
|
||||
servicebus
|
||||
shcha
|
||||
slnt
|
||||
Sos
|
||||
@@ -116,7 +110,6 @@ unregister
|
||||
versioned
|
||||
vsdevcmd
|
||||
We'd
|
||||
westus
|
||||
wildcards
|
||||
XBox
|
||||
YBox
|
||||
|
||||
6
.github/actions/spelling/allow/apis.txt
vendored
6
.github/actions/spelling/allow/apis.txt
vendored
@@ -29,7 +29,6 @@ Dacl
|
||||
dataobject
|
||||
dcomp
|
||||
DERR
|
||||
delayimp
|
||||
dlldata
|
||||
DNE
|
||||
DONTADDTORECENT
|
||||
@@ -76,7 +75,6 @@ IConnection
|
||||
ICustom
|
||||
IDialog
|
||||
IDirect
|
||||
Idn
|
||||
IExplorer
|
||||
IFACEMETHOD
|
||||
IFile
|
||||
@@ -167,7 +165,6 @@ roundf
|
||||
RSHIFT
|
||||
SACL
|
||||
schandle
|
||||
SEH
|
||||
semver
|
||||
serializer
|
||||
SETVERSION
|
||||
@@ -213,10 +210,8 @@ UFIELD
|
||||
ULARGE
|
||||
UOI
|
||||
UPDATEINIFILE
|
||||
urlmon
|
||||
userenv
|
||||
USEROBJECTFLAGS
|
||||
Vcpp
|
||||
Viewbox
|
||||
virtualalloc
|
||||
vsnwprintf
|
||||
@@ -224,7 +219,6 @@ wcsstr
|
||||
wcstoui
|
||||
WDJ
|
||||
winhttp
|
||||
wininet
|
||||
winmain
|
||||
winsta
|
||||
winstamin
|
||||
|
||||
23
.github/actions/spelling/expect/expect.txt
vendored
23
.github/actions/spelling/expect/expect.txt
vendored
@@ -78,7 +78,6 @@ aumid
|
||||
Authenticode
|
||||
AUTOBUDDY
|
||||
AUTOCHECKBOX
|
||||
autocrlf
|
||||
autohide
|
||||
AUTOHSCROLL
|
||||
automagically
|
||||
@@ -192,10 +191,8 @@ changelist
|
||||
chaof
|
||||
charinfo
|
||||
CHARSETINFO
|
||||
chcbpat
|
||||
chh
|
||||
chk
|
||||
chshdng
|
||||
CHT
|
||||
Cic
|
||||
cielab
|
||||
@@ -224,7 +221,6 @@ cmt
|
||||
cmw
|
||||
cmyk
|
||||
CNL
|
||||
cnn
|
||||
cnt
|
||||
CNTRL
|
||||
Codeflow
|
||||
@@ -264,6 +260,7 @@ condrv
|
||||
conechokey
|
||||
conemu
|
||||
configurability
|
||||
confusables
|
||||
conhost
|
||||
conime
|
||||
conimeinfo
|
||||
@@ -413,6 +410,7 @@ DECANM
|
||||
DECARM
|
||||
DECAUPSS
|
||||
DECAWM
|
||||
DECBI
|
||||
DECBKM
|
||||
DECCARA
|
||||
DECCIR
|
||||
@@ -421,13 +419,16 @@ DECCKSR
|
||||
DECCOLM
|
||||
DECCRA
|
||||
DECCTR
|
||||
DECDC
|
||||
DECDHL
|
||||
decdld
|
||||
DECDMAC
|
||||
DECDWL
|
||||
DECEKBD
|
||||
DECERA
|
||||
DECFI
|
||||
DECFRA
|
||||
DECIC
|
||||
DECID
|
||||
DECINVM
|
||||
DECKPAM
|
||||
@@ -506,7 +507,6 @@ directio
|
||||
DIRECTX
|
||||
DISABLEDELAYEDEXPANSION
|
||||
DISABLENOSCROLL
|
||||
DISPATCHNOTIFY
|
||||
DISPLAYATTRIBUTE
|
||||
DISPLAYATTRIBUTEPROPERTY
|
||||
DISPLAYCHANGE
|
||||
@@ -575,6 +575,7 @@ EDITTEXT
|
||||
EDITUPDATE
|
||||
edputil
|
||||
Efast
|
||||
efghijklmn
|
||||
EHsc
|
||||
EINS
|
||||
EJO
|
||||
@@ -812,6 +813,7 @@ HIBYTE
|
||||
hicon
|
||||
HIDEWINDOW
|
||||
hinst
|
||||
Hirots
|
||||
HISTORYBUFS
|
||||
HISTORYNODUP
|
||||
HISTORYSIZE
|
||||
@@ -828,8 +830,6 @@ HMK
|
||||
hmod
|
||||
hmodule
|
||||
hmon
|
||||
homeglyphs
|
||||
homoglyph
|
||||
HORZ
|
||||
hostable
|
||||
hostlib
|
||||
@@ -976,6 +976,8 @@ KLF
|
||||
KLMNO
|
||||
KLMNOPQRST
|
||||
KLMNOPQRSTQQQQQ
|
||||
KLMNOPQRSTUVWXY
|
||||
KLMNOPQRSTY
|
||||
KOK
|
||||
KPRIORITY
|
||||
KVM
|
||||
@@ -1139,6 +1141,7 @@ mmsystem
|
||||
MNC
|
||||
MNOPQ
|
||||
MNOPQR
|
||||
MNOPQRSTUVWXY
|
||||
MODALFRAME
|
||||
MODERNCORE
|
||||
MONITORINFO
|
||||
@@ -1284,6 +1287,7 @@ nullability
|
||||
nullness
|
||||
nullonfailure
|
||||
nullopts
|
||||
NULs
|
||||
numlock
|
||||
numpad
|
||||
NUMSCROLL
|
||||
@@ -1772,6 +1776,7 @@ somefile
|
||||
SOURCEBRANCH
|
||||
sourced
|
||||
spammy
|
||||
spand
|
||||
SRCCODEPAGE
|
||||
SRCCOPY
|
||||
SRCINVERT
|
||||
@@ -2047,6 +2052,7 @@ USRDLL
|
||||
utr
|
||||
UVWX
|
||||
UVWXY
|
||||
UVWXYZ
|
||||
uwa
|
||||
uwp
|
||||
uxtheme
|
||||
@@ -2296,6 +2302,7 @@ xunit
|
||||
xutr
|
||||
XVIRTUALSCREEN
|
||||
XWalk
|
||||
xwwyzz
|
||||
xxyyzz
|
||||
yact
|
||||
YCast
|
||||
@@ -2306,7 +2313,9 @@ YOffset
|
||||
YSubstantial
|
||||
YVIRTUALSCREEN
|
||||
YWalk
|
||||
Zab
|
||||
zabcd
|
||||
Zabcdefghijklmn
|
||||
Zabcdefghijklmnopqrstuvwxyz
|
||||
ZCmd
|
||||
ZCtrl
|
||||
|
||||
@@ -420,6 +420,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TerminalStress", "src\tools
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenderingTests", "src\tools\RenderingTests\RenderingTests.vcxproj", "{37C995E0-2349-4154-8E77-4A52C0C7F46D}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tracy", "oss\tracy\tracy.vcxproj", "{93818413-1073-496A-A599-8450659BA190}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
AuditMode|Any CPU = AuditMode|Any CPU
|
||||
@@ -2798,6 +2800,32 @@ Global
|
||||
{37C995E0-2349-4154-8E77-4A52C0C7F46D}.Release|x64.Build.0 = Release|x64
|
||||
{37C995E0-2349-4154-8E77-4A52C0C7F46D}.Release|x86.ActiveCfg = Release|Win32
|
||||
{37C995E0-2349-4154-8E77-4A52C0C7F46D}.Release|x86.Build.0 = Release|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.AuditMode|ARM.ActiveCfg = AuditMode|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.AuditMode|ARM64.ActiveCfg = Release|ARM64
|
||||
{93818413-1073-496A-A599-8450659BA190}.AuditMode|x64.ActiveCfg = Release|x64
|
||||
{93818413-1073-496A-A599-8450659BA190}.AuditMode|x86.ActiveCfg = Release|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.Debug|ARM.ActiveCfg = Debug|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{93818413-1073-496A-A599-8450659BA190}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{93818413-1073-496A-A599-8450659BA190}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{93818413-1073-496A-A599-8450659BA190}.Debug|x64.Build.0 = Debug|x64
|
||||
{93818413-1073-496A-A599-8450659BA190}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.Debug|x86.Build.0 = Debug|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.Fuzzing|ARM.ActiveCfg = Fuzzing|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
|
||||
{93818413-1073-496A-A599-8450659BA190}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
|
||||
{93818413-1073-496A-A599-8450659BA190}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.Release|ARM.ActiveCfg = Release|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{93818413-1073-496A-A599-8450659BA190}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{93818413-1073-496A-A599-8450659BA190}.Release|x64.ActiveCfg = Release|x64
|
||||
{93818413-1073-496A-A599-8450659BA190}.Release|x64.Build.0 = Release|x64
|
||||
{93818413-1073-496A-A599-8450659BA190}.Release|x86.ActiveCfg = Release|Win32
|
||||
{93818413-1073-496A-A599-8450659BA190}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -2904,6 +2932,7 @@ Global
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD} = {40BD8415-DD93-4200-8D82-498DDDC08CC8}
|
||||
{613CCB57-5FA9-48EF-80D0-6B1E319E20C4} = {A10C4720-DCA4-4640-9749-67F4314F527C}
|
||||
{37C995E0-2349-4154-8E77-4A52C0C7F46D} = {A10C4720-DCA4-4640-9749-67F4314F527C}
|
||||
{93818413-1073-496A-A599-8450659BA190} = {A10C4720-DCA4-4640-9749-67F4314F527C}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}
|
||||
|
||||
175
build/Helix/AzurePipelinesHelperScripts.ps1
Normal file
175
build/Helix/AzurePipelinesHelperScripts.ps1
Normal file
@@ -0,0 +1,175 @@
|
||||
function GetAzureDevOpsBaseUri
|
||||
{
|
||||
Param(
|
||||
[string]$CollectionUri,
|
||||
[string]$TeamProject
|
||||
)
|
||||
|
||||
return $CollectionUri + $TeamProject
|
||||
}
|
||||
|
||||
function GetQueryTestRunsUri
|
||||
{
|
||||
Param(
|
||||
[string]$CollectionUri,
|
||||
[string]$TeamProject,
|
||||
[string]$BuildUri,
|
||||
[switch]$IncludeRunDetails
|
||||
)
|
||||
|
||||
if ($IncludeRunDetails)
|
||||
{
|
||||
$includeRunDetailsParameter = "&includeRunDetails=true"
|
||||
}
|
||||
else
|
||||
{
|
||||
$includeRunDetailsParameter = ""
|
||||
}
|
||||
|
||||
$baseUri = GetAzureDevOpsBaseUri -CollectionUri $CollectionUri -TeamProject $TeamProject
|
||||
$queryUri = "$baseUri/_apis/test/runs?buildUri=$BuildUri$includeRunDetailsParameter&api-version=5.0"
|
||||
return $queryUri
|
||||
}
|
||||
|
||||
function Get-HelixJobTypeFromTestRun
|
||||
{
|
||||
Param ($testRun)
|
||||
|
||||
$testRunSingleResultUri = "$($testRun.url)/results?`$top=1&`$skip=0&api-version=5.1"
|
||||
$singleTestResult = Invoke-RestMethod -Uri $testRunSingleResultUri -Method Get -Headers $azureDevOpsRestApiHeaders
|
||||
$count = $singleTestResult.value.Length
|
||||
if($count -eq 0)
|
||||
{
|
||||
# If the count is 0, then results have not yet been reported for this run.
|
||||
# We only care about completed runs with results, so it is ok to just return 'UNKNOWN' for this run.
|
||||
return "UNKNOWN"
|
||||
}
|
||||
else
|
||||
{
|
||||
$info = ConvertFrom-Json $singleTestResult.value.comment
|
||||
$helixJobId = $info.HelixJobId
|
||||
$job = Invoke-RestMethodWithRetries "https://helix.dot.net/api/2019-06-17/jobs/${helixJobId}?access_token=${HelixAccessToken}"
|
||||
return $job.Type
|
||||
}
|
||||
}
|
||||
|
||||
function Append-HelixAccessTokenToUrl
|
||||
{
|
||||
Param ([string]$url, [string]$token)
|
||||
if($url.Contains("?"))
|
||||
{
|
||||
$url = "$($url)&access_token=$($token)"
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = "$($url)?access_token=$($token)"
|
||||
}
|
||||
return $url
|
||||
}
|
||||
|
||||
|
||||
# The Helix Rest api is sometimes unreliable. So we call these apis with retry logic.
|
||||
# Note: The Azure DevOps apis are stable and do not need to be called with this retry logic.
|
||||
$helixApiRetries = 0
|
||||
$helixApiRetriesMax = 10
|
||||
|
||||
function Download-StringWithRetries
|
||||
{
|
||||
Param ([string]$fileName, [string]$url)
|
||||
|
||||
$result = ""
|
||||
$done = $false
|
||||
|
||||
while(!($done))
|
||||
{
|
||||
try
|
||||
{
|
||||
Write-Host "Downloading $fileName"
|
||||
$result = (New-Object System.Net.WebClient).DownloadString($url)
|
||||
$done = $true
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Host "Failed to download $fileName $($PSItem.Exception)"
|
||||
|
||||
$helixApiRetries = $helixApiRetries + 1
|
||||
if($helixApiRetries -lt $helixApiRetriesMax)
|
||||
{
|
||||
Write-Host "Sleep and retry download of $fileName"
|
||||
Start-Sleep 60
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "Failed to download $fileName"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
function Invoke-RestMethodWithRetries
|
||||
{
|
||||
Param ([string]$url,$Headers)
|
||||
|
||||
$result = @()
|
||||
$done = $false
|
||||
|
||||
while(!($done))
|
||||
{
|
||||
try
|
||||
{
|
||||
$result = Invoke-RestMethod -Uri $url -Method Get -Headers $Headers
|
||||
$done = $true
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Host "Failed to invoke Rest method $($PSItem.Exception)"
|
||||
|
||||
$helixApiRetries = $helixApiRetries + 1
|
||||
if($helixApiRetries -lt $helixApiRetriesMax)
|
||||
{
|
||||
Write-Host "Sleep and retry invoke"
|
||||
Start-Sleep 60
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "Failed to invoke Rest method"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
function Download-FileWithRetries
|
||||
{
|
||||
Param ([string]$fileurl, [string]$destination)
|
||||
|
||||
$done = $false
|
||||
|
||||
while(!($done))
|
||||
{
|
||||
try
|
||||
{
|
||||
Write-Host "Downloading $destination"
|
||||
$webClient.DownloadFile($fileurl, $destination)
|
||||
$done = $true
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Host "Failed to download $destination $($PSItem.Exception)"
|
||||
|
||||
$helixApiRetries = $helixApiRetries + 1
|
||||
if($helixApiRetries -lt $helixApiRetriesMax)
|
||||
{
|
||||
Write-Host "Sleep and retry download of $destination"
|
||||
Start-Sleep 60
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "Failed to download $destination"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
112
build/Helix/EnsureMachineState.ps1
Normal file
112
build/Helix/EnsureMachineState.ps1
Normal file
@@ -0,0 +1,112 @@
|
||||
$scriptDirectory = $script:MyInvocation.MyCommand.Path | Split-Path -Parent
|
||||
|
||||
# List all processes to aid debugging:
|
||||
Write-Host "All processes running:"
|
||||
Get-Process
|
||||
|
||||
tasklist /svc
|
||||
|
||||
# Add this test directory as an exclusion for Windows Defender
|
||||
Write-Host "Add $scriptDirectory as Exclusion Path"
|
||||
Add-MpPreference -ExclusionPath $scriptDirectory
|
||||
Write-Host "Add $($env:HELIX_CORRELATION_PAYLOAD) as Exclusion Path"
|
||||
Add-MpPreference -ExclusionPath $env:HELIX_CORRELATION_PAYLOAD
|
||||
Get-MpPreference
|
||||
Get-MpComputerStatus
|
||||
|
||||
|
||||
# Minimize all windows:
|
||||
$shell = New-Object -ComObject "Shell.Application"
|
||||
$shell.minimizeall()
|
||||
|
||||
# Kill any instances of Windows Security Alert:
|
||||
$windowTitleToMatch = "*Windows Security Alert*"
|
||||
$procs = Get-Process | Where {$_.MainWindowTitle -like "*Windows Security Alert*"}
|
||||
foreach ($proc in $procs)
|
||||
{
|
||||
Write-Host "Found process with '$windowTitleToMatch' title: $proc"
|
||||
$proc.Kill();
|
||||
}
|
||||
|
||||
# Kill processes by name that are known to interfere with our tests:
|
||||
$processNamesToStop = @("Microsoft.Photos", "WinStore.App", "SkypeApp", "SkypeBackgroundHost", "OneDriveSetup", "OneDrive")
|
||||
foreach($procName in $processNamesToStop)
|
||||
{
|
||||
Write-Host "Attempting to kill $procName if it is running"
|
||||
Stop-Process -ProcessName $procName -Verbose -ErrorAction Ignore
|
||||
}
|
||||
Write-Host "All processes running after attempting to kill unwanted processes:"
|
||||
Get-Process
|
||||
|
||||
tasklist /svc
|
||||
|
||||
$platform = $env:testbuildplatform
|
||||
if(!$platform)
|
||||
{
|
||||
$platform = "x86"
|
||||
}
|
||||
|
||||
function UninstallApps {
|
||||
Param([string[]]$appsToUninstall)
|
||||
|
||||
foreach($pkgName in $appsToUninstall)
|
||||
{
|
||||
foreach($pkg in (Get-AppxPackage $pkgName).PackageFullName)
|
||||
{
|
||||
Write-Output "Removing: $pkg"
|
||||
Remove-AppxPackage $pkg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function UninstallTestApps {
|
||||
Param([string[]]$appsToUninstall)
|
||||
|
||||
foreach($pkgName in $appsToUninstall)
|
||||
{
|
||||
foreach($pkg in (Get-AppxPackage $pkgName).PackageFullName)
|
||||
{
|
||||
Write-Output "Removing: $pkg"
|
||||
Remove-AppxPackage $pkg
|
||||
}
|
||||
|
||||
# Sometimes an app can get into a state where it is no longer returned by Get-AppxPackage, but it is still present
|
||||
# which prevents other versions of the app from being installed.
|
||||
# To handle this, we can directly call Remove-AppxPackage against the full name of the package. However, without
|
||||
# Get-AppxPackage to find the PackageFullName, we just have to manually construct the name.
|
||||
$packageFullName = "$($pkgName)_1.0.0.0_$($platform)__8wekyb3d8bbwe"
|
||||
Write-Host "Removing $packageFullName if installed"
|
||||
Remove-AppPackage $packageFullName -ErrorVariable appxerror -ErrorAction SilentlyContinue
|
||||
if($appxerror)
|
||||
{
|
||||
foreach($error in $appxerror)
|
||||
{
|
||||
# In most cases, Remove-AppPackage will fail due to the package not being found. Don't treat this as an error.
|
||||
if(!($error.Exception.Message -match "0x80073CF1"))
|
||||
{
|
||||
Write-Error $error
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "Successfully removed $packageFullName"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Uninstall AppX packages that are known to cause issues with our tests"
|
||||
UninstallApps("*Skype*", "*Windows.Photos*")
|
||||
|
||||
Write-Host "Uninstall any of our test apps that may have been left over from previous test runs"
|
||||
UninstallTestApps("NugetPackageTestApp", "NugetPackageTestAppCX", "IXMPTestApp", "MUXControlsTestApp")
|
||||
|
||||
Write-Host "Uninstall MUX Framework package that may have been left over from previous test runs"
|
||||
# We don't want to uninstall all versions of the MUX Framework package, as there may be other apps preinstalled on the system
|
||||
# that depend on it. We only uninstall the Framework package that corresponds to the version of MUX that we are testing.
|
||||
[xml]$versionData = (Get-Content "version.props")
|
||||
$versionMajor = $versionData.GetElementsByTagName("MUXVersionMajor").'#text'
|
||||
$versionMinor = $versionData.GetElementsByTagName("MUXVersionMinor").'#text'
|
||||
UninstallApps("Microsoft.UI.Xaml.$versionMajor.$versionMinor")
|
||||
|
||||
Get-Process
|
||||
336
build/Helix/GenerateTestProjFile.ps1
Normal file
336
build/Helix/GenerateTestProjFile.ps1
Normal file
@@ -0,0 +1,336 @@
|
||||
[CmdLetBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$TestFile,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$OutputProjFile,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$JobTestSuiteName,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$TaefPath,
|
||||
|
||||
[string]$TaefQuery
|
||||
)
|
||||
|
||||
Class TestCollection
|
||||
{
|
||||
[string]$Name
|
||||
[string]$SetupMethodName
|
||||
[string]$TeardownMethodName
|
||||
[System.Collections.Generic.Dictionary[string, string]]$Properties
|
||||
|
||||
TestCollection()
|
||||
{
|
||||
if ($this.GetType() -eq [TestCollection])
|
||||
{
|
||||
throw "This class should never be instantiated directly; it should only be derived from."
|
||||
}
|
||||
}
|
||||
|
||||
TestCollection([string]$name)
|
||||
{
|
||||
$this.Init($name)
|
||||
}
|
||||
|
||||
hidden Init([string]$name)
|
||||
{
|
||||
$this.Name = $name
|
||||
$this.Properties = @{}
|
||||
}
|
||||
}
|
||||
|
||||
Class Test : TestCollection
|
||||
{
|
||||
Test([string]$name)
|
||||
{
|
||||
$this.Init($name)
|
||||
}
|
||||
}
|
||||
|
||||
Class TestClass : TestCollection
|
||||
{
|
||||
[System.Collections.Generic.List[Test]]$Tests
|
||||
|
||||
TestClass([string]$name)
|
||||
{
|
||||
$this.Init($name)
|
||||
$this.Tests = @{}
|
||||
}
|
||||
}
|
||||
|
||||
Class TestModule : TestCollection
|
||||
{
|
||||
[System.Collections.Generic.List[TestClass]]$TestClasses
|
||||
|
||||
TestModule([string]$name)
|
||||
{
|
||||
$this.Init($name)
|
||||
$this.TestClasses = @{}
|
||||
}
|
||||
}
|
||||
|
||||
function Parse-TestInfo([string]$taefOutput)
|
||||
{
|
||||
enum LineType
|
||||
{
|
||||
None
|
||||
TestModule
|
||||
TestClass
|
||||
Test
|
||||
Setup
|
||||
Teardown
|
||||
Property
|
||||
}
|
||||
|
||||
[string]$testModuleIndentation = " "
|
||||
[string]$testClassIndentation = " "
|
||||
[string]$testIndentation = " "
|
||||
[string]$setupBeginning = "Setup: "
|
||||
[string]$teardownBeginning = "Teardown: "
|
||||
[string]$propertyBeginning = "Property["
|
||||
|
||||
function Get-LineType([string]$line)
|
||||
{
|
||||
if ($line.Contains($setupBeginning))
|
||||
{
|
||||
return [LineType]::Setup;
|
||||
}
|
||||
elseif ($line.Contains($teardownBeginning))
|
||||
{
|
||||
return [LineType]::Teardown;
|
||||
}
|
||||
elseif ($line.Contains($propertyBeginning))
|
||||
{
|
||||
return [LineType]::Property;
|
||||
}
|
||||
elseif ($line.StartsWith($testModuleIndentation) -and -not $line.StartsWith("$testModuleIndentation "))
|
||||
{
|
||||
return [LineType]::TestModule;
|
||||
}
|
||||
elseif ($line.StartsWith($testClassIndentation) -and -not $line.StartsWith("$testClassIndentation "))
|
||||
{
|
||||
return [LineType]::TestClass;
|
||||
}
|
||||
elseif ($line.StartsWith($testIndentation) -and -not $line.StartsWith("$testIndentation "))
|
||||
{
|
||||
return [LineType]::Test;
|
||||
}
|
||||
else
|
||||
{
|
||||
return [LineType]::None;
|
||||
}
|
||||
}
|
||||
|
||||
[string[]]$lines = $taefOutput.Split(@([Environment]::NewLine, "`n"), [StringSplitOptions]::RemoveEmptyEntries)
|
||||
[System.Collections.Generic.List[TestModule]]$testModules = @()
|
||||
|
||||
[TestModule]$currentTestModule = $null
|
||||
[TestClass]$currentTestClass = $null
|
||||
[Test]$currentTest = $null
|
||||
|
||||
[TestCollection]$lastTestCollection = $null
|
||||
|
||||
foreach ($rawLine in $lines)
|
||||
{
|
||||
[LineType]$lineType = (Get-LineType $rawLine)
|
||||
|
||||
# We don't need the whitespace around the line anymore, so we'll discard it to make things easier.
|
||||
[string]$line = $rawLine.Trim()
|
||||
|
||||
if ($lineType -eq [LineType]::TestModule)
|
||||
{
|
||||
if ($currentTest -ne $null -and $currentTestClass -ne $null)
|
||||
{
|
||||
$currentTestClass.Tests.Add($currentTest)
|
||||
}
|
||||
|
||||
if ($currentTestClass -ne $null -and $currentTestModule -ne $null)
|
||||
{
|
||||
$currentTestModule.TestClasses.Add($currentTestClass)
|
||||
}
|
||||
|
||||
if ($currentTestModule -ne $null)
|
||||
{
|
||||
$testModules.Add($currentTestModule)
|
||||
}
|
||||
|
||||
$currentTestModule = [TestModule]::new($line)
|
||||
$currentTestClass = $null
|
||||
$currentTest = $null
|
||||
$lastTestCollection = $currentTestModule
|
||||
}
|
||||
elseif ($lineType -eq [LineType]::TestClass)
|
||||
{
|
||||
if ($currentTest -ne $null -and $currentTestClass -ne $null)
|
||||
{
|
||||
$currentTestClass.Tests.Add($currentTest)
|
||||
}
|
||||
|
||||
if ($currentTestClass -ne $null -and $currentTestModule -ne $null)
|
||||
{
|
||||
$currentTestModule.TestClasses.Add($currentTestClass)
|
||||
}
|
||||
|
||||
$currentTestClass = [TestClass]::new($line)
|
||||
$currentTest = $null
|
||||
$lastTestCollection = $currentTestClass
|
||||
}
|
||||
elseif ($lineType -eq [LineType]::Test)
|
||||
{
|
||||
if ($currentTest -ne $null -and $currentTestClass -ne $null)
|
||||
{
|
||||
$currentTestClass.Tests.Add($currentTest)
|
||||
}
|
||||
|
||||
$currentTest = [Test]::new($line)
|
||||
$lastTestCollection = $currentTest
|
||||
}
|
||||
elseif ($lineType -eq [LineType]::Setup)
|
||||
{
|
||||
if ($lastTestCollection -ne $null)
|
||||
{
|
||||
$lastTestCollection.SetupMethodName = $line.Replace($setupBeginning, "")
|
||||
}
|
||||
}
|
||||
elseif ($lineType -eq [LineType]::Teardown)
|
||||
{
|
||||
if ($lastTestCollection -ne $null)
|
||||
{
|
||||
$lastTestCollection.TeardownMethodName = $line.Replace($teardownBeginning, "")
|
||||
}
|
||||
}
|
||||
elseif ($lineType -eq [LineType]::Property)
|
||||
{
|
||||
if ($lastTestCollection -ne $null)
|
||||
{
|
||||
foreach ($match in [Regex]::Matches($line, "Property\[(.*)\]\s+=\s+(.*)"))
|
||||
{
|
||||
[string]$propertyKey = $match.Groups[1].Value;
|
||||
[string]$propertyValue = $match.Groups[2].Value;
|
||||
$lastTestCollection.Properties.Add($propertyKey, $propertyValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($currentTest -ne $null -and $currentTestClass -ne $null)
|
||||
{
|
||||
$currentTestClass.Tests.Add($currentTest)
|
||||
}
|
||||
|
||||
if ($currentTestClass -ne $null -and $currentTestModule -ne $null)
|
||||
{
|
||||
$currentTestModule.TestClasses.Add($currentTestClass)
|
||||
}
|
||||
|
||||
if ($currentTestModule -ne $null)
|
||||
{
|
||||
$testModules.Add($currentTestModule)
|
||||
}
|
||||
|
||||
return $testModules
|
||||
}
|
||||
|
||||
Write-Verbose "TaefQuery = $TaefQuery"
|
||||
|
||||
$TaefSelectQuery = ""
|
||||
$TaefQueryToAppend = ""
|
||||
if($TaefQuery)
|
||||
{
|
||||
$TaefSelectQuery = "/select:`"$TaefQuery`""
|
||||
$TaefQueryToAppend = " and $TaefQuery"
|
||||
}
|
||||
Write-Verbose "TaefSelectQuery = $TaefSelectQuery"
|
||||
|
||||
|
||||
$taefExe = "$TaefPath\te.exe"
|
||||
[string]$taefOutput = & "$taefExe" /listproperties $TaefSelectQuery $TestFile | Out-String
|
||||
|
||||
[System.Collections.Generic.List[TestModule]]$testModules = (Parse-TestInfo $taefOutput)
|
||||
|
||||
$projFileContent = @"
|
||||
<Project>
|
||||
<ItemGroup>
|
||||
"@
|
||||
|
||||
foreach ($testModule in $testModules)
|
||||
{
|
||||
foreach ($testClass in $testModules.TestClasses)
|
||||
{
|
||||
Write-Host "Generating Helix work item for test class $($testClass.Name)..."
|
||||
[System.Collections.Generic.List[string]]$testSuiteNames = @()
|
||||
|
||||
$testSuiteExists = $false
|
||||
$suitelessTestExists = $false
|
||||
|
||||
foreach ($test in $testClass.Tests)
|
||||
{
|
||||
# A test method inherits its 'TestSuite' property from its TestClass
|
||||
if (!$test.Properties.ContainsKey("TestSuite") -and $testClass.Properties.ContainsKey("TestSuite"))
|
||||
{
|
||||
$test.Properties["TestSuite"] = $testClass.Properties["TestSuite"]
|
||||
}
|
||||
|
||||
if ($test.Properties.ContainsKey("TestSuite"))
|
||||
{
|
||||
[string]$testSuite = $test.Properties["TestSuite"]
|
||||
|
||||
if (-not $testSuiteNames.Contains($testSuite))
|
||||
{
|
||||
Write-Host " Found test suite $testSuite. Generating Helix work item for it as well."
|
||||
$testSuiteNames.Add($testSuite)
|
||||
}
|
||||
|
||||
$testSuiteExists = $true
|
||||
}
|
||||
else
|
||||
{
|
||||
$suitelessTestExists = $true
|
||||
}
|
||||
}
|
||||
|
||||
$testClassSelectPattern = "$($testClass.Name).*"
|
||||
if($testClass.Name.Contains("::"))
|
||||
{
|
||||
$testClassSelectPattern = "$($testClass.Name)::*"
|
||||
}
|
||||
$testNameQuery= "(@Name='$testClassSelectPattern')"
|
||||
|
||||
$workItemName = $testClass.Name
|
||||
# Native tests use '::' as a separator, which is not valid for workItem names.
|
||||
$workItemName = $workItemName -replace "::", "-"
|
||||
|
||||
if ($suitelessTestExists)
|
||||
{
|
||||
$projFileContent += @"
|
||||
|
||||
<HelixWorkItem Include="$($workItemName)" Condition="'`$(TestSuite)'=='$($JobTestSuiteName)'">
|
||||
<Timeout>00:30:00</Timeout>
|
||||
<Command>call %HELIX_CORRELATION_PAYLOAD%\runtests.cmd /select:"(@Name='$($testClass.Name)*'$(if ($testSuiteExists) { "and not @TestSuite='*'" }))$($TaefQueryToAppend)"</Command>
|
||||
</HelixWorkItem>
|
||||
"@
|
||||
}
|
||||
|
||||
foreach ($testSuiteName in $testSuiteNames)
|
||||
{
|
||||
$projFileContent += @"
|
||||
|
||||
<HelixWorkItem Include="$($workItemName)-$testSuiteName" Condition="'`$(TestSuite)'=='$($JobTestSuiteName)'">
|
||||
<Timeout>00:30:00</Timeout>
|
||||
<Command>call %HELIX_CORRELATION_PAYLOAD%\runtests.cmd /select:"(@Name='$($testClass.Name)*' and @TestSuite='$testSuiteName')$($TaefQueryToAppend)"</Command>
|
||||
</HelixWorkItem>
|
||||
"@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$projFileContent += @"
|
||||
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
"@
|
||||
|
||||
Set-Content $OutputProjFile $projFileContent -NoNewline -Encoding UTF8
|
||||
12
build/Helix/InstallTestAppDependencies.ps1
Normal file
12
build/Helix/InstallTestAppDependencies.ps1
Normal file
@@ -0,0 +1,12 @@
|
||||
# Displaying progress is unnecessary and is just distracting.
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
|
||||
$dependencyFiles = Get-ChildItem -Filter "*Microsoft.VCLibs.*.appx"
|
||||
|
||||
foreach ($file in $dependencyFiles)
|
||||
{
|
||||
Write-Host "Adding dependency $($file)..."
|
||||
|
||||
Add-AppxPackage $file
|
||||
|
||||
}
|
||||
8
build/Helix/OutputFailedTestQuery.ps1
Normal file
8
build/Helix/OutputFailedTestQuery.ps1
Normal file
@@ -0,0 +1,8 @@
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$WttInputPath
|
||||
)
|
||||
|
||||
Add-Type -Language CSharp -ReferencedAssemblies System.Xml,System.Xml.Linq,System.Runtime.Serialization,System.Runtime.Serialization.Json (Get-Content $PSScriptRoot\HelixTestHelpers.cs -Raw)
|
||||
|
||||
[HelixTestHelpers.FailedTestDetector]::OutputFailedTestQuery($WttInputPath)
|
||||
32
build/Helix/OutputSubResultsJsonFiles.ps1
Normal file
32
build/Helix/OutputSubResultsJsonFiles.ps1
Normal file
@@ -0,0 +1,32 @@
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$WttInputPath,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$WttSingleRerunInputPath,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$WttMultipleRerunInputPath,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$TestNamePrefix
|
||||
)
|
||||
|
||||
# Ideally these would be passed as parameters to the script. However ps makes it difficult to deal with string literals containing '&', so we just
|
||||
# read the values directly from the environment variables
|
||||
$helixResultsContainerUri = $Env:HELIX_RESULTS_CONTAINER_URI
|
||||
$helixResultsContainerRsas = $Env:HELIX_RESULTS_CONTAINER_RSAS
|
||||
|
||||
Add-Type -Language CSharp -ReferencedAssemblies System.Xml,System.Xml.Linq,System.Runtime.Serialization,System.Runtime.Serialization.Json (Get-Content $PSScriptRoot\HelixTestHelpers.cs -Raw)
|
||||
|
||||
$testResultParser = [HelixTestHelpers.TestResultParser]::new($TestNamePrefix, $helixResultsContainerUri, $helixResultsContainerRsas)
|
||||
[System.Collections.Generic.Dictionary[string, string]]$subResultsJsonByMethodName = $testResultParser.GetSubResultsJsonByMethodName($WttInputPath, $WttSingleRerunInputPath, $WttMultipleRerunInputPath)
|
||||
|
||||
$subResultsJsonDirectory = [System.IO.Path]::GetDirectoryName($WttInputPath)
|
||||
|
||||
foreach ($methodName in $subResultsJsonByMethodName.Keys)
|
||||
{
|
||||
$subResultsJson = $subResultsJsonByMethodName[$methodName]
|
||||
$subResultsJsonPath = [System.IO.Path]::Combine($subResultsJsonDirectory, $methodName + "_subresults.json")
|
||||
Out-File $subResultsJsonPath -Encoding utf8 -InputObject $subResultsJson
|
||||
}
|
||||
131
build/Helix/OutputTestResults.ps1
Normal file
131
build/Helix/OutputTestResults.ps1
Normal file
@@ -0,0 +1,131 @@
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]$MinimumExpectedTestsExecutedCount,
|
||||
|
||||
[string]$AccessToken = $env:SYSTEM_ACCESSTOKEN,
|
||||
[string]$CollectionUri = $env:SYSTEM_COLLECTIONURI,
|
||||
[string]$TeamProject = $env:SYSTEM_TEAMPROJECT,
|
||||
[string]$BuildUri = $env:BUILD_BUILDURI,
|
||||
[bool]$CheckJobAttempt
|
||||
)
|
||||
|
||||
$azureDevOpsRestApiHeaders = @{
|
||||
"Accept"="application/json"
|
||||
"Authorization"="Basic $([System.Convert]::ToBase64String([System.Text.ASCIIEncoding]::ASCII.GetBytes(":$AccessToken")))"
|
||||
}
|
||||
|
||||
. "$PSScriptRoot/AzurePipelinesHelperScripts.ps1"
|
||||
|
||||
Write-Host "Checking test results..."
|
||||
|
||||
$queryUri = GetQueryTestRunsUri -CollectionUri $CollectionUri -TeamProject $TeamProject -BuildUri $BuildUri -IncludeRunDetails
|
||||
Write-Host "queryUri = $queryUri"
|
||||
|
||||
$testRuns = Invoke-RestMethodWithRetries $queryUri -Headers $azureDevOpsRestApiHeaders
|
||||
[System.Collections.Generic.List[string]]$failingTests = @()
|
||||
[System.Collections.Generic.List[string]]$unreliableTests = @()
|
||||
[System.Collections.Generic.List[string]]$unexpectedResultTest = @()
|
||||
|
||||
[System.Collections.Generic.List[string]]$namesOfProcessedTestRuns = @()
|
||||
$totalTestsExecutedCount = 0
|
||||
|
||||
# We assume that we only have one testRun with a given name that we care about
|
||||
# We only process the last testRun with a given name (based on completedDate)
|
||||
# The name of a testRun is set to the Helix queue that it was run on (e.g. windows.10.amd64.client21h1.xaml)
|
||||
# If we have multiple test runs on the same queue that we care about, we will need to re-visit this logic
|
||||
foreach ($testRun in ($testRuns.value | Sort-Object -Property "completedDate" -Descending))
|
||||
{
|
||||
if ($CheckJobAttempt)
|
||||
{
|
||||
if ($namesOfProcessedTestRuns -contains $testRun.name)
|
||||
{
|
||||
Write-Host "Skipping test run '$($testRun.name)', since we have already processed a test run of that name."
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Processing results from test run '$($testRun.name)'"
|
||||
$namesOfProcessedTestRuns.Add($testRun.name)
|
||||
|
||||
$totalTestsExecutedCount += $testRun.totalTests
|
||||
|
||||
$testRunResultsUri = "$($testRun.url)/results?api-version=5.0"
|
||||
$testResults = Invoke-RestMethodWithRetries "$($testRun.url)/results?api-version=5.0" -Headers $azureDevOpsRestApiHeaders
|
||||
|
||||
foreach ($testResult in $testResults.value)
|
||||
{
|
||||
$shortTestCaseTitle = $testResult.testCaseTitle -replace "[a-zA-Z0-9]+.[a-zA-Z0-9]+.Windows.UI.Xaml.Tests.MUXControls.",""
|
||||
|
||||
if ($testResult.outcome -eq "Failed")
|
||||
{
|
||||
if (-not $failingTests.Contains($shortTestCaseTitle))
|
||||
{
|
||||
$failingTests.Add($shortTestCaseTitle)
|
||||
}
|
||||
}
|
||||
elseif ($testResult.outcome -eq "Warning")
|
||||
{
|
||||
if (-not $unreliableTests.Contains($shortTestCaseTitle))
|
||||
{
|
||||
$unreliableTests.Add($shortTestCaseTitle)
|
||||
}
|
||||
}
|
||||
elseif ($testResult.outcome -ne "Passed")
|
||||
{
|
||||
# We should only see tests with result "Passed", "Failed" or "Warning"
|
||||
if (-not $unexpectedResultTest.Contains($shortTestCaseTitle))
|
||||
{
|
||||
$unexpectedResultTest.Add($shortTestCaseTitle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($unreliableTests.Count -gt 0)
|
||||
{
|
||||
Write-Host @"
|
||||
##vso[task.logissue type=warning;]Unreliable tests:
|
||||
##vso[task.logissue type=warning;]$($unreliableTests -join "$([Environment]::NewLine)##vso[task.logissue type=warning;]")
|
||||
|
||||
"@
|
||||
}
|
||||
|
||||
if ($failingTests.Count -gt 0)
|
||||
{
|
||||
Write-Host @"
|
||||
##vso[task.logissue type=error;]Failing tests:
|
||||
##vso[task.logissue type=error;]$($failingTests -join "$([Environment]::NewLine)##vso[task.logissue type=error;]")
|
||||
|
||||
"@
|
||||
}
|
||||
|
||||
if ($unexpectedResultTest.Count -gt 0)
|
||||
{
|
||||
Write-Host @"
|
||||
##vso[task.logissue type=error;]Tests with unexpected results:
|
||||
##vso[task.logissue type=error;]$($unexpectedResultTest -join "$([Environment]::NewLine)##vso[task.logissue type=error;]")
|
||||
|
||||
"@
|
||||
}
|
||||
|
||||
if($totalTestsExecutedCount -lt $MinimumExpectedTestsExecutedCount)
|
||||
{
|
||||
Write-Host "Expected at least $MinimumExpectedTestsExecutedCount tests to be executed."
|
||||
Write-Host "Actual executed test count is: $totalTestsExecutedCount"
|
||||
Write-Host "##vso[task.complete result=Failed;]"
|
||||
}
|
||||
elseif ($failingTests.Count -gt 0)
|
||||
{
|
||||
Write-Host "At least one test failed."
|
||||
Write-Host "##vso[task.complete result=Failed;]"
|
||||
}
|
||||
elseif ($unreliableTests.Count -gt 0)
|
||||
{
|
||||
Write-Host "All tests eventually passed, but some initially failed."
|
||||
Write-Host "##vso[task.complete result=Succeeded;]"
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "All tests passed."
|
||||
Write-Host "##vso[task.complete result=Succeeded;]"
|
||||
}
|
||||
62
build/Helix/PrepareHelixPayload.ps1
Normal file
62
build/Helix/PrepareHelixPayload.ps1
Normal file
@@ -0,0 +1,62 @@
|
||||
[CmdLetBinding()]
|
||||
Param(
|
||||
[string]$Platform,
|
||||
[string]$Configuration,
|
||||
[string]$ArtifactName='drop'
|
||||
)
|
||||
|
||||
$payloadDir = "HelixPayload\$Configuration\$Platform"
|
||||
|
||||
$repoDirectory = Join-Path (Split-Path -Parent $script:MyInvocation.MyCommand.Path) "..\..\"
|
||||
$nugetPackagesDir = Join-Path (Split-Path -Parent $script:MyInvocation.MyCommand.Path) "packages"
|
||||
|
||||
# Create the payload directory. Remove it if it already exists.
|
||||
If(test-path $payloadDir)
|
||||
{
|
||||
Remove-Item $payloadDir -Recurse
|
||||
}
|
||||
New-Item -ItemType Directory -Force -Path $payloadDir
|
||||
|
||||
# Copy files from nuget packages
|
||||
Copy-Item "$nugetPackagesDir\microsoft.windows.apps.test.1.0.181203002\lib\netcoreapp2.1\*.dll" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.60.210621002\build\Binaries\$Platform\*" $payloadDir
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Taef.10.60.210621002\build\Binaries\$Platform\NetFx4.5\*" $payloadDir
|
||||
New-Item -ItemType Directory -Force -Path "$payloadDir\.NETCoreApp2.1\"
|
||||
Copy-Item "$nugetPackagesDir\runtime.win-$Platform.microsoft.netcore.app.2.1.0\runtimes\win-$Platform\lib\netcoreapp2.1\*" "$payloadDir\.NETCoreApp2.1\"
|
||||
Copy-Item "$nugetPackagesDir\runtime.win-$Platform.microsoft.netcore.app.2.1.0\runtimes\win-$Platform\native\*" "$payloadDir\.NETCoreApp2.1\"
|
||||
New-Item -ItemType Directory -Force -Path "$payloadDir\content\"
|
||||
Copy-Item "$nugetPackagesDir\Microsoft.Internal.Windows.Terminal.TestContent.1.0.1\content\*" "$payloadDir\content\"
|
||||
|
||||
function Copy-If-Exists
|
||||
{
|
||||
Param($source, $destinationDir)
|
||||
|
||||
if (Test-Path $source)
|
||||
{
|
||||
Write-Host "Copy from '$source' to '$destinationDir'"
|
||||
Copy-Item -Force $source $destinationDir
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "'$source' does not exist."
|
||||
}
|
||||
}
|
||||
|
||||
# Copy files from the 'drop' artifact dir
|
||||
Copy-Item "$repoDirectory\Artifacts\$ArtifactName\$Configuration\$Platform\Test\*" $payloadDir -Recurse
|
||||
|
||||
# Copy files from the repo
|
||||
New-Item -ItemType Directory -Force -Path "$payloadDir"
|
||||
Copy-Item "build\helix\ConvertWttLogToXUnit.ps1" "$payloadDir"
|
||||
Copy-Item "build\helix\OutputFailedTestQuery.ps1" "$payloadDir"
|
||||
Copy-Item "build\helix\OutputSubResultsJsonFiles.ps1" "$payloadDir"
|
||||
Copy-Item "build\helix\HelixTestHelpers.cs" "$payloadDir"
|
||||
Copy-Item "build\helix\runtests.cmd" $payloadDir
|
||||
Copy-Item "build\helix\InstallTestAppDependencies.ps1" "$payloadDir"
|
||||
Copy-Item "build\Helix\EnsureMachineState.ps1" "$payloadDir"
|
||||
|
||||
# Extract the unpackaged distribution of Windows Terminal to the payload directory,
|
||||
# where it will create a subdirectory named terminal-0.0.1.0
|
||||
# This is referenced in TerminalApp.cs later as part of the test harness.
|
||||
& tar -x -v -f "$repoDirectory\Artifacts\$ArtifactName\unpackaged\WindowsTerminalDev_0.0.1.0_x64.zip" -C "$payloadDir"
|
||||
Copy-Item "res\fonts\*.ttf" "$payloadDir\terminal-0.0.1.0"
|
||||
130
build/Helix/ProcessHelixFiles.ps1
Normal file
130
build/Helix/ProcessHelixFiles.ps1
Normal file
@@ -0,0 +1,130 @@
|
||||
Param(
|
||||
[string]$AccessToken = $env:SYSTEM_ACCESSTOKEN,
|
||||
[string]$HelixAccessToken = $env:HelixAccessToken,
|
||||
[string]$CollectionUri = $env:SYSTEM_COLLECTIONURI,
|
||||
[string]$TeamProject = $env:SYSTEM_TEAMPROJECT,
|
||||
[string]$BuildUri = $env:BUILD_BUILDURI,
|
||||
[string]$OutputFolder = "HelixOutput"
|
||||
)
|
||||
|
||||
$helixLinkFile = "$OutputFolder\LinksToHelixTestFiles.html"
|
||||
|
||||
|
||||
function Generate-File-Links
|
||||
{
|
||||
Param ([Array[]]$files,[string]$sectionName)
|
||||
if($files.Count -gt 0)
|
||||
{
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<div class=$sectionName>"
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<h4>$sectionName</h4>"
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<ul>"
|
||||
foreach($file in $files)
|
||||
{
|
||||
$url = Append-HelixAccessTokenToUrl $file.Link "{Your-Helix-Access-Token-Here}"
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<li>$($url)</li>"
|
||||
}
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "</ul>"
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "</div>"
|
||||
}
|
||||
}
|
||||
|
||||
function Append-HelixAccessTokenToUrl
|
||||
{
|
||||
Param ([string]$url, [string]$token)
|
||||
if($token)
|
||||
{
|
||||
if($url.Contains("?"))
|
||||
{
|
||||
$url = "$($url)&access_token=$($token)"
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = "$($url)?access_token=$($token)"
|
||||
}
|
||||
}
|
||||
return $url
|
||||
}
|
||||
|
||||
#Create output directory
|
||||
New-Item $OutputFolder -ItemType Directory
|
||||
|
||||
$azureDevOpsRestApiHeaders = @{
|
||||
"Accept"="application/json"
|
||||
"Authorization"="Basic $([System.Convert]::ToBase64String([System.Text.ASCIIEncoding]::ASCII.GetBytes(":$AccessToken")))"
|
||||
}
|
||||
|
||||
. "$PSScriptRoot/AzurePipelinesHelperScripts.ps1"
|
||||
|
||||
$queryUri = GetQueryTestRunsUri -CollectionUri $CollectionUri -TeamProject $TeamProject -BuildUri $BuildUri -IncludeRunDetails
|
||||
Write-Host "queryUri = $queryUri"
|
||||
|
||||
$testRuns = Invoke-RestMethodWithRetries $queryUri -Headers $azureDevOpsRestApiHeaders
|
||||
$webClient = New-Object System.Net.WebClient
|
||||
[System.Collections.Generic.List[string]]$workItems = @()
|
||||
|
||||
foreach ($testRun in $testRuns.value)
|
||||
{
|
||||
Write-Host "testRunUri = $testRun.url"
|
||||
$testResults = Invoke-RestMethodWithRetries "$($testRun.url)/results?api-version=5.0" -Headers $azureDevOpsRestApiHeaders
|
||||
$isTestRunNameShown = $false
|
||||
|
||||
foreach ($testResult in $testResults.value)
|
||||
{
|
||||
$info = ConvertFrom-Json ([System.Web.HttpUtility]::HtmlDecode($testResult.comment))
|
||||
$helixJobId = $info.HelixJobId
|
||||
$helixWorkItemName = $info.HelixWorkItemName
|
||||
|
||||
$workItem = "$helixJobId-$helixWorkItemName"
|
||||
|
||||
Write-Host "Helix Work Item = $workItem"
|
||||
|
||||
if (-not $workItems.Contains($workItem))
|
||||
{
|
||||
$workItems.Add($workItem)
|
||||
$filesQueryUri = "https://helix.dot.net/api/2019-06-17/jobs/$helixJobId/workitems/$helixWorkItemName/files"
|
||||
$filesQueryUri = Append-HelixAccessTokenToUrl $filesQueryUri $helixAccessToken
|
||||
$files = Invoke-RestMethodWithRetries $filesQueryUri
|
||||
|
||||
$screenShots = $files | where { $_.Name.EndsWith(".jpg") }
|
||||
$dumps = $files | where { $_.Name.EndsWith(".dmp") }
|
||||
$pgcFiles = $files | where { $_.Name.EndsWith(".pgc") }
|
||||
if ($screenShots.Count + $dumps.Count + $pgcFiles.Count -gt 0)
|
||||
{
|
||||
if(-Not $isTestRunNameShown)
|
||||
{
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<h2>$($testRun.name)</h2>"
|
||||
$isTestRunNameShown = $true
|
||||
}
|
||||
Out-File -FilePath $helixLinkFile -Append -InputObject "<h3>$helixWorkItemName</h3>"
|
||||
Generate-File-Links $screenShots "Screenshots"
|
||||
Generate-File-Links $dumps "CrashDumps"
|
||||
Generate-File-Links $pgcFiles "PGC files"
|
||||
$misc = $files | where { ($screenShots -NotContains $_) -And ($dumps -NotContains $_) -And ($visualTreeVerificationFiles -NotContains $_) -And ($pgcFiles -NotContains $_) }
|
||||
Generate-File-Links $misc "Misc"
|
||||
|
||||
foreach($pgcFile in $pgcFiles)
|
||||
{
|
||||
$flavorPath = $testResult.automatedTestName.Split('.')[0]
|
||||
$archPath = $testResult.automatedTestName.Split('.')[1]
|
||||
$fileName = $pgcFile.Name
|
||||
$fullPath = "$OutputFolder\PGO\$flavorPath\$archPath"
|
||||
$destination = "$fullPath\$fileName"
|
||||
|
||||
Write-Host "Copying $($pgcFile.Name) to $destination"
|
||||
|
||||
if (-Not (Test-Path $fullPath))
|
||||
{
|
||||
New-Item $fullPath -ItemType Directory
|
||||
}
|
||||
|
||||
$link = $pgcFile.Link
|
||||
|
||||
Write-Host "Downloading $link to $destination"
|
||||
|
||||
$link = Append-HelixAccessTokenToUrl $link $HelixAccessToken
|
||||
Download-FileWithRetries $link $destination
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
20
build/Helix/RunTestsInHelix.proj
Normal file
20
build/Helix/RunTestsInHelix.proj
Normal file
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.DotNet.Helix.Sdk" DefaultTargets="Test">
|
||||
<PropertyGroup>
|
||||
<HelixSource>pr/terminal/$(BUILD_SOURCEBRANCH)/</HelixSource>
|
||||
<EnableXUnitReporter>true</EnableXUnitReporter>
|
||||
<EnableAzurePipelinesReporter>true</EnableAzurePipelinesReporter>
|
||||
<FailOnMissionControlTestFailure>true</FailOnMissionControlTestFailure>
|
||||
<HelixPreCommands>$(HelixPreCommands);set testnameprefix=$(Configuration).$(Platform);set testbuildplatform=$(Platform);set rerunPassesRequiredToAvoidFailure=$(rerunPassesRequiredToAvoidFailure)</HelixPreCommands>
|
||||
<OutputPath>..\..\bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<HelixCorrelationPayload Include="..\..\HelixPayload\$(Configuration)\$(Platform)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- These .proj files are generated by the build machine prior to running tests via GenerateTestProjFile.ps1. -->
|
||||
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-TerminalAppLocalTests.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
|
||||
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-SettingsModelLocalTests.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
|
||||
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-HostTestsUIA.proj" Condition=" '$(TestSuite)'=='DevTestSuite' " />
|
||||
<Import Project="$(ProjFilesPath)\$(Configuration)\$(Platform)\RunTestsInHelix-WindowsTerminalUIATests.proj" Condition=" '$(TestSuite)'=='PgoInstrumentationSuite' " />
|
||||
</Project>
|
||||
136
build/Helix/UpdateUnreliableTests.ps1
Normal file
136
build/Helix/UpdateUnreliableTests.ps1
Normal file
@@ -0,0 +1,136 @@
|
||||
[CmdLetBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]$RerunPassesRequiredToAvoidFailure,
|
||||
|
||||
[string]$AccessToken = $env:SYSTEM_ACCESSTOKEN,
|
||||
[string]$CollectionUri = $env:SYSTEM_COLLECTIONURI,
|
||||
[string]$TeamProject = $env:SYSTEM_TEAMPROJECT,
|
||||
[string]$BuildUri = $env:BUILD_BUILDURI
|
||||
)
|
||||
|
||||
. "$PSScriptRoot/AzurePipelinesHelperScripts.ps1"
|
||||
|
||||
|
||||
$azureDevOpsRestApiHeaders = @{
|
||||
"Accept"="application/json"
|
||||
"Authorization"="Basic $([System.Convert]::ToBase64String([System.Text.ASCIIEncoding]::ASCII.GetBytes(":$AccessToken")))"
|
||||
}
|
||||
|
||||
$queryUri = GetQueryTestRunsUri -CollectionUri $CollectionUri -TeamProject $TeamProject -BuildUri $BuildUri
|
||||
Write-Host "queryUri = $queryUri"
|
||||
|
||||
# To account for unreliable tests, we'll iterate through all of the tests associated with this build, check to see any tests that were unreliable
|
||||
# (denoted by being marked as "skipped"), and if so, we'll instead mark those tests with a warning and enumerate all of the attempted runs
|
||||
# with their pass/fail states as well as any relevant error messages for failed attempts.
|
||||
$testRuns = Invoke-RestMethodWithRetries $queryUri -Headers $azureDevOpsRestApiHeaders
|
||||
|
||||
$timesSeenByRunName = @{}
|
||||
|
||||
foreach ($testRun in $testRuns.value)
|
||||
{
|
||||
$testRunResultsUri = "$($testRun.url)/results?api-version=5.0"
|
||||
|
||||
Write-Host "Marking test run `"$($testRun.name)`" as in progress so we can change its results to account for unreliable tests."
|
||||
Invoke-RestMethod "$($testRun.url)?api-version=5.0" -Method Patch -Body (ConvertTo-Json @{ "state" = "InProgress" }) -Headers $azureDevOpsRestApiHeaders -ContentType "application/json" | Out-Null
|
||||
|
||||
Write-Host "Retrieving test results..."
|
||||
$testResults = Invoke-RestMethodWithRetries $testRunResultsUri -Headers $azureDevOpsRestApiHeaders
|
||||
|
||||
foreach ($testResult in $testResults.value)
|
||||
{
|
||||
$testNeedsSubResultProcessing = $false
|
||||
if ($testResult.outcome -eq "NotExecuted")
|
||||
{
|
||||
$testNeedsSubResultProcessing = $true
|
||||
}
|
||||
elseif($testResult.outcome -eq "Failed")
|
||||
{
|
||||
$testNeedsSubResultProcessing = $testResult.errorMessage -like "*_subresults.json*"
|
||||
}
|
||||
|
||||
if ($testNeedsSubResultProcessing)
|
||||
{
|
||||
Write-Host " Test $($testResult.testCaseTitle) was detected as unreliable. Updating..."
|
||||
|
||||
# The errorMessage field contains a link to the JSON-encoded rerun result data.
|
||||
$resultsJson = Download-StringWithRetries "Error results" $testResult.errorMessage
|
||||
$rerunResults = ConvertFrom-Json $resultsJson
|
||||
[System.Collections.Generic.List[System.Collections.Hashtable]]$rerunDataList = @()
|
||||
$attemptCount = 0
|
||||
$passCount = 0
|
||||
$totalDuration = 0
|
||||
|
||||
foreach ($rerun in $rerunResults.results)
|
||||
{
|
||||
$rerunData = @{
|
||||
"displayName" = "Attempt #$($attemptCount + 1) - $($testResult.testCaseTitle)";
|
||||
"durationInMs" = $rerun.duration;
|
||||
"outcome" = $rerun.outcome;
|
||||
}
|
||||
|
||||
if ($rerun.outcome -eq "Passed")
|
||||
{
|
||||
$passCount++
|
||||
}
|
||||
|
||||
if ($attemptCount -gt 0)
|
||||
{
|
||||
$rerunData["sequenceId"] = $attemptCount
|
||||
}
|
||||
|
||||
Write-Host " Attempt #$($attemptCount + 1): $($rerun.outcome)"
|
||||
|
||||
if ($rerun.outcome -ne "Passed")
|
||||
{
|
||||
$screenshots = "$($rerunResults.blobPrefix)/$($rerun.screenshots -join @"
|
||||
$($rerunResults.blobSuffix)
|
||||
$($rerunResults.blobPrefix)
|
||||
"@)$($rerunResults.blobSuffix)"
|
||||
|
||||
# We subtract 1 from the error index because we added 1 so we could use 0
|
||||
# as a default value not injected into the JSON in order to keep its size down.
|
||||
# We did this because there's a maximum size enforced for the errorMessage parameter
|
||||
# in the Azure DevOps REST API.
|
||||
$fullErrorMessage = @"
|
||||
Log: $($rerunResults.blobPrefix)/$($rerun.log)$($rerunResults.blobSuffix)
|
||||
|
||||
Screenshots:
|
||||
$screenshots
|
||||
|
||||
Error log:
|
||||
$($rerunResults.errors[$rerun.errorIndex - 1])
|
||||
"@
|
||||
|
||||
$rerunData["errorMessage"] = $fullErrorMessage
|
||||
}
|
||||
|
||||
$attemptCount++
|
||||
$totalDuration += $rerun.duration
|
||||
$rerunDataList.Add($rerunData)
|
||||
}
|
||||
|
||||
$overallOutcome = "Warning"
|
||||
|
||||
if ($attemptCount -eq 2)
|
||||
{
|
||||
Write-Host " Test $($testResult.testCaseTitle) passed on the immediate rerun, so we'll mark it as unreliable."
|
||||
}
|
||||
elseif ($passCount -gt $RerunPassesRequiredToAvoidFailure)
|
||||
{
|
||||
Write-Host " Test $($testResult.testCaseTitle) passed on $passCount of $attemptCount attempts, which is greater than or equal to the $RerunPassesRequiredToAvoidFailure passes required to avoid being marked as failed. Marking as unreliable."
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host " Test $($testResult.testCaseTitle) passed on only $passCount of $attemptCount attempts, which is less than the $RerunPassesRequiredToAvoidFailure passes required to avoid being marked as failed. Marking as failed."
|
||||
$overallOutcome = "Failed"
|
||||
}
|
||||
|
||||
$updateBody = ConvertTo-Json @(@{ "id" = $testResult.id; "outcome" = $overallOutcome; "errorMessage" = " "; "durationInMs" = $totalDuration; "subResults" = $rerunDataList; "resultGroupType" = "rerun" }) -Depth 5
|
||||
Invoke-RestMethod -Uri $testRunResultsUri -Method Patch -Headers $azureDevOpsRestApiHeaders -Body $updateBody -ContentType "application/json" | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Finished updates. Re-marking test run `"$($testRun.name)`" as completed."
|
||||
Invoke-RestMethod -Uri "$($testRun.url)?api-version=5.0" -Method Patch -Body (ConvertTo-Json @{ "state" = "Completed" }) -Headers $azureDevOpsRestApiHeaders -ContentType "application/json" | Out-Null
|
||||
}
|
||||
5
build/Helix/global.json
Normal file
5
build/Helix/global.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"msbuild-sdks": {
|
||||
"Microsoft.DotNet.Helix.Sdk": "6.0.0-beta.22525.5"
|
||||
}
|
||||
}
|
||||
9
build/Helix/packages.config
Normal file
9
build/Helix/packages.config
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MUXCustomBuildTasks" version="1.0.48" targetFramework="native" />
|
||||
<package id="Microsoft.Internal.Windows.Terminal.TestContent" version="1.0.1" />
|
||||
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="native" />
|
||||
<package id="microsoft.windows.apps.test" version="1.0.181203002" targetFramework="native" />
|
||||
<package id="runtime.win-x86.microsoft.netcore.app" version="2.1.0" targetFramework="native" />
|
||||
<package id="runtime.win-x64.microsoft.netcore.app" version="2.1.0" targetFramework="native" />
|
||||
</packages>
|
||||
32
build/Helix/readme.md
Normal file
32
build/Helix/readme.md
Normal file
@@ -0,0 +1,32 @@
|
||||
This directory contains code and configuration files to run WinUI tests in Helix.
|
||||
|
||||
Helix is a cloud hosted test execution environment which is accessed via the Arcade SDK.
|
||||
More details:
|
||||
* [Arcade](https://github.com/dotnet/arcade)
|
||||
* [Helix](https://github.com/dotnet/arcade/tree/master/src/Microsoft.DotNet.Helix/Sdk)
|
||||
|
||||
WinUI tests are scheduled in Helix by the Azure DevOps Pipeline: [RunHelixTests.yml](../RunHelixTests.yml).
|
||||
|
||||
The workflow is as follows:
|
||||
1. NuGet Restore is called on the packages.config in this directory. This downloads any runtime dependencies
|
||||
that are needed to run tests.
|
||||
2. PrepareHelixPayload.ps1 is called. This copies the necessary files from various locations into a Helix
|
||||
payload directory. This directory is what will get sent to the Helix machines.
|
||||
3. RunTestsInHelix.proj is executed. This proj has a dependency on
|
||||
[Microsoft.DotNet.Helix.Sdk](https://github.com/dotnet/arcade/tree/master/src/Microsoft.DotNet.Helix/Sdk)
|
||||
which it uses to publish the Helix payload directory and to schedule the Helix Work Items. The WinUI tests
|
||||
are parallelized into multiple Helix Work Items.
|
||||
4. Each Helix Work Item calls [runtests.cmd](runtests.cmd) with a specific query to pass to
|
||||
[TAEF](https://docs.microsoft.com/en-us/windows-hardware/drivers/taef/) which runs the tests.
|
||||
5. If a test is detected to have failed, we run it again, first once, then eight more times if it fails again.
|
||||
If it fails all ten times, we report the test as failed; otherwise, we report it as unreliable,
|
||||
which will show up as a warning, but which will not fail the build. When a test is reported as unreliable,
|
||||
we include the results for each individual run via a JSON string in the original test's errorMessage field.
|
||||
6. TAEF produces logs in WTT format. Helix is able to process logs in XUnit format. We run
|
||||
[ConvertWttLogToXUnit.ps1](ConvertWttLogToXUnit.ps1) to convert the logs into the necessary format.
|
||||
7. RunTestsInHelix.proj has EnableAzurePipelinesReporter set to true. This allows the XUnit formatted test
|
||||
results to be reported back to the Azure DevOps Pipeline.
|
||||
8. We process unreliable tests once all tests have been reported by reading the JSON string from the
|
||||
errorMessage field and calling the Azure DevOps REST API to modify the unreliable tests to have sub-results
|
||||
added to the test and to mark the test as "warning", which will enable people to see exactly how the test
|
||||
failed in runs where it did.
|
||||
105
build/Helix/runtests.cmd
Normal file
105
build/Helix/runtests.cmd
Normal file
@@ -0,0 +1,105 @@
|
||||
setlocal ENABLEDELAYEDEXPANSION
|
||||
|
||||
echo %TIME%
|
||||
|
||||
robocopy %HELIX_CORRELATION_PAYLOAD% . /s /NP > NUL
|
||||
|
||||
echo %TIME%
|
||||
|
||||
reg add HKLM\Software\Policies\Microsoft\Windows\Appx /v AllowAllTrustedApps /t REG_DWORD /d 1 /f
|
||||
|
||||
rem enable dump collection for our test apps:
|
||||
rem note, this script is run from a 32-bit cmd, but we need to set the native reg-key
|
||||
FOR %%A IN (TestHostApp.exe,te.exe,te.processhost.exe,conhost.exe,OpenConsole.exe,WindowsTerminal.exe) DO (
|
||||
%systemroot%\sysnative\cmd.exe /c reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\%%A" /v DumpFolder /t REG_EXPAND_SZ /d %HELIX_DUMP_FOLDER% /f
|
||||
%systemroot%\sysnative\cmd.exe /c reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\%%A" /v DumpType /t REG_DWORD /d 2 /f
|
||||
%systemroot%\sysnative\cmd.exe /c reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\%%A" /v DumpCount /t REG_DWORD /d 10 /f
|
||||
)
|
||||
|
||||
echo %TIME%
|
||||
|
||||
:: kill dhandler, which is a tool designed to handle unexpected windows appearing. But since our tests are
|
||||
:: expected to show UI we don't want it running.
|
||||
taskkill -f -im dhandler.exe
|
||||
|
||||
echo %TIME%
|
||||
powershell -ExecutionPolicy Bypass .\EnsureMachineState.ps1
|
||||
echo %TIME%
|
||||
powershell -ExecutionPolicy Bypass .\InstallTestAppDependencies.ps1
|
||||
echo %TIME%
|
||||
|
||||
set testBinaryCandidates=TerminalApp.LocalTests.dll SettingsModel.LocalTests.dll Conhost.UIA.Tests.dll WindowsTerminal.UIA.Tests.dll
|
||||
set testBinaries=
|
||||
for %%B in (%testBinaryCandidates%) do (
|
||||
if exist %%B (
|
||||
set "testBinaries=!testBinaries! %%B"
|
||||
)
|
||||
)
|
||||
|
||||
echo %TIME%
|
||||
te.exe %testBinaries% /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError %*
|
||||
echo %TIME%
|
||||
|
||||
powershell -ExecutionPolicy Bypass Get-Process
|
||||
|
||||
move te.wtl te_original.wtl
|
||||
|
||||
copy /y te_original.wtl %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
copy /y *.pgc %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
|
||||
set FailedTestQuery=
|
||||
for /F "tokens=* usebackq" %%I IN (`powershell -ExecutionPolicy Bypass .\OutputFailedTestQuery.ps1 te_original.wtl`) DO (
|
||||
set FailedTestQuery=%%I
|
||||
)
|
||||
|
||||
rem The first time, we'll just re-run failed tests once. In many cases, tests fail very rarely, such that
|
||||
rem a single re-run will be sufficient to detect many unreliable tests.
|
||||
if "%FailedTestQuery%" == "" goto :SkipReruns
|
||||
|
||||
echo %TIME%
|
||||
te.exe %testBinaries% /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError /select:"%FailedTestQuery%"
|
||||
echo %TIME%
|
||||
|
||||
move te.wtl te_rerun.wtl
|
||||
|
||||
copy /y te_rerun.wtl %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
|
||||
rem If there are still failing tests remaining, we'll run them eight more times, so they'll have been run a total of ten times.
|
||||
rem If any tests fail all ten times, we can be pretty confident that these are actual test failures rather than unreliable tests.
|
||||
if not exist te_rerun.wtl goto :SkipReruns
|
||||
|
||||
set FailedTestQuery=
|
||||
for /F "tokens=* usebackq" %%I IN (`powershell -ExecutionPolicy Bypass .\OutputFailedTestQuery.ps1 te_rerun.wtl`) DO (
|
||||
set FailedTestQuery=%%I
|
||||
)
|
||||
|
||||
if "%FailedTestQuery%" == "" goto :SkipReruns
|
||||
|
||||
echo %TIME%
|
||||
te.exe %testBinaries% /enablewttlogging /unicodeOutput:false /sessionTimeout:0:15 /testtimeout:0:10 /screenCaptureOnError /testmode:Loop /LoopTest:8 /select:"%FailedTestQuery%"
|
||||
echo %TIME%
|
||||
|
||||
powershell -ExecutionPolicy Bypass Get-Process
|
||||
|
||||
move te.wtl te_rerun_multiple.wtl
|
||||
|
||||
copy /y te_rerun_multiple.wtl %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
copy /y WexLogFileOutput\*.jpg %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
powershell -ExecutionPolicy Bypass .\CopyVisualTreeVerificationFiles.ps1
|
||||
|
||||
:SkipReruns
|
||||
|
||||
powershell -ExecutionPolicy Bypass Get-Process
|
||||
|
||||
echo %TIME%
|
||||
powershell -ExecutionPolicy Bypass .\OutputSubResultsJsonFiles.ps1 te_original.wtl te_rerun.wtl te_rerun_multiple.wtl %testnameprefix%
|
||||
powershell -ExecutionPolicy Bypass .\ConvertWttLogToXUnit.ps1 te_original.wtl te_rerun.wtl te_rerun_multiple.wtl testResults.xml %testnameprefix%
|
||||
echo %TIME%
|
||||
|
||||
copy /y *_subresults.json %HELIX_WORKITEM_UPLOAD_ROOT%
|
||||
|
||||
type testResults.xml
|
||||
|
||||
echo %TIME%
|
||||
51
build/config/ESRPSigning_ConPTY.json
Normal file
51
build/config/ESRPSigning_ConPTY.json
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"Version": "1.0.0",
|
||||
"UseMinimatch": false,
|
||||
"SignBatches": [
|
||||
{
|
||||
"MatchedPath": [
|
||||
"conpty.dll",
|
||||
"OpenConsole.exe"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolSign",
|
||||
"Parameters": [
|
||||
{
|
||||
"parameterName": "OpusName",
|
||||
"parameterValue": "Microsoft"
|
||||
},
|
||||
{
|
||||
"parameterName": "OpusInfo",
|
||||
"parameterValue": "http://www.microsoft.com"
|
||||
},
|
||||
{
|
||||
"parameterName": "FileDigest",
|
||||
"parameterValue": "/fd \"SHA256\""
|
||||
},
|
||||
{
|
||||
"parameterName": "PageHash",
|
||||
"parameterValue": "/NPH"
|
||||
},
|
||||
{
|
||||
"parameterName": "TimeStamp",
|
||||
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
}
|
||||
],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolVerify",
|
||||
"Parameters": [],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
72
build/config/ESRPSigning_Terminal.json
Normal file
72
build/config/ESRPSigning_Terminal.json
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"Version": "1.0.0",
|
||||
"UseMinimatch": false,
|
||||
"SignBatches": [
|
||||
{
|
||||
"MatchedPath": [
|
||||
// Namespaced DLLs
|
||||
"Microsoft.Terminal.*.dll",
|
||||
"Microsoft.Terminal.*.winmd",
|
||||
|
||||
// ConPTY and DefTerm
|
||||
"OpenConsole.exe",
|
||||
"OpenConsoleProxy.dll",
|
||||
|
||||
// VCRT Forwarders
|
||||
"*_app.dll",
|
||||
|
||||
// Legacy DLLs with old names
|
||||
"TerminalApp.dll",
|
||||
"TerminalApp.winmd",
|
||||
"TerminalConnection.dll",
|
||||
"TerminalThemeHelpers.dll",
|
||||
"WindowsTerminalShellExt.dll",
|
||||
|
||||
// The rest
|
||||
"TerminalAzBridge.exe",
|
||||
"wt.exe",
|
||||
"WindowsTerminal.exe",
|
||||
"elevate-shim.exe"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolSign",
|
||||
"Parameters": [
|
||||
{
|
||||
"parameterName": "OpusName",
|
||||
"parameterValue": "Microsoft"
|
||||
},
|
||||
{
|
||||
"parameterName": "OpusInfo",
|
||||
"parameterValue": "http://www.microsoft.com"
|
||||
},
|
||||
{
|
||||
"parameterName": "FileDigest",
|
||||
"parameterValue": "/fd \"SHA256\""
|
||||
},
|
||||
{
|
||||
"parameterName": "PageHash",
|
||||
"parameterValue": "/NPH"
|
||||
},
|
||||
{
|
||||
"parameterName": "TimeStamp",
|
||||
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
}
|
||||
],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolVerify",
|
||||
"Parameters": [],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
[
|
||||
{
|
||||
"MatchedPath": [
|
||||
"conpty.dll",
|
||||
"OpenConsole.exe"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolSign",
|
||||
"Parameters": [
|
||||
{
|
||||
"parameterName": "OpusName",
|
||||
"parameterValue": "Microsoft"
|
||||
},
|
||||
{
|
||||
"parameterName": "OpusInfo",
|
||||
"parameterValue": "http://www.microsoft.com"
|
||||
},
|
||||
{
|
||||
"parameterName": "FileDigest",
|
||||
"parameterValue": "/fd \"SHA256\""
|
||||
},
|
||||
{
|
||||
"parameterName": "PageHash",
|
||||
"parameterValue": "/NPH"
|
||||
},
|
||||
{
|
||||
"parameterName": "TimeStamp",
|
||||
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
}
|
||||
],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolVerify",
|
||||
"Parameters": [],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1,65 +0,0 @@
|
||||
[
|
||||
{
|
||||
"MatchedPath": [
|
||||
// Namespaced DLLs
|
||||
"PackageContents/Microsoft.Terminal.*.dll",
|
||||
"PackageContents/Microsoft.Terminal.*.winmd",
|
||||
|
||||
// ConPTY and DefTerm
|
||||
"PackageContents/OpenConsole.exe",
|
||||
"PackageContents/OpenConsoleProxy.dll",
|
||||
|
||||
// Legacy DLLs with old names
|
||||
"PackageContents/TerminalApp.dll",
|
||||
"PackageContents/TerminalApp.winmd",
|
||||
"PackageContents/TerminalConnection.dll",
|
||||
"PackageContents/TerminalThemeHelpers.dll",
|
||||
"PackageContents/WindowsTerminalShellExt.dll",
|
||||
|
||||
// The rest
|
||||
"PackageContents/TerminalAzBridge.exe",
|
||||
"PackageContents/wt.exe",
|
||||
"PackageContents/WindowsTerminal.exe",
|
||||
"PackageContents/elevate-shim.exe"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolSign",
|
||||
"Parameters": [
|
||||
{
|
||||
"parameterName": "OpusName",
|
||||
"parameterValue": "Microsoft"
|
||||
},
|
||||
{
|
||||
"parameterName": "OpusInfo",
|
||||
"parameterValue": "http://www.microsoft.com"
|
||||
},
|
||||
{
|
||||
"parameterName": "FileDigest",
|
||||
"parameterValue": "/fd \"SHA256\""
|
||||
},
|
||||
{
|
||||
"parameterName": "PageHash",
|
||||
"parameterValue": "/NPH"
|
||||
},
|
||||
{
|
||||
"parameterName": "TimeStamp",
|
||||
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
}
|
||||
],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolVerify",
|
||||
"Parameters": [],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1,46 +0,0 @@
|
||||
[
|
||||
{
|
||||
"MatchedPath": [
|
||||
"PublicTerminalCore.dll"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolSign",
|
||||
"Parameters": [
|
||||
{
|
||||
"parameterName": "OpusName",
|
||||
"parameterValue": "Microsoft"
|
||||
},
|
||||
{
|
||||
"parameterName": "OpusInfo",
|
||||
"parameterValue": "http://www.microsoft.com"
|
||||
},
|
||||
{
|
||||
"parameterName": "FileDigest",
|
||||
"parameterValue": "/fd \"SHA256\""
|
||||
},
|
||||
{
|
||||
"parameterName": "PageHash",
|
||||
"parameterValue": "/NPH"
|
||||
},
|
||||
{
|
||||
"parameterName": "TimeStamp",
|
||||
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
}
|
||||
],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolVerify",
|
||||
"Parameters": [],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1,47 +0,0 @@
|
||||
[
|
||||
{
|
||||
"MatchedPath": [
|
||||
"WpfTerminalControl/net472/Microsoft.Terminal.Wpf.dll",
|
||||
"WpfTerminalControl/net6.0-windows/Microsoft.Terminal.Wpf.dll"
|
||||
],
|
||||
"SigningInfo": {
|
||||
"Operations": [
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolSign",
|
||||
"Parameters": [
|
||||
{
|
||||
"parameterName": "OpusName",
|
||||
"parameterValue": "Microsoft"
|
||||
},
|
||||
{
|
||||
"parameterName": "OpusInfo",
|
||||
"parameterValue": "http://www.microsoft.com"
|
||||
},
|
||||
{
|
||||
"parameterName": "FileDigest",
|
||||
"parameterValue": "/fd \"SHA256\""
|
||||
},
|
||||
{
|
||||
"parameterName": "PageHash",
|
||||
"parameterValue": "/NPH"
|
||||
},
|
||||
{
|
||||
"parameterName": "TimeStamp",
|
||||
"parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
}
|
||||
],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-230012",
|
||||
"OperationSetCode": "SigntoolVerify",
|
||||
"Parameters": [],
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"instanceUrl": "https://microsoft.visualstudio.com",
|
||||
"projectName": "OS",
|
||||
"areaPath": "OS\\Windows Client and Services\\ADEPT\\E4D-Engineered for Developers\\SHINE\\Terminal",
|
||||
"notificationAliases": ["condev@microsoft.com", "duhowett@microsoft.com"]
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="Terminal.PGO.props" />
|
||||
<Import Project="$(PkgMicrosoft_PGO_Helpers_Cpp)\build\Microsoft.PGO-Helpers.Cpp.props" />
|
||||
<Import Project="$(PkgMicrosoft_PGO_Helpers_Cpp)\build\Microsoft.PGO-Helpers.Cpp.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -12,6 +12,5 @@
|
||||
<files>
|
||||
<!-- The target directories for pgd files need to remain as is. PGO optimization pass will rely on this exact directory layout. -->
|
||||
<file src="x64\*.pgd" target="tools\x64"/>
|
||||
<file src="arm64\*.pgd" target="tools\arm64"/>
|
||||
</files>
|
||||
</package>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Optional, defaults to main. Name of the branch which will be used for calculating branch point. -->
|
||||
<PGOBranch>release-1.18</PGOBranch>
|
||||
<PGOBranch>main</PGOBranch>
|
||||
|
||||
<!-- Mandatory. Name of the NuGet package which will contain PGO databases for consumption by build system. -->
|
||||
<PGOPackageName>Microsoft.Internal.Windows.Terminal.PGODatabase</PGOPackageName>
|
||||
@@ -46,5 +46,6 @@
|
||||
<PGOCopyRuntime Condition="'$(PGOBuildMode)' == 'Instrument'">true</PGOCopyRuntime>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Do not import PGO-Helpers props here, as it is too early to detect the C++ tools directory -->
|
||||
<!-- Import PGO-Helpers -->
|
||||
<Import Project="$(PkgMicrosoft_PGO_Helpers_Cpp)\build\Microsoft.PGO-Helpers.Cpp.props" />
|
||||
</Project>
|
||||
|
||||
@@ -29,80 +29,76 @@ variables:
|
||||
# 0.0.1904.0900
|
||||
name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr)
|
||||
|
||||
parameters:
|
||||
- name: auditMode
|
||||
displayName: "Build in Audit Mode (x64)"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: runTests
|
||||
displayName: "Run Tests"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
|
||||
stages:
|
||||
- ${{ if eq(parameters.auditMode, true) }}:
|
||||
- stage: Audit_x64
|
||||
displayName: Audit Mode
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./templates-v2/job-build-project.yml
|
||||
parameters:
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-OSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-INT-L
|
||||
buildPlatforms: [x64]
|
||||
buildConfigurations: [AuditMode]
|
||||
buildEverything: true
|
||||
keepAllExpensiveBuildOutputs: false
|
||||
- stage: Audit_x64
|
||||
displayName: Audit Mode
|
||||
dependsOn: []
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates/build-console-audit-job.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
|
||||
- stage: CodeHealth
|
||||
displayName: Code Health
|
||||
- stage: Build_x64
|
||||
displayName: Build x64
|
||||
dependsOn: []
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates/build-console-ci.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
- stage: Build_x86
|
||||
displayName: Build x86
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./templates-v2/job-check-code-format.yml
|
||||
- template: ./templates/build-console-ci.yml
|
||||
parameters:
|
||||
platform: x86
|
||||
- stage: Build_ARM64
|
||||
displayName: Build ARM64
|
||||
dependsOn: []
|
||||
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
|
||||
jobs:
|
||||
- template: ./templates/build-console-ci.yml
|
||||
parameters:
|
||||
platform: ARM64
|
||||
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- stage: Build_${{ platform }}
|
||||
displayName: Build ${{ platform }}
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./templates-v2/job-build-project.yml
|
||||
parameters:
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-OSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-INT-L
|
||||
buildPlatforms:
|
||||
- ${{ platform }}
|
||||
buildConfigurations: [Release]
|
||||
buildEverything: true
|
||||
keepAllExpensiveBuildOutputs: false
|
||||
- stage: Test_x64
|
||||
displayName: Test x64
|
||||
dependsOn: [Build_x64]
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates/test-console-ci.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
- stage: Test_x86
|
||||
displayName: Test x86
|
||||
dependsOn: [Build_x86]
|
||||
jobs:
|
||||
- template: ./templates/test-console-ci.yml
|
||||
parameters:
|
||||
platform: x86
|
||||
|
||||
- ${{ if eq(parameters.runTests, true) }}:
|
||||
- stage: Test_${{ platform }}
|
||||
displayName: Test ${{ platform }}
|
||||
dependsOn:
|
||||
- Build_${{ platform }}
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates-v2/job-test-project.yml
|
||||
parameters:
|
||||
platform: ${{ platform }}
|
||||
# The tests might be run more than once; log one artifact per attempt.
|
||||
outputArtifactStem: -$(System.JobAttempt)
|
||||
- stage: Helix_x64
|
||||
displayName: Helix x64
|
||||
dependsOn: [Build_x64]
|
||||
condition: and(succeeded(), not(eq(variables['Build.Reason'], 'PullRequest')))
|
||||
jobs:
|
||||
- template: ./templates/console-ci-helix-job.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
|
||||
- ${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
|
||||
- stage: CodeIndexer
|
||||
displayName: Github CodeNav Indexer
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./templates-v2/job-index-github-codenav.yml
|
||||
- stage: Scripts
|
||||
displayName: Code Health Scripts
|
||||
dependsOn: []
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates/check-formatting.yml
|
||||
|
||||
|
||||
- stage: CodeIndexer
|
||||
displayName: Github CodeNav Indexer
|
||||
dependsOn: [Build_x64]
|
||||
condition: and(succeeded(), not(eq(variables['Build.Reason'], 'PullRequest')))
|
||||
jobs:
|
||||
- template: ./templates/codenav-indexer.yml
|
||||
|
||||
@@ -8,12 +8,6 @@ schedules:
|
||||
- main
|
||||
always: false # only run if there's code changes!
|
||||
|
||||
|
||||
parameters:
|
||||
- name: targetBranch
|
||||
type: string
|
||||
default: "automated/loc-update"
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
|
||||
@@ -33,7 +27,6 @@ steps:
|
||||
clean: true
|
||||
submodules: false
|
||||
fetchDepth: 1 # Don't need a deep checkout for loc files!
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
persistCredentials: true
|
||||
path: s # Adding a second repo made Azure DevOps change where we're checked out.
|
||||
|
||||
@@ -44,13 +37,6 @@ steps:
|
||||
persistCredentials: true
|
||||
path: s/Terminal.Internal
|
||||
|
||||
- pwsh: |-
|
||||
Install-Module PSGitHub -Scope CurrentUser -Force
|
||||
git config --local user.email "consvc@microsoft.com"
|
||||
git config --local user.name "Console Service Bot"
|
||||
git config --local core.autocrlf true
|
||||
displayName: Prepare git submission environment
|
||||
|
||||
- task: MicrosoftTDBuild.tdbuild-task.tdbuild-task.TouchdownBuildTask@1
|
||||
displayName: 'Touchdown Build - 7105, PRODEXT'
|
||||
inputs:
|
||||
@@ -64,44 +50,13 @@ steps:
|
||||
outputDirectoryRoot: LocOutput
|
||||
appendRelativeDir: true
|
||||
pseudoSetting: Included
|
||||
localizationTarget: true
|
||||
|
||||
- pwsh: |-
|
||||
Remove-Item -EA:Ignore -R -Force LocOutput\Terminal.Internal
|
||||
$Files = Get-ChildItem LocOutput -R -Include 'ContextMenu.resw','Resources.resw' | ? FullName -Like '*en-US\*\*.resw'
|
||||
$Files | % { Move-Item -Verbose $_.Directory $_.Directory.Parent.Parent -EA:Ignore }
|
||||
& tar.exe -c -f LocOutputMunged.tar -C LocOutput .
|
||||
& tar.exe -x -v -f LocOutputMunged.tar
|
||||
rm LocOutputMunged.tar
|
||||
rm -r -fo LocOutput
|
||||
& ./build/scripts/Copy-ContextMenuResourcesToCascadiaPackage.ps1
|
||||
displayName: Move Loc files to the right places
|
||||
# Saving one of these makes it really easy to inspect the loc output...
|
||||
- powershell: 'tar czf LocOutput.tar.gz LocOutput'
|
||||
displayName: 'Archive Loc Output for Submission'
|
||||
|
||||
- pwsh: |-
|
||||
git add **/*.resw
|
||||
git status
|
||||
git diff --quiet --cached --exit-code
|
||||
If ($LASTEXITCODE -Ne 0) {
|
||||
$Now = Get-Date
|
||||
git commit -m "Localization Updates - $Now"
|
||||
git push origin HEAD:refs/heads/${{parameters.targetBranch}} -f
|
||||
Write-Host "##vso[task.setvariable variable=ChangesPushedToRepo]1"
|
||||
} Else {
|
||||
Write-Host "##vso[task.setvariable variable=ChangesPushedToRepo]0"
|
||||
}
|
||||
displayName: git commit and push
|
||||
|
||||
- pwsh: |-
|
||||
Import-Module PSGitHub
|
||||
$BaseBranch = "$(Build.SourceBranch)" -Replace "^refs/heads/",""
|
||||
Write-Host "Preparing PR against $BaseBranch"
|
||||
$PSDefaultParameterValues['*GitHub*:Owner'] = "microsoft"
|
||||
$PSDefaultParameterValues['*GitHub*:RepositoryName'] = "terminal"
|
||||
$PSDefaultParameterValues['*GitHub*:Token'] = ("$(GithubPullRequestToken)" | ConvertTo-SecureString -AsPlainText -Force)
|
||||
$existingPr = Get-GitHubPullRequest -HeadBranch "${{parameters.targetBranch}}" -BaseBranch $BaseBranch
|
||||
If ($null -Eq $existingPr) {
|
||||
$Now = Get-Date
|
||||
New-GitHubPullRequest -Head "${{parameters.targetBranch}}" -Base $BaseBranch -Title "Localization Updates - $BaseBranch - $Now" -Verbose
|
||||
}
|
||||
displayName: Publish pull request
|
||||
condition: and(eq(variables['ChangesPushedToRepo'], '1'), succeeded())
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: LocOutput'
|
||||
inputs:
|
||||
PathtoPublish: LocOutput.tar.gz
|
||||
ArtifactName: LocOutput
|
||||
|
||||
@@ -7,7 +7,6 @@ pr:
|
||||
paths:
|
||||
include:
|
||||
- src/features.xml
|
||||
- build/pipelines/feature-flag-ci.yml
|
||||
|
||||
variables:
|
||||
- name: runCodesignValidationInjectionBG
|
||||
@@ -22,19 +21,9 @@ parameters:
|
||||
# Dev is built automatically
|
||||
# WindowsInbox does not typically build with VS.
|
||||
|
||||
stages:
|
||||
jobs:
|
||||
- ${{ each branding in parameters.buildBrandings }}:
|
||||
- stage: Build_${{ branding }}
|
||||
dependsOn: []
|
||||
displayName: Build ${{ branding }}
|
||||
jobs:
|
||||
- template: ./templates-v2/job-build-project.yml
|
||||
parameters:
|
||||
pool: # This only runs in CI
|
||||
name: SHINE-OSS-L
|
||||
buildPlatforms: [x64]
|
||||
buildConfigurations: [Release]
|
||||
buildEverything: true
|
||||
branding: ${{ branding }}
|
||||
keepAllExpensiveBuildOutputs: false
|
||||
artifactStem: -${{ branding }} # Disambiguate artifacts with the same config/platform
|
||||
- template: ./templates/build-console-ci.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
branding: ${{ branding }}
|
||||
|
||||
@@ -16,52 +16,44 @@ pr: none
|
||||
name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr)
|
||||
|
||||
stages:
|
||||
- stage: Build
|
||||
displayName: Fuzzing Build
|
||||
- stage: Build_Fuzz_Config
|
||||
displayName: Build Fuzzers
|
||||
dependsOn: []
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates-v2/job-build-project.yml
|
||||
parameters:
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-OSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-INT-L
|
||||
buildPlatforms: [x64]
|
||||
buildConfigurations: [Fuzzing]
|
||||
buildEverything: true
|
||||
keepAllExpensiveBuildOutputs: false
|
||||
|
||||
- stage: Submit
|
||||
displayName: Submit to OneFuzz
|
||||
dependsOn: [Build]
|
||||
- template: ./templates/build-console-fuzzing.yml
|
||||
parameters:
|
||||
platform: x64
|
||||
- stage: OneFuzz
|
||||
displayName: Submit OneFuzz Job
|
||||
dependsOn: ['Build_Fuzz_Config']
|
||||
condition: succeeded()
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
variables:
|
||||
artifactName: fuzzingBuildOutput
|
||||
jobs:
|
||||
- job:
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download artifacts
|
||||
inputs:
|
||||
artifactName: build-x64-Fuzzing
|
||||
downloadPath: $(Build.ArtifactStagingDirectory)
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '3.x'
|
||||
addToPath: true
|
||||
architecture: 'x64'
|
||||
- bash: |
|
||||
set -ex
|
||||
pip -q install onefuzz
|
||||
onefuzz config --endpoint $(endpoint) --client_id $(client_id) --authority $(authority) --tenant_domain $(tenant_domain) --client_secret $(client_secret)
|
||||
sed -i s/INSERT_PAT_HERE/$(ado_pat)/ build/Fuzz/notifications-ado.json
|
||||
sed -i s/INSERT_ASSIGNED_HERE/$(ado_assigned_to)/ build/Fuzz/notifications-ado.json
|
||||
displayName: Configure OneFuzz
|
||||
- bash: |
|
||||
onefuzz template libfuzzer basic --colocate_all_tasks --vm_count 1 --target_exe $target_exe_path --notification_config @./build/Fuzz/notifications-ado.json OpenConsole $test_name $(Build.SourceVersion) default
|
||||
displayName: Submit OneFuzz Job
|
||||
env:
|
||||
target_exe_path: $(Build.ArtifactStagingDirectory)/OpenConsoleFuzzer.exe
|
||||
test_name: WriteCharsLegacy
|
||||
- job:
|
||||
steps:
|
||||
- task: DownloadBuildArtifacts@0
|
||||
inputs:
|
||||
artifactName: $(artifactName)
|
||||
downloadPath: $(Build.ArtifactStagingDirectory)
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '3.x'
|
||||
addToPath: true
|
||||
architecture: 'x64'
|
||||
- bash: |
|
||||
set -ex
|
||||
pip -q install onefuzz
|
||||
onefuzz config --endpoint $(endpoint) --client_id $(client_id) --authority $(authority) --tenant_domain $(tenant_domain) --client_secret $(client_secret)
|
||||
sed -i s/INSERT_PAT_HERE/$(ado_pat)/ build/Fuzz/notifications-ado.json
|
||||
sed -i s/INSERT_ASSIGNED_HERE/$(ado_assigned_to)/ build/Fuzz/notifications-ado.json
|
||||
displayName: Configure OneFuzz
|
||||
- bash: |
|
||||
onefuzz template libfuzzer basic --colocate_all_tasks --vm_count 1 --target_exe $target_exe_path --notification_config @./build/Fuzz/notifications-ado.json OpenConsole $test_name $(Build.SourceVersion) default
|
||||
displayName: Submit OneFuzz Job
|
||||
env:
|
||||
target_exe_path: $(Build.ArtifactStagingDirectory)/$(artifactName)/Fuzzing/x64/test/OpenConsoleFuzzer.exe
|
||||
test_name: WriteCharsLegacy
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
trigger: none
|
||||
pr: none
|
||||
schedules:
|
||||
- cron: "30 3 * * 2-6" # Run at 03:30 UTC Tuesday through Saturday (After the work day in Pacific, Mon-Fri)
|
||||
displayName: "Nightly Terminal Build"
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
always: false # only run if there's code changes!
|
||||
|
||||
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
||||
|
||||
extends:
|
||||
template: templates-v2\pipeline-full-release-build.yml
|
||||
parameters:
|
||||
branding: Canary
|
||||
buildTerminal: true
|
||||
pgoBuildMode: Optimize
|
||||
codeSign: true
|
||||
generateSbom: true
|
||||
publishSymbolsToPublic: true
|
||||
publishVpackToWindows: false
|
||||
symbolExpiryTime: 15 # Nightly builds do not keep symbols for very long!
|
||||
@@ -1,49 +0,0 @@
|
||||
trigger: none
|
||||
pr: none
|
||||
schedules:
|
||||
- cron: "30 3 * * 2-6" # Run at 03:30 UTC Tuesday through Saturday (After the work day in Pacific, Mon-Fri)
|
||||
displayName: "Nightly Terminal Build"
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
always: false # only run if there's code changes!
|
||||
|
||||
parameters:
|
||||
- name: publishToAzure
|
||||
displayName: "Deploy to **PUBLIC** Azure Storage"
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
||||
|
||||
variables:
|
||||
- template: templates-v2/variables-nuget-package-version.yml
|
||||
parameters:
|
||||
branding: Canary
|
||||
- template: templates-v2/variables-onebranch-config.yml
|
||||
|
||||
extends:
|
||||
template: templates-v2/pipeline-onebranch-full-release-build.yml
|
||||
parameters:
|
||||
official: true
|
||||
branding: Canary
|
||||
buildTerminal: true
|
||||
pgoBuildMode: Optimize
|
||||
codeSign: true
|
||||
publishSymbolsToPublic: true
|
||||
publishVpackToWindows: false
|
||||
symbolExpiryTime: 15
|
||||
${{ if eq(true, parameters.publishToAzure) }}:
|
||||
extraPublishJobs:
|
||||
- template: job-deploy-to-azure-storage.yml
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
dependsOn: [PublishSymbols]
|
||||
storagePublicRootURL: $(AppInstallerRootURL)
|
||||
subscription: $(AzureSubscriptionName)
|
||||
storageAccount: $(AzureStorageAccount)
|
||||
storageContainer: $(AzureStorageContainer)
|
||||
buildConfiguration: Release
|
||||
buildPlatforms: [x64, x86, arm64]
|
||||
environment: production-canary
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
trigger: none
|
||||
pr: none
|
||||
|
||||
# Expose all of these parameters for user configuration.
|
||||
parameters:
|
||||
- name: branding
|
||||
displayName: "Branding (Build Type)"
|
||||
type: string
|
||||
default: Release
|
||||
values:
|
||||
- Release
|
||||
- Preview
|
||||
- Canary
|
||||
- Dev
|
||||
- name: buildTerminal
|
||||
displayName: "Build Windows Terminal MSIX"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildConPTY
|
||||
displayName: "Build ConPTY NuGet"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildWPF
|
||||
displayName: "Build Terminal WPF Control"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pgoBuildMode
|
||||
displayName: "PGO Build Mode"
|
||||
type: string
|
||||
default: Optimize
|
||||
values:
|
||||
- Optimize
|
||||
- Instrument
|
||||
- None
|
||||
- name: buildConfigurations
|
||||
displayName: "Build Configurations"
|
||||
type: object
|
||||
default:
|
||||
- Release
|
||||
- name: buildPlatforms
|
||||
displayName: "Build Platforms"
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
- name: terminalInternalPackageVersion
|
||||
displayName: "Terminal Internal Package Version"
|
||||
type: string
|
||||
default: '0.0.8'
|
||||
|
||||
- name: publishSymbolsToPublic
|
||||
displayName: "Publish Symbols to MSDL"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: publishVpackToWindows
|
||||
displayName: "Publish VPack to Windows"
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
||||
|
||||
variables:
|
||||
- template: templates-v2/variables-nuget-package-version.yml
|
||||
parameters:
|
||||
branding: ${{ parameters.branding }}
|
||||
- template: templates-v2/variables-onebranch-config.yml
|
||||
|
||||
extends:
|
||||
template: templates-v2/pipeline-onebranch-full-release-build.yml
|
||||
parameters:
|
||||
official: true
|
||||
branding: ${{ parameters.branding }}
|
||||
buildTerminal: ${{ parameters.buildTerminal }}
|
||||
buildConPTY: ${{ parameters.buildConPTY }}
|
||||
buildWPF: ${{ parameters.buildWPF }}
|
||||
pgoBuildMode: ${{ parameters.pgoBuildMode }}
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
codeSign: true
|
||||
terminalInternalPackageVersion: ${{ parameters.terminalInternalPackageVersion }}
|
||||
publishSymbolsToPublic: ${{ parameters.publishSymbolsToPublic }}
|
||||
publishVpackToWindows: ${{ parameters.publishVpackToWindows }}
|
||||
@@ -1,27 +1,5 @@
|
||||
trigger: none
|
||||
pr: none
|
||||
schedules:
|
||||
- cron: "0 5 * * 2-6" # Run at 05:00 UTC Tuesday through Saturday (Even later than Localization, after the work day in Pacific, Mon-Fri)
|
||||
displayName: "Nightly Instrumentation Build"
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
always: false # only run if there's code changes!
|
||||
|
||||
parameters:
|
||||
- name: branding
|
||||
displayName: "Branding (Build Type)"
|
||||
type: string
|
||||
default: Preview # By default, we'll PGO the Preview builds to get max coverage
|
||||
values:
|
||||
- Release
|
||||
- Preview
|
||||
- Dev
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- arm64
|
||||
|
||||
variables:
|
||||
- name: runCodesignValidationInjectionBG
|
||||
@@ -32,57 +10,18 @@ variables:
|
||||
name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr)
|
||||
|
||||
stages:
|
||||
- stage: Build
|
||||
displayName: Build
|
||||
- stage: Build_x64
|
||||
displayName: Build x64
|
||||
dependsOn: []
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
- template: ./templates-v2/job-build-project.yml
|
||||
- template: ./templates/build-console-pgo.yml
|
||||
parameters:
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-OSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: SHINE-INT-L
|
||||
branding: ${{ parameters.branding }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
buildConfigurations: [Release]
|
||||
buildEverything: true
|
||||
pgoBuildMode: Instrument
|
||||
artifactStem: -instrumentation
|
||||
|
||||
- stage: RunPGO
|
||||
displayName: Run PGO
|
||||
dependsOn: [Build]
|
||||
condition: succeeded()
|
||||
platform: x64
|
||||
- stage: Publish_PGO_Databases
|
||||
displayName: Publish PGO databases
|
||||
dependsOn: ['Build_x64']
|
||||
jobs:
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- template: ./templates-v2/job-run-pgo-tests.yml
|
||||
parameters:
|
||||
# This job chooses its own pools based on platform
|
||||
buildPlatform: ${{ platform }}
|
||||
buildConfiguration: Release
|
||||
artifactStem: -instrumentation
|
||||
|
||||
- stage: FinalizePGO
|
||||
displayName: Finalize PGO and Publish
|
||||
dependsOn: [RunPGO]
|
||||
condition: succeeded()
|
||||
jobs:
|
||||
# This job takes multiple platforms and fans them back in to a single artifact.
|
||||
- template: ./templates-v2/job-pgo-merge-pgd.yml
|
||||
- template: ./templates/pgo-build-and-publish-nuget-job.yml
|
||||
parameters:
|
||||
jobName: MergePGD
|
||||
pool:
|
||||
vmImage: 'windows-2022'
|
||||
buildConfiguration: Release
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
artifactStem: -instrumentation
|
||||
|
||||
- template: ./templates-v2/job-pgo-build-nuget-and-publish.yml
|
||||
parameters:
|
||||
pool:
|
||||
vmImage: 'windows-2022'
|
||||
dependsOn: MergePGD
|
||||
buildConfiguration: Release
|
||||
artifactStem: -instrumentation
|
||||
pgoArtifact: 'PGO'
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
# This build should never run as CI or against a pull request.
|
||||
trigger: none
|
||||
pr: none
|
||||
|
||||
# Expose all of these parameters for user configuration.
|
||||
pool:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS17-latest
|
||||
|
||||
parameters:
|
||||
- name: branding
|
||||
displayName: "Branding (Build Type)"
|
||||
@@ -10,11 +14,22 @@ parameters:
|
||||
values:
|
||||
- Release
|
||||
- Preview
|
||||
- Dev
|
||||
- name: buildTerminal
|
||||
displayName: "Build Windows Terminal MSIX"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: runCompliance
|
||||
displayName: "Run Compliance and Security Build"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: publishSymbolsToPublic
|
||||
displayName: "Publish Symbols to MSDL"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildTerminalVPack
|
||||
displayName: "Build Windows Terminal VPack"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildConPTY
|
||||
displayName: "Build ConPTY NuGet"
|
||||
type: boolean
|
||||
@@ -32,53 +47,682 @@ parameters:
|
||||
- Instrument
|
||||
- None
|
||||
- name: buildConfigurations
|
||||
displayName: "Build Configurations"
|
||||
type: object
|
||||
default:
|
||||
- Release
|
||||
- name: buildPlatforms
|
||||
displayName: "Build Platforms"
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
- name: codeSign
|
||||
displayName: "Sign all build outputs"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: generateSbom
|
||||
displayName: "Generate a Bill of Materials"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: terminalInternalPackageVersion
|
||||
displayName: "Terminal Internal Package Version"
|
||||
type: string
|
||||
default: '0.0.8'
|
||||
|
||||
- name: publishSymbolsToPublic
|
||||
displayName: "Publish Symbols to MSDL"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: publishVpackToWindows
|
||||
displayName: "Publish VPack to Windows"
|
||||
type: boolean
|
||||
default: false
|
||||
variables:
|
||||
MakeAppxPath: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\MakeAppx.exe'
|
||||
TerminalInternalPackageVersion: "0.0.8"
|
||||
# If we are building a branch called "release-*", change the NuGet suffix
|
||||
# to "preview". If we don't do that, XES will set the suffix to "release1"
|
||||
# because it truncates the value after the first period.
|
||||
# We also want to disable the suffix entirely if we're Release branded while
|
||||
# on a release branch.
|
||||
# main is special, however. XES ignores main. Since we never produce actual
|
||||
# shipping builds from main, we want to force it to have a beta label as
|
||||
# well.
|
||||
#
|
||||
# In effect:
|
||||
# BRANCH / BRANDING | Release | Preview
|
||||
# ------------------|----------------------------|-----------------------------
|
||||
# release-* | 1.12.20220427 | 1.13.20220427-preview
|
||||
# main | 1.14.20220427-experimental | 1.14.20220427-experimental
|
||||
# all others | 1.14.20220427-mybranch | 1.14.20220427-mybranch
|
||||
${{ if startsWith(variables['Build.SourceBranchName'], 'release-') }}:
|
||||
${{ if eq(parameters.branding, 'Release') }}:
|
||||
NoNuGetPackBetaVersion: true
|
||||
${{ else }}:
|
||||
NuGetPackBetaVersion: preview
|
||||
${{ elseif eq(variables['Build.SourceBranchName'], 'main') }}:
|
||||
NuGetPackBetaVersion: experimental
|
||||
|
||||
name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)
|
||||
resources:
|
||||
repositories:
|
||||
- repository: self
|
||||
type: git
|
||||
ref: main
|
||||
jobs:
|
||||
- job: Build
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ each platform in parameters.buildPlatforms }}:
|
||||
${{ config }}_${{ platform }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
BuildPlatform: ${{ platform }}
|
||||
displayName: Build
|
||||
timeoutInMinutes: 240
|
||||
cancelTimeoutInMinutes: 1
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- task: PowerShell@2
|
||||
displayName: Rationalize Build Platform
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Arch = "$(BuildPlatform)"
|
||||
|
||||
extends:
|
||||
template: templates-v2/pipeline-full-release-build.yml
|
||||
parameters:
|
||||
branding: ${{ parameters.branding }}
|
||||
buildTerminal: ${{ parameters.buildTerminal }}
|
||||
buildConPTY: ${{ parameters.buildConPTY }}
|
||||
buildWPF: ${{ parameters.buildWPF }}
|
||||
pgoBuildMode: ${{ parameters.pgoBuildMode }}
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
terminalInternalPackageVersion: ${{ parameters.terminalInternalPackageVersion }}
|
||||
publishSymbolsToPublic: ${{ parameters.publishSymbolsToPublic }}
|
||||
publishVpackToWindows: ${{ parameters.publishVpackToWindows }}
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
- template: .\templates\restore-nuget-steps.yml
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download terminal-internal Universal Package
|
||||
inputs:
|
||||
feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
|
||||
packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
|
||||
versionListDownload: $(TerminalInternalPackageVersion)
|
||||
- task: TouchdownBuildTask@1
|
||||
displayName: Download Localization Files
|
||||
inputs:
|
||||
teamId: 7105
|
||||
authId: $(TouchdownAppId)
|
||||
authKey: $(TouchdownAppKey)
|
||||
resourceFilePath: >-
|
||||
src\cascadia\TerminalApp\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalApp\Resources\en-US\ContextMenu.resw
|
||||
|
||||
src\cascadia\TerminalControl\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalConnection\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalSettingsModel\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalSettingsEditor\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\CascadiaPackage\Resources\en-US\Resources.resw
|
||||
appendRelativeDir: true
|
||||
localizationTarget: false
|
||||
pseudoSetting: Included
|
||||
- task: PowerShell@2
|
||||
displayName: Move Loc files one level up
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Files = Get-ChildItem . -R -Filter 'Resources.resw' | ? FullName -Like '*en-US\*\Resources.resw'
|
||||
|
||||
$Files | % { Move-Item -Verbose $_.Directory $_.Directory.Parent.Parent -EA:Ignore }
|
||||
pwsh: true
|
||||
- task: PowerShell@2
|
||||
displayName: Copy the Context Menu Loc Resources to CascadiaPackage
|
||||
inputs:
|
||||
filePath: ./build/scripts/Copy-ContextMenuResourcesToCascadiaPackage.ps1
|
||||
pwsh: true
|
||||
- task: PowerShell@2
|
||||
displayName: Generate NOTICE.html from NOTICE.md
|
||||
inputs:
|
||||
filePath: .\build\scripts\Generate-ThirdPartyNotices.ps1
|
||||
arguments: -MarkdownNoticePath .\NOTICE.md -OutputPath .\src\cascadia\CascadiaPackage\NOTICE.html
|
||||
pwsh: true
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution **\OpenConsole.sln
|
||||
condition: true
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /t:Terminal\CascadiaPackage /p:WindowsTerminalReleaseBuild=true /bl:$(Build.SourcesDirectory)\msbuild.binlog
|
||||
platform: $(BuildPlatform)
|
||||
configuration: $(BuildConfiguration)
|
||||
clean: true
|
||||
maximumCpuCount: true
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: binlog'
|
||||
condition: failed()
|
||||
continueOnError: True
|
||||
inputs:
|
||||
PathtoPublish: $(Build.SourcesDirectory)\msbuild.binlog
|
||||
ArtifactName: binlog-$(BuildPlatform)
|
||||
- task: PowerShell@2
|
||||
displayName: Check MSIX for common regressions
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Package = Get-ChildItem -Recurse -Filter "CascadiaPackage_*.msix"
|
||||
|
||||
.\build\scripts\Test-WindowsTerminalPackage.ps1 -Verbose -Path $Package.FullName
|
||||
pwsh: true
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution **\OpenConsole.sln for PublicTerminalCore
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /p:WindowsTerminalReleaseBuild=true /t:Terminal\wpf\PublicTerminalCore
|
||||
platform: $(BuildPlatform)
|
||||
configuration: $(BuildConfiguration)
|
||||
- ${{ if eq(parameters.buildConPTY, true) }}:
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution **\OpenConsole.sln for ConPTY
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
msbuildArgs: /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }} /p:WindowsTerminalReleaseBuild=true /t:Conhost\Host_EXE;Conhost\winconpty_DLL
|
||||
platform: $(BuildPlatform)
|
||||
configuration: $(BuildConfiguration)
|
||||
- task: PowerShell@2
|
||||
displayName: Source Index PDBs
|
||||
inputs:
|
||||
filePath: build\scripts\Index-Pdbs.ps1
|
||||
arguments: -SearchDir '$(Build.SourcesDirectory)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
|
||||
errorActionPreference: silentlyContinue
|
||||
pwsh: true
|
||||
- task: PowerShell@2
|
||||
displayName: Run Unit Tests
|
||||
condition: and(succeeded(), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
|
||||
enabled: False
|
||||
inputs:
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)'
|
||||
- task: PowerShell@2
|
||||
displayName: Run Feature Tests
|
||||
condition: and(succeeded(), eq(variables['BuildPlatform'], 'x64'))
|
||||
enabled: False
|
||||
inputs:
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)'
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy *.msix and symbols to Artifacts
|
||||
inputs:
|
||||
Contents: >-
|
||||
**/*.msix
|
||||
|
||||
**/*.appxsym
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/appx
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
displayName: 'Generate SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/appx'
|
||||
|
||||
- pwsh: |-
|
||||
$Package = (Get-ChildItem "$(Build.ArtifactStagingDirectory)/appx" -Recurse -Filter "Cascadia*.msix" | Select -First 1)
|
||||
$PackageFilename = $Package.FullName
|
||||
Write-Host "##vso[task.setvariable variable=WindowsTerminalPackagePath]${PackageFilename}"
|
||||
& "$(MakeAppxPath)" unpack /p $PackageFilename /d "$(Build.SourcesDirectory)\UnpackedTerminalPackage"
|
||||
displayName: Unpack the new Terminal package for signing
|
||||
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Submit Terminal's binaries for signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: '$(Build.SourcesDirectory)\UnpackedTerminalPackage'
|
||||
signType: batchSigning
|
||||
batchSignPolicyFile: '$(Build.SourcesDirectory)\build\config\ESRPSigning_Terminal.json'
|
||||
|
||||
- pwsh: |-
|
||||
$PackageFilename = "$(WindowsTerminalPackagePath)"
|
||||
Remove-Item "$(Build.SourcesDirectory)\UnpackedTerminalPackage\CodeSignSummary*"
|
||||
& "$(MakeAppxPath)" pack /h SHA256 /o /p $PackageFilename /d "$(Build.SourcesDirectory)\UnpackedTerminalPackage"
|
||||
displayName: Re-pack the new Terminal package after signing
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (appx)
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)/appx
|
||||
ArtifactName: appx-$(BuildPlatform)-$(BuildConfiguration)
|
||||
|
||||
- pwsh: |-
|
||||
$XamlAppxPath = (Get-Item "src\cascadia\CascadiaPackage\AppPackages\*\Dependencies\$(BuildPlatform)\Microsoft.UI.Xaml*.appx").FullName
|
||||
& .\build\scripts\New-UnpackagedTerminalDistribution.ps1 -TerminalAppX $(WindowsTerminalPackagePath) -XamlAppX $XamlAppxPath -Destination "$(Build.ArtifactStagingDirectory)/unpackaged"
|
||||
displayName: Build Unpackaged Distribution
|
||||
|
||||
- publish: $(Build.ArtifactStagingDirectory)/unpackaged
|
||||
artifact: unpackaged-$(BuildPlatform)-$(BuildConfiguration)
|
||||
displayName: Publish Artifact (unpackaged)
|
||||
|
||||
- ${{ if eq(parameters.buildConPTY, true) }}:
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy ConPTY to Artifacts
|
||||
inputs:
|
||||
Contents: |-
|
||||
$(Build.SourcesDirectory)/bin/**/conpty.dll
|
||||
$(Build.SourcesDirectory)/bin/**/conpty.lib
|
||||
$(Build.SourcesDirectory)/bin/**/conpty.pdb
|
||||
$(Build.SourcesDirectory)/bin/**/OpenConsole.exe
|
||||
$(Build.SourcesDirectory)/bin/**/OpenConsole.pdb
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/conpty
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (ConPTY)
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)/conpty
|
||||
ArtifactName: conpty-dll-$(BuildPlatform)-$(BuildConfiguration)
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy PublicTerminalCore.dll to Artifacts
|
||||
inputs:
|
||||
Contents: >-
|
||||
**/PublicTerminalCore.dll
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/wpf
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (PublicTerminalCore)
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)/wpf
|
||||
ArtifactName: wpf-dll-$(BuildPlatform)-$(BuildConfiguration)
|
||||
|
||||
- task: PublishSymbols@2
|
||||
displayName: Publish symbols path
|
||||
continueOnError: True
|
||||
inputs:
|
||||
SearchPattern: |
|
||||
$(Build.SourcesDirectory)/bin/**/*.pdb
|
||||
$(Build.SourcesDirectory)/bin/**/*.exe
|
||||
$(Build.SourcesDirectory)/bin/**/*.dll
|
||||
IndexSources: false
|
||||
SymbolServerType: TeamServices
|
||||
|
||||
- ${{ if eq(parameters.runCompliance, true) }}:
|
||||
- template: ./templates/build-console-compliance-job.yml
|
||||
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- job: BundleAndSign
|
||||
displayName: Create and sign AppX/MSIX bundles
|
||||
variables:
|
||||
${{ if eq(parameters.branding, 'Release') }}:
|
||||
BundleStemName: Microsoft.WindowsTerminal
|
||||
${{ elseif eq(parameters.branding, 'Preview') }}:
|
||||
BundleStemName: Microsoft.WindowsTerminalPreview
|
||||
${{ else }}:
|
||||
BundleStemName: WindowsTerminalDev
|
||||
dependsOn: Build
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download Artifacts ${{ platform }}
|
||||
inputs:
|
||||
artifactName: appx-${{ platform }}-Release
|
||||
# Add 3000 to the major version component, but only for the bundle.
|
||||
# This is to ensure that it is newer than "2022.xx.yy.zz" or whatever the original bundle versions were before
|
||||
# we switched to uniform naming.
|
||||
- pwsh: |-
|
||||
$VersionEpoch = 3000
|
||||
$Components = "$(XES_APPXMANIFESTVERSION)" -Split "\."
|
||||
$Components[0] = ([int]$Components[0] + $VersionEpoch)
|
||||
$BundleVersion = $Components -Join "."
|
||||
New-Item -Type Directory "$(System.ArtifactsDirectory)\bundle"
|
||||
.\build\scripts\Create-AppxBundle.ps1 -InputPath "$(System.ArtifactsDirectory)" -ProjectName CascadiaPackage -BundleVersion $BundleVersion -OutputPath "$(System.ArtifactsDirectory)\bundle\$(BundleStemName)_$(XES_APPXMANIFESTVERSION)_8wekyb3d8bbwe.msixbundle"
|
||||
displayName: Create WindowsTerminal*.msixbundle
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Submit *.msixbundle to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(System.ArtifactsDirectory)\bundle
|
||||
Pattern: $(BundleStemName)*.msixbundle
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolSign",
|
||||
"Parameters": {
|
||||
"OpusName": "Microsoft",
|
||||
"OpusInfo": "http://www.microsoft.com",
|
||||
"FileDigest": "/fd \"SHA256\"",
|
||||
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: appxbundle-signed'
|
||||
inputs:
|
||||
PathtoPublish: $(System.ArtifactsDirectory)\bundle
|
||||
ArtifactName: appxbundle-signed
|
||||
|
||||
- ${{ if eq(parameters.buildConPTY, true) }}:
|
||||
- job: PackageAndSignConPTY
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ config }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
displayName: Create NuGet Package (ConPTY)
|
||||
dependsOn: Build
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download ${{ platform }} ConPTY binaries
|
||||
inputs:
|
||||
artifactName: conpty-dll-${{ platform }}-$(BuildConfiguration)
|
||||
downloadPath: bin\${{ platform }}\$(BuildConfiguration)\
|
||||
extractTars: false
|
||||
- task: PowerShell@2
|
||||
displayName: Move downloaded artifacts around
|
||||
inputs:
|
||||
targetType: inline
|
||||
# Find all artifact files and move them up a directory. Ugh.
|
||||
script: |-
|
||||
Get-ChildItem bin -Recurse -Directory -Filter conpty-dll-* | % {
|
||||
$_ | Get-ChildItem -Recurse -File | % {
|
||||
Move-Item -Verbose $_.FullName $_.Directory.Parent.FullName
|
||||
}
|
||||
}
|
||||
Move-Item bin\x86 bin\Win32
|
||||
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Submit ConPTY libraries and OpenConsole for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: '$(Build.SourcesDirectory)/bin'
|
||||
signType: batchSigning
|
||||
batchSignPolicyFile: '$(Build.SourcesDirectory)\build\config\ESRPSigning_ConPTY.json'
|
||||
|
||||
- task: NuGetToolInstaller@1
|
||||
displayName: Use NuGet 5.10.0
|
||||
inputs:
|
||||
versionSpec: 5.10.0
|
||||
- task: NuGetCommand@2
|
||||
displayName: NuGet pack
|
||||
inputs:
|
||||
command: pack
|
||||
packagesToPack: $(Build.SourcesDirectory)\src\winconpty\package\winconpty.nuspec
|
||||
packDestination: '$(Build.ArtifactStagingDirectory)/nupkg'
|
||||
versioningScheme: byEnvVar
|
||||
versionEnvVar: XES_PACKAGEVERSIONNUMBER
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (nupkg)
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)\nupkg
|
||||
ArtifactName: conpty-nupkg-$(BuildConfiguration)
|
||||
|
||||
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- job: PackageAndSignWPF
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ config }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
displayName: Create NuGet Package (WPF Terminal Control)
|
||||
dependsOn: Build
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download ${{ platform }} PublicTerminalCore
|
||||
inputs:
|
||||
artifactName: wpf-dll-${{ platform }}-$(BuildConfiguration)
|
||||
itemPattern: '**/*.dll'
|
||||
downloadPath: bin\${{ platform }}\$(BuildConfiguration)\
|
||||
extractTars: false
|
||||
- task: PowerShell@2
|
||||
displayName: Move downloaded artifacts around
|
||||
inputs:
|
||||
targetType: inline
|
||||
# Find all artifact files and move them up a directory. Ugh.
|
||||
script: |-
|
||||
Get-ChildItem bin -Recurse -Directory -Filter wpf-dll-* | % {
|
||||
$_ | Get-ChildItem -Recurse -File | % {
|
||||
Move-Item -Verbose $_.FullName $_.Directory.Parent.FullName
|
||||
}
|
||||
}
|
||||
Move-Item bin\x86 bin\Win32
|
||||
- task: NuGetToolInstaller@1
|
||||
displayName: Use NuGet 5.10.0
|
||||
inputs:
|
||||
versionSpec: 5.10.0
|
||||
- task: NuGetCommand@2
|
||||
displayName: NuGet restore copy
|
||||
inputs:
|
||||
selectOrConfig: config
|
||||
nugetConfigPath: NuGet.Config
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution **\OpenConsole.sln for WPF Control
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
msbuildArgs: /p:WindowsTerminalReleaseBuild=$(UseReleaseBranding);Version=$(XES_PACKAGEVERSIONNUMBER) /t:Pack
|
||||
platform: Any CPU
|
||||
configuration: $(BuildConfiguration)
|
||||
maximumCpuCount: true
|
||||
- task: PublishSymbols@2
|
||||
displayName: Publish symbols path
|
||||
continueOnError: True
|
||||
inputs:
|
||||
SearchPattern: |
|
||||
$(Build.SourcesDirectory)/bin/**/*.pdb
|
||||
$(Build.SourcesDirectory)/bin/**/*.exe
|
||||
$(Build.SourcesDirectory)/bin/**/*.dll
|
||||
IndexSources: false
|
||||
SymbolServerType: TeamServices
|
||||
SymbolsArtifactName: Symbols_WPF_$(BuildConfiguration)
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy *.nupkg to Artifacts
|
||||
inputs:
|
||||
Contents: '**/*Wpf*.nupkg'
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (nupkg)
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)\nupkg
|
||||
ArtifactName: wpf-nupkg-$(BuildConfiguration)
|
||||
|
||||
- ${{ if eq(parameters.publishSymbolsToPublic, true) }}:
|
||||
- job: PublishSymbols
|
||||
displayName: Publish Symbols
|
||||
dependsOn: BundleAndSign
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
submodules: true
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
|
||||
- template: .\templates\restore-nuget-steps.yml
|
||||
|
||||
# Download the appx-PLATFORM-CONFIG-VERSION artifact for every platform/version combo
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download Symbols ${{ platform }}
|
||||
inputs:
|
||||
artifactName: appx-${{ platform }}-Release
|
||||
|
||||
# It seems easier to do this -- download every appxsym -- then enumerate all the PDBs in the build directory for the
|
||||
# public symbol push. Otherwise, we would have to list all of the PDB files one by one.
|
||||
- pwsh: |-
|
||||
mkdir $(Build.SourcesDirectory)/appxsym-temp
|
||||
Get-ChildItem "$(System.ArtifactsDirectory)" -Filter *.appxsym -Recurse | % {
|
||||
$src = $_.FullName
|
||||
$dest = Join-Path "$(Build.SourcesDirectory)/appxsym-temp/" $_.Name
|
||||
|
||||
mkdir $dest
|
||||
Write-Host "Extracting $src to $dest..."
|
||||
tar -x -v -f $src -C $dest
|
||||
}
|
||||
displayName: Extract symbols for public consumption
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: Source Index PDBs (the public ones)
|
||||
inputs:
|
||||
filePath: build\scripts\Index-Pdbs.ps1
|
||||
arguments: -SearchDir '$(Build.SourcesDirectory)/appxsym-temp' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
|
||||
pwsh: true
|
||||
|
||||
# Publish the app symbols to the public MSDL symbol server
|
||||
# accessible via https://msdl.microsoft.com/download/symbols
|
||||
- task: PublishSymbols@2
|
||||
displayName: 'Publish app symbols to MSDL'
|
||||
inputs:
|
||||
symbolsFolder: '$(Build.SourcesDirectory)/appxsym-temp'
|
||||
searchPattern: '**/*.pdb'
|
||||
SymbolsMaximumWaitTime: 30
|
||||
SymbolServerType: 'TeamServices'
|
||||
SymbolsProduct: 'Windows Terminal Application Binaries'
|
||||
SymbolsVersion: '$(XES_APPXMANIFESTVERSION)'
|
||||
# The ADO task does not support indexing of GitHub sources.
|
||||
indexSources: false
|
||||
detailedLog: true
|
||||
# There is a bug which causes this task to fail if LIB includes an inaccessible path (even though it does not depend on it).
|
||||
# To work around this issue, we just force LIB to be any dir that we know exists.
|
||||
# Copied from https://github.com/microsoft/icu/blob/f869c214adc87415dfe751d81f42f1bca55dcf5f/build/azure-nuget.yml#L564-L583
|
||||
env:
|
||||
LIB: $(Build.SourcesDirectory)
|
||||
ArtifactServices_Symbol_AccountName: microsoftpublicsymbols
|
||||
ArtifactServices_Symbol_PAT: $(ADO_microsoftpublicsymbols_PAT)
|
||||
|
||||
|
||||
- ${{ if eq(parameters.buildTerminalVPack, true) }}:
|
||||
- job: VPack
|
||||
displayName: Create Windows vPack
|
||||
dependsOn: BundleAndSign
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
submodules: true
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download Build Artifacts
|
||||
inputs:
|
||||
artifactName: appxbundle-signed
|
||||
extractTars: false
|
||||
- task: PowerShell@2
|
||||
displayName: Rename and stage packages for vpack
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
# Rename to known/fixed name for Windows build system
|
||||
|
||||
Get-ChildItem Microsoft.WindowsTerminal_*.msixbundle | Rename-Item -NewName { 'Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle' }
|
||||
|
||||
|
||||
# Create vpack directory and place item inside
|
||||
|
||||
mkdir WindowsTerminal.app
|
||||
|
||||
mv Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle .\WindowsTerminal.app\
|
||||
workingDirectory: $(System.ArtifactsDirectory)\appxbundle-signed
|
||||
- task: PkgESVPack@12
|
||||
displayName: 'Package ES - VPack'
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
inputs:
|
||||
sourceDirectory: $(System.ArtifactsDirectory)\appxbundle-signed\WindowsTerminal.app
|
||||
description: VPack for the Windows Terminal Application
|
||||
pushPkgName: WindowsTerminal.app
|
||||
owner: conhost
|
||||
githubToken: $(GitHubTokenForVpackProvenance)
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: 'Copy VPack Manifest to Drop'
|
||||
inputs:
|
||||
targetPath: $(XES_VPACKMANIFESTDIRECTORY)
|
||||
artifactName: VPackManifest
|
||||
- task: PkgESFCIBGit@12
|
||||
displayName: 'Submit VPack Manifest to Windows'
|
||||
inputs:
|
||||
configPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
|
||||
artifactsDirectory: $(XES_VPACKMANIFESTDIRECTORY)
|
||||
prTimeOut: 5
|
||||
...
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
parameters:
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
- name: generateSbom
|
||||
type: boolean
|
||||
default: false
|
||||
- name: codeSign
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: PackWPF
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: publishArtifacts
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
${{ if eq(parameters.codeSign, true) }}:
|
||||
displayName: Pack and Sign Microsoft.Terminal.Wpf
|
||||
${{ else }}:
|
||||
displayName: Pack Microsoft.Terminal.Wpf
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ config }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
variables:
|
||||
OutputBuildPlatform: AnyCPU
|
||||
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
|
||||
JobOutputDirectory: $(Build.ArtifactStagingDirectory)\nupkg
|
||||
JobOutputArtifactName: wpf-nupkg-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- template: steps-download-bin-dir-artifact.yml
|
||||
parameters:
|
||||
buildPlatforms:
|
||||
- ${{ parameters.buildPlatforms }}
|
||||
- Any CPU # Make sure we grab the precompiled WPF bits
|
||||
# This build is already matrix'd on configuration, so
|
||||
# just pass a single config into the download template.
|
||||
buildConfigurations:
|
||||
- $(BuildConfiguration)
|
||||
artifactStem: ${{ parameters.artifactStem }}
|
||||
|
||||
- template: .\steps-restore-nuget.yml
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: Build solution OpenConsole.sln for WPF Control (Pack)
|
||||
inputs:
|
||||
solution: 'OpenConsole.sln'
|
||||
msbuildArgs: >-
|
||||
/p:WindowsTerminalReleaseBuild=true;Version=$(XES_PACKAGEVERSIONNUMBER)
|
||||
/p:NoBuild=true
|
||||
/p:IncludeSymbols=true
|
||||
/t:Terminal\wpf\WpfTerminalControl:Pack
|
||||
platform: Any CPU
|
||||
configuration: $(BuildConfiguration)
|
||||
maximumCpuCount: true
|
||||
clean: false
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy *.nupkg to Artifacts
|
||||
inputs:
|
||||
Contents: 'bin/**/*Wpf*.nupkg'
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- task: EsrpCodeSigning@3
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
|
||||
- ${{ if eq(parameters.generateSbom, true) }}:
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
displayName: 'Generate SBOM manifest (wpf)'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/nupkg'
|
||||
BuildComponentPath: '$(Build.SourcesDirectory)/bin'
|
||||
|
||||
- task: DropValidatorTask@0
|
||||
displayName: 'Validate wpf SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/nupkg'
|
||||
OutputPath: 'output.json'
|
||||
ValidateSignature: true
|
||||
Verbosity: 'Verbose'
|
||||
|
||||
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
||||
- publish: $(JobOutputDirectory)
|
||||
artifact: $(JobOutputArtifactName)
|
||||
displayName: Publish nupkg
|
||||
@@ -1,293 +0,0 @@
|
||||
parameters:
|
||||
- name: branding
|
||||
type: string
|
||||
default: Dev
|
||||
- name: additionalBuildOptions
|
||||
type: string
|
||||
default: ''
|
||||
- name: buildTerminal
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildConPTY
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildWPF
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildWPFDotNetComponents # This weird hack is to make sure we sign and source index the .NET pieces
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildEverything
|
||||
displayName: "Build Everything (Overrides all other build options)"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pgoBuildMode
|
||||
type: string
|
||||
default: None
|
||||
values: [Optimize, Instrument, None]
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
default:
|
||||
- Release
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
- name: generateSbom
|
||||
type: boolean
|
||||
default: false
|
||||
- name: codeSign
|
||||
type: boolean
|
||||
default: false
|
||||
- name: keepAllExpensiveBuildOutputs
|
||||
type: boolean
|
||||
default: true
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: 'Build'
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: beforeBuildSteps
|
||||
type: stepList
|
||||
default: []
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: publishArtifacts
|
||||
type: boolean
|
||||
default: true
|
||||
- name: removeAllNonSignedFiles
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ each platform in parameters.buildPlatforms }}:
|
||||
${{ config }}_${{ platform }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
BuildPlatform: ${{ platform }}
|
||||
${{ if eq(platform, 'x86') }}:
|
||||
OutputBuildPlatform: Win32
|
||||
${{ elseif eq(platform, 'Any CPU') }}:
|
||||
OutputBuildPlatform: AnyCPU
|
||||
${{ else }}:
|
||||
OutputBuildPlatform: ${{ platform }}
|
||||
variables:
|
||||
MakeAppxPath: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\MakeAppx.exe'
|
||||
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
|
||||
# Azure DevOps abhors a vacuum
|
||||
# If these are blank, expansion will fail later on... which will result in direct substitution of the variable *names*
|
||||
# later on. We'll just... set them to a single space and if we need to, check IsNullOrWhiteSpace.
|
||||
# Yup.
|
||||
BuildTargetParameter: ' '
|
||||
SelectedSigningFragments: ' '
|
||||
JobOutputDirectory: $(Terminal.BinDir)
|
||||
JobOutputArtifactName: build-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
displayName: Build
|
||||
timeoutInMinutes: 240
|
||||
cancelTimeoutInMinutes: 1
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
# This generates either nothing for BuildTargetParameter, or /t:X;Y;Z, to control targets later.
|
||||
- pwsh: |-
|
||||
If (-Not [bool]::Parse("${{ parameters.buildEverything }}")) {
|
||||
$BuildTargets = @()
|
||||
$SignFragments = @()
|
||||
If ([bool]::Parse("${{ parameters.buildTerminal }}")) {
|
||||
$BuildTargets += "Terminal\CascadiaPackage"
|
||||
$SignFragments += "terminal_constituents"
|
||||
}
|
||||
If ([bool]::Parse("${{ parameters.buildWPFDotNetComponents }}")) {
|
||||
$BuildTargets += "Terminal\wpf\WpfTerminalControl"
|
||||
$SignFragments += "wpfdotnet"
|
||||
}
|
||||
If ([bool]::Parse("${{ parameters.buildWPF }}")) {
|
||||
$BuildTargets += "Terminal\wpf\PublicTerminalCore"
|
||||
$SignFragments += "wpf"
|
||||
}
|
||||
If ([bool]::Parse("${{ parameters.buildConPTY }}")) {
|
||||
$BuildTargets += "Conhost\Host_EXE;Conhost\winconpty_DLL"
|
||||
$SignFragments += "conpty"
|
||||
}
|
||||
Write-Host "Targets: $($BuildTargets -Join ";")"
|
||||
Write-Host "Sign targets: $($SignFragments -Join ";")"
|
||||
Write-Host "##vso[task.setvariable variable=BuildTargetParameter]/t:$($BuildTargets -Join ";")"
|
||||
Write-Host "##vso[task.setvariable variable=SelectedSigningFragments]$($SignFragments -Join ";")"
|
||||
}
|
||||
displayName: Prepare Build and Sign Targets
|
||||
|
||||
- pwsh: |-
|
||||
.\build\scripts\Generate-ThirdPartyNotices.ps1 -MarkdownNoticePath .\NOTICE.md -OutputPath .\src\cascadia\CascadiaPackage\NOTICE.html
|
||||
displayName: Generate NOTICE.html from NOTICE.md
|
||||
|
||||
- template: .\steps-restore-nuget.yml
|
||||
|
||||
- ${{ parameters.beforeBuildSteps }}
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: Build OpenConsole.sln
|
||||
inputs:
|
||||
solution: 'OpenConsole.sln'
|
||||
msbuildArgs: >-
|
||||
/p:WindowsTerminalOfficialBuild=true;WindowsTerminalBranding=${{ parameters.branding }};PGOBuildMode=${{ parameters.pgoBuildMode }}
|
||||
${{ parameters.additionalBuildOptions }}
|
||||
/bl:$(Build.SourcesDirectory)\msbuild.binlog
|
||||
$(BuildTargetParameter)
|
||||
platform: $(BuildPlatform)
|
||||
configuration: $(BuildConfiguration)
|
||||
maximumCpuCount: true
|
||||
|
||||
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
||||
- publish: $(Build.SourcesDirectory)/msbuild.binlog
|
||||
artifact: logs-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
condition: always()
|
||||
displayName: Publish Build Log
|
||||
- ${{ else }}:
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy Build Log
|
||||
inputs:
|
||||
contents: $(Build.SourcesDirectory)/msbuild.binlog
|
||||
TargetFolder: $(Terminal.BinDir)
|
||||
|
||||
# This saves ~2GiB per architecture. We won't need these later.
|
||||
# Removes:
|
||||
# - All .lib that do not have an associated .exp (which would indicate that they are import libs)
|
||||
# - All .pdbs from those .libs (which were only used during linking)
|
||||
# - Directories ending in Lib (static lib projects that we fully linked into DLLs which may also contain unnecessary resources)
|
||||
# - All LocalTests_ project outputs, as they were subsumed into TestHostApp
|
||||
# - All PDB files inside the WindowsTerminal/ output, which do not belong there.
|
||||
# - console.dll, which apparently breaks XFGCheck? lol.
|
||||
- pwsh: |-
|
||||
$binDir = '$(Terminal.BinDir)'
|
||||
$ImportLibs = Get-ChildItem $binDir -Recurse -File -Filter '*.exp' | ForEach-Object { $_.FullName -Replace "exp$","lib" }
|
||||
$StaticLibs = Get-ChildItem $binDir -Recurse -File -Filter '*.lib' | Where-Object FullName -NotIn $ImportLibs
|
||||
|
||||
$Items = @()
|
||||
$Items += $StaticLibs
|
||||
$Items += Get-Item ($StaticLibs.FullName -Replace "lib$","pdb") -ErrorAction:Ignore
|
||||
$Items += Get-ChildItem $binDir -Directory -Filter '*Lib'
|
||||
$Items += Get-ChildItem $binDir -Directory -Filter 'LocalTests_*'
|
||||
$Items += Get-ChildItem "${$binDir}\WindowsTerminal" -Filter '*.pdb' -ErrorAction:Ignore
|
||||
|
||||
If (-Not [bool]::Parse('${{ parameters.keepAllExpensiveBuildOutputs }}')) {
|
||||
$Items += Get-ChildItem '$(Terminal.BinDir)' -Filter '*.pdb' -Recurse
|
||||
}
|
||||
|
||||
$Items += Get-ChildItem $binDir -Filter 'console.dll'
|
||||
|
||||
$Items | Remove-Item -Recurse -Force -Verbose -ErrorAction:Ignore
|
||||
displayName: Clean up static libs and extra symbols
|
||||
errorActionPreference: silentlyContinue # It's OK if this silently fails
|
||||
|
||||
# We cannot index PDBs that we have deleted!
|
||||
- ${{ if eq(parameters.keepAllExpensiveBuildOutputs, true) }}:
|
||||
- pwsh: |-
|
||||
build\scripts\Index-Pdbs.ps1 -SearchDir '$(Terminal.BinDir)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
|
||||
displayName: Source Index PDBs
|
||||
errorActionPreference: silentlyContinue
|
||||
|
||||
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
|
||||
- pwsh: |-
|
||||
$Package = (Get-ChildItem -Recurse -Filter "CascadiaPackage*.msix" | Select -First 1)
|
||||
$PackageFilename = $Package.FullName
|
||||
Write-Host "##vso[task.setvariable variable=WindowsTerminalPackagePath]${PackageFilename}"
|
||||
displayName: Locate the MSIX
|
||||
|
||||
# CHECK EXCEPTION
|
||||
# PGO requires a desktop CRT
|
||||
- ${{ if ne(parameters.pgoBuildMode, 'Instrument') }}:
|
||||
- pwsh: |-
|
||||
.\build\scripts\Test-WindowsTerminalPackage.ps1 -Verbose -Path "$(WindowsTerminalPackagePath)"
|
||||
displayName: Check MSIX for common regressions
|
||||
condition: and(succeeded(), ne(variables.WindowsTerminalPackagePath, ''))
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- pwsh: |-
|
||||
& "$(MakeAppxPath)" unpack /p "$(WindowsTerminalPackagePath)" /d "$(Terminal.BinDir)/PackageContents"
|
||||
displayName: Unpack the MSIX for signing
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- template: steps-create-signing-config.yml
|
||||
parameters:
|
||||
outFile: '$(Build.SourcesDirectory)/ESRPSigningConfig.json'
|
||||
stage: build
|
||||
fragments: $(SelectedSigningFragments)
|
||||
|
||||
# Code-sign everything we just put together.
|
||||
# We run the signing in Terminal.BinDir, because all of the signing batches are relative to the final architecture/configuration output folder.
|
||||
- task: EsrpCodeSigning@3
|
||||
displayName: Submit Signing Request
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: '$(Terminal.BinDir)'
|
||||
signType: batchSigning
|
||||
batchSignPolicyFile: '$(Build.SourcesDirectory)/ESRPSigningConfig.json'
|
||||
|
||||
# We only need to re-pack the MSIX if we actually signed, so this can stay in the codeSign conditional
|
||||
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
|
||||
- pwsh: |-
|
||||
$outDir = New-Item -Type Directory "$(Terminal.BinDir)/_appx" -ErrorAction:Ignore
|
||||
$PackageFilename = Join-Path $outDir.FullName (Split-Path -Leaf "$(WindowsTerminalPackagePath)")
|
||||
& "$(MakeAppxPath)" pack /h SHA256 /o /p $PackageFilename /d "$(Terminal.BinDir)/PackageContents"
|
||||
Write-Host "##vso[task.setvariable variable=WindowsTerminalPackagePath]${PackageFilename}"
|
||||
displayName: Re-pack the new Terminal package after signing
|
||||
|
||||
# Some of our governed pipelines explicitly fail builds that have *any* non-codesigned filed (!)
|
||||
- ${{ if eq(parameters.removeAllNonSignedFiles, true) }}:
|
||||
- pwsh: |-
|
||||
Get-ChildItem "$(Terminal.BinDir)" -Recurse -Include "*.dll","*.exe" |
|
||||
Where-Object { (Get-AuthenticodeSignature $_).Status -Ne "Valid" } |
|
||||
Remove-Item -Verbose -Force
|
||||
displayName: Remove all non-signed output files
|
||||
|
||||
- ${{ else }}: # No Signing
|
||||
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
|
||||
- pwsh: |-
|
||||
$outDir = New-Item -Type Directory "$(Terminal.BinDir)/_appx" -ErrorAction:Ignore
|
||||
$PackageFilename = Join-Path $outDir.FullName (Split-Path -Leaf "$(WindowsTerminalPackagePath)")
|
||||
Copy-Item "$(WindowsTerminalPackagePath)" $PackageFilename
|
||||
Write-Host "##vso[task.setvariable variable=WindowsTerminalPackagePath]${PackageFilename}"
|
||||
displayName: Stage the package (unsigned)
|
||||
condition: and(succeeded(), ne(variables.WindowsTerminalPackagePath, ''))
|
||||
|
||||
- ${{ if or(parameters.buildTerminal, parameters.buildEverything) }}:
|
||||
- pwsh: |-
|
||||
$XamlAppxPath = (Get-Item "src\cascadia\CascadiaPackage\AppPackages\*\Dependencies\$(BuildPlatform)\Microsoft.UI.Xaml*.appx").FullName
|
||||
$outDir = New-Item -Type Directory "$(Terminal.BinDir)/_unpackaged" -ErrorAction:Ignore
|
||||
& .\build\scripts\New-UnpackagedTerminalDistribution.ps1 -TerminalAppX $(WindowsTerminalPackagePath) -XamlAppX $XamlAppxPath -Destination $outDir.FullName
|
||||
displayName: Build Unpackaged Distribution (from MSIX)
|
||||
condition: and(succeeded(), ne(variables.WindowsTerminalPackagePath, ''))
|
||||
|
||||
- ${{ if eq(parameters.generateSbom, true) }}:
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
displayName: 'Generate SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(Terminal.BinDir)'
|
||||
|
||||
- task: DropValidatorTask@0
|
||||
displayName: 'Validate SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(Terminal.BinDir)'
|
||||
OutputPath: 'output.json'
|
||||
ValidateSignature: true
|
||||
Verbosity: 'Verbose'
|
||||
|
||||
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
||||
- publish: $(Terminal.BinDir)
|
||||
artifact: $(JobOutputArtifactName)
|
||||
displayName: Publish All Outputs
|
||||
@@ -1,15 +0,0 @@
|
||||
jobs:
|
||||
- job: CodeFormatCheck
|
||||
displayName: Check Code Format
|
||||
pool: { vmImage: windows-2022 }
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: false
|
||||
clean: true
|
||||
|
||||
- powershell: |-
|
||||
.\build\scripts\Invoke-FormattingCheck.ps1
|
||||
displayName: 'Run formatters'
|
||||
@@ -1,150 +0,0 @@
|
||||
parameters:
|
||||
- name: branding
|
||||
type: string
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
- name: generateSbom
|
||||
type: boolean
|
||||
default: false
|
||||
- name: codeSign
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: Bundle
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: publishArtifacts
|
||||
type: boolean
|
||||
default: true
|
||||
- name: afterBuildSteps
|
||||
type: stepList
|
||||
default: []
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
${{ if eq(parameters.codeSign, true) }}:
|
||||
displayName: Pack and Sign Terminal MSIXBundle
|
||||
${{ else }}:
|
||||
displayName: Pack Terminal MSIXBundle
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ config }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
variables:
|
||||
${{ if eq(parameters.branding, 'Release') }}:
|
||||
BundleStemName: Microsoft.WindowsTerminal
|
||||
${{ elseif eq(parameters.branding, 'Preview') }}:
|
||||
BundleStemName: Microsoft.WindowsTerminalPreview
|
||||
${{ else }}:
|
||||
BundleStemName: WindowsTerminalDev
|
||||
JobOutputDirectory: '$(System.ArtifactsDirectory)/bundle'
|
||||
JobOutputArtifactName: appxbundle-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- template: steps-download-bin-dir-artifact.yml
|
||||
parameters:
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
# This build is already matrix'd on configuration, so
|
||||
# just pass a single config into the download template.
|
||||
buildConfigurations:
|
||||
- $(BuildConfiguration)
|
||||
artifactStem: ${{ parameters.artifactStem }}
|
||||
|
||||
# Add 3000 to the major version component, but only for the bundle.
|
||||
# This is to ensure that it is newer than "2022.xx.yy.zz" or whatever the original bundle versions were before
|
||||
# we switched to uniform naming.
|
||||
- pwsh: |-
|
||||
$VersionEpoch = 3000
|
||||
$Components = "$(XES_APPXMANIFESTVERSION)" -Split "\."
|
||||
$Components[0] = ([int]$Components[0] + $VersionEpoch)
|
||||
$BundleVersion = $Components -Join "."
|
||||
New-Item -Type Directory "$(System.ArtifactsDirectory)/bundle"
|
||||
$BundlePath = "$(System.ArtifactsDirectory)\bundle\$(BundleStemName)_$(XES_APPXMANIFESTVERSION)_8wekyb3d8bbwe.msixbundle"
|
||||
.\build\scripts\Create-AppxBundle.ps1 -InputPath 'bin/' -ProjectName CascadiaPackage -BundleVersion $BundleVersion -OutputPath $BundlePath
|
||||
Write-Host "##vso[task.setvariable variable=MsixBundlePath]${BundlePath}"
|
||||
displayName: Create msixbundle
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- task: EsrpCodeSigning@3
|
||||
displayName: Submit *.msixbundle to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(System.ArtifactsDirectory)\bundle
|
||||
Pattern: $(BundleStemName)*.msixbundle
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolSign",
|
||||
"Parameters": {
|
||||
"OpusName": "Microsoft",
|
||||
"OpusInfo": "http://www.microsoft.com",
|
||||
"FileDigest": "/fd \"SHA256\"",
|
||||
"TimeStamp": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
|
||||
},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "Dynamic",
|
||||
"CertTemplateName": "WINMSAPP1ST",
|
||||
"CertSubjectName": "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
|
||||
"OperationCode": "SigntoolVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
|
||||
- ${{ if eq(parameters.generateSbom, true) }}:
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
displayName: 'Generate SBOM manifest (bundle)'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/bundle'
|
||||
BuildComponentPath: '$(Build.SourcesDirectory)/bin'
|
||||
|
||||
- task: DropValidatorTask@0
|
||||
displayName: 'Validate bundle SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/bundle'
|
||||
OutputPath: 'output.json'
|
||||
ValidateSignature: true
|
||||
Verbosity: 'Verbose'
|
||||
|
||||
- ${{ parameters.afterBuildSteps }}
|
||||
|
||||
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
||||
- publish: $(JobOutputDirectory)
|
||||
artifact: $(JobOutputArtifactName)
|
||||
displayName: Publish msixbundle
|
||||
@@ -1,129 +0,0 @@
|
||||
parameters:
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
- name: generateSbom
|
||||
type: boolean
|
||||
default: false
|
||||
- name: codeSign
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: PackConPTY
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: publishArtifacts
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
${{ if eq(parameters.codeSign, true) }}:
|
||||
displayName: Pack and Sign Microsoft.Windows.Console.ConPTY
|
||||
${{ else }}:
|
||||
displayName: Pack Microsoft.Windows.Console.ConPTY
|
||||
strategy:
|
||||
matrix:
|
||||
${{ each config in parameters.buildConfigurations }}:
|
||||
${{ config }}:
|
||||
BuildConfiguration: ${{ config }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
variables:
|
||||
JobOutputDirectory: $(Build.ArtifactStagingDirectory)\nupkg
|
||||
JobOutputArtifactName: conpty-nupkg-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- template: steps-download-bin-dir-artifact.yml
|
||||
parameters:
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
# This build is already matrix'd on configuration, so
|
||||
# just pass a single config into the download template.
|
||||
buildConfigurations:
|
||||
- $(BuildConfiguration)
|
||||
artifactStem: ${{ parameters.artifactStem }}
|
||||
|
||||
- template: steps-ensure-nuget-version.yml
|
||||
|
||||
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
|
||||
# This should be `task: NuGetCommand@2`
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: NuGet pack
|
||||
inputs:
|
||||
command: pack
|
||||
packagesToPack: $(Build.SourcesDirectory)\src\winconpty\package\winconpty.nuspec
|
||||
packDestination: '$(Build.ArtifactStagingDirectory)/nupkg'
|
||||
versioningScheme: byEnvVar
|
||||
versionEnvVar: XES_PACKAGEVERSIONNUMBER
|
||||
|
||||
- ${{ if eq(parameters.codeSign, true) }}:
|
||||
- task: EsrpCodeSigning@3
|
||||
displayName: Submit *.nupkg to ESRP for code signing
|
||||
inputs:
|
||||
ConnectedServiceName: 9d6d2960-0793-4d59-943e-78dcb434840a
|
||||
FolderPath: $(Build.ArtifactStagingDirectory)/nupkg
|
||||
Pattern: '*.nupkg'
|
||||
UseMinimatch: true
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: >-
|
||||
[
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetSign",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
},
|
||||
{
|
||||
"KeyCode": "CP-401405",
|
||||
"OperationCode": "NuGetVerify",
|
||||
"Parameters": {},
|
||||
"ToolName": "sign",
|
||||
"ToolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
|
||||
- ${{ if eq(parameters.generateSbom, true) }}:
|
||||
- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
|
||||
displayName: 'Generate SBOM manifest (conpty)'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/nupkg'
|
||||
BuildComponentPath: '$(Build.SourcesDirectory)/bin'
|
||||
|
||||
- task: DropValidatorTask@0
|
||||
displayName: 'Validate conpty SBOM manifest'
|
||||
inputs:
|
||||
BuildDropPath: '$(System.ArtifactsDirectory)/nupkg'
|
||||
OutputPath: 'output.json'
|
||||
ValidateSignature: true
|
||||
Verbosity: 'Verbose'
|
||||
|
||||
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
||||
- publish: $(JobOutputDirectory)
|
||||
artifact: $(JobOutputArtifactName)
|
||||
displayName: Publish nupkg
|
||||
@@ -1,75 +0,0 @@
|
||||
parameters:
|
||||
- name: buildConfiguration
|
||||
type: string
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: MergePGD
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
displayName: Merge PGO Counts for ${{ parameters.buildConfiguration }}
|
||||
|
||||
steps:
|
||||
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
|
||||
- script: |
|
||||
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
|
||||
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
|
||||
del %TEMP%\vsinstalldir.txt
|
||||
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
|
||||
echo VCToolsInstallDir = %VCToolsInstallDir%
|
||||
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
|
||||
displayName: 'Retrieve VC tools directory'
|
||||
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download PGO Databases for ${{ platform }}
|
||||
inputs:
|
||||
artifactName: build-${{ platform }}-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
itemPattern: '**/*.pgd'
|
||||
downloadPath: '$(Build.SourcesDirectory)/pgd/${{ platform }}/${{ parameters.buildConfiguration }}'
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download PGO Counts for ${{ platform }}
|
||||
inputs:
|
||||
artifactName: pgc-intermediates-${{ platform }}-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
downloadPath: '$(Build.SourcesDirectory)/pgc/${{ platform }}/${{ parameters.buildConfiguration }}'
|
||||
- pwsh: |-
|
||||
$Arch = '${{ platform }}'
|
||||
$Conf = '${{ parameters.buildConfiguration }}'
|
||||
$PGCDir = '$(Build.SourcesDirectory)/pgc/${{ platform }}/${{ parameters.buildConfiguration }}'
|
||||
$PGDDir = '$(Build.SourcesDirectory)/pgd/${{ platform }}/${{ parameters.buildConfiguration }}'
|
||||
# Flatten the PGD directory
|
||||
Get-ChildItem $PGDDir -Recurse -Filter *.pgd | Move-Item -Destination $PGDDir -Verbose
|
||||
Get-ChildItem $PGCDir -Filter *.pgc |
|
||||
ForEach-Object {
|
||||
$Parts = $_.Name -Split "!";
|
||||
$_ | Add-Member Module $Parts[0] -PassThru
|
||||
} |
|
||||
Group-Object Module |
|
||||
ForEach-Object {
|
||||
& "$(VCToolsInstallDir)\bin\Hostx64\${{ platform }}\pgomgr.exe" /merge $_.Group.FullName "$PGDDir\$($_.Name).pgd"
|
||||
}
|
||||
displayName: Merge PGO Counts for ${{ platform }}
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy merged pgds to artifact staging'
|
||||
inputs:
|
||||
sourceFolder: '$(Build.SourcesDirectory)/pgd/${{ platform }}/${{ parameters.buildConfiguration }}'
|
||||
contents: '**\*.pgd'
|
||||
targetFolder: '$(Build.ArtifactStagingDirectory)\out-pgd\${{ platform }}'
|
||||
|
||||
- publish: $(Build.ArtifactStagingDirectory)\out-pgd
|
||||
artifact: pgd-merged-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
displayName: "Publish merged PGDs"
|
||||
@@ -1,97 +0,0 @@
|
||||
parameters:
|
||||
- name: includePublicSymbolServer
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: PublishSymbols
|
||||
- name: symbolExpiryTime
|
||||
type: string
|
||||
default: 36530 # This is the default from PublishSymbols@2
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: symbolPatGoesInTaskInputs
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
${{ if eq(parameters.includePublicSymbolServer, true) }}:
|
||||
displayName: Publish Symbols to Internal and MSDL
|
||||
${{ else }}:
|
||||
displayName: Publish Symbols Internally
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
variables:
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download all PDBs from all prior build phases
|
||||
inputs:
|
||||
itemPattern: '**/*.pdb'
|
||||
targetPath: '$(Build.SourcesDirectory)/bin'
|
||||
|
||||
- task: PublishSymbols@2
|
||||
displayName: Publish Symbols (to current Azure DevOps tenant)
|
||||
continueOnError: True
|
||||
inputs:
|
||||
SymbolsFolder: '$(Build.SourcesDirectory)/bin'
|
||||
SearchPattern: '**/*.pdb'
|
||||
IndexSources: false
|
||||
DetailedLog: true
|
||||
SymbolsMaximumWaitTime: 30
|
||||
SymbolServerType: 'TeamServices'
|
||||
SymbolsProduct: 'Windows Terminal Converged Symbols'
|
||||
SymbolsVersion: '$(XES_APPXMANIFESTVERSION)'
|
||||
SymbolExpirationInDays: ${{ parameters.symbolExpiryTime }}
|
||||
env:
|
||||
LIB: $(Build.SourcesDirectory)
|
||||
|
||||
- ${{ if eq(parameters.includePublicSymbolServer, true) }}:
|
||||
- task: PublishSymbols@2
|
||||
displayName: 'Publish symbols to MSDL'
|
||||
continueOnError: True
|
||||
inputs:
|
||||
SymbolsFolder: '$(Build.SourcesDirectory)/bin'
|
||||
SearchPattern: '**/*.pdb'
|
||||
IndexSources: false
|
||||
DetailedLog: true
|
||||
SymbolsMaximumWaitTime: 30
|
||||
SymbolServerType: 'TeamServices'
|
||||
SymbolsProduct: 'Windows Terminal Converged Symbols'
|
||||
SymbolsVersion: '$(XES_APPXMANIFESTVERSION)'
|
||||
SymbolExpirationInDays: ${{ parameters.symbolExpiryTime }}
|
||||
${{ if eq(parameters.symbolPatGoesInTaskInputs, true) }}:
|
||||
Pat: $(ADO_microsoftpublicsymbols_PAT)
|
||||
# The ADO task does not support indexing of GitHub sources.
|
||||
# There is a bug which causes this task to fail if LIB includes an inaccessible path (even though it does not depend on it).
|
||||
# To work around this issue, we just force LIB to be any dir that we know exists.
|
||||
# Copied from https://github.com/microsoft/icu/blob/f869c214adc87415dfe751d81f42f1bca55dcf5f/build/azure-nuget.yml#L564-L583
|
||||
env:
|
||||
LIB: $(Build.SourcesDirectory)
|
||||
ArtifactServices_Symbol_AccountName: microsoftpublicsymbols
|
||||
${{ if ne(parameters.symbolPatGoesInTaskInputs, true) }}:
|
||||
ArtifactServices_Symbol_PAT: $(ADO_microsoftpublicsymbols_PAT)
|
||||
@@ -1,82 +0,0 @@
|
||||
parameters:
|
||||
buildConfiguration: 'Release'
|
||||
buildPlatform: ''
|
||||
artifactStem: ''
|
||||
testLogPath: '$(Build.BinariesDirectory)\$(BuildPlatform)\$(BuildConfiguration)\testsOnBuildMachine.wtl'
|
||||
|
||||
jobs:
|
||||
- job: PGO${{ parameters.buildPlatform }}${{ parameters.buildConfiguration }}
|
||||
displayName: PGO ${{ parameters.buildPlatform }} ${{ parameters.buildConfiguration }}
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.buildConfiguration }}
|
||||
BuildPlatform: ${{ parameters.buildPlatform }}
|
||||
OutputBuildPlatform: ${{ parameters.buildPlatform }}
|
||||
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
${{ if ne(parameters.buildPlatform, 'ARM64') }}:
|
||||
name: SHINE-OSS-Testing-x64
|
||||
${{ else }}:
|
||||
name: SHINE-OSS-Testing-arm64
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
${{ if ne(parameters.buildPlatform, 'ARM64') }}:
|
||||
name: SHINE-INT-Testing-x64
|
||||
${{ else }}:
|
||||
name: SHINE-INT-Testing-arm64
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: false
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download artifacts
|
||||
inputs:
|
||||
artifactName: build-${{ parameters.buildPlatform }}-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
downloadPath: $(Terminal.BinDir)
|
||||
|
||||
# The tests expect Terminal to be an unpackaged distribution named terminal-0.0.1.0 (after the dev build version scheme)
|
||||
# Extract to that folder explicitly and strip the embedded folder name from the unpackaged archive.
|
||||
- powershell: |-
|
||||
$TargetDirectory = New-Item -Type Directory (Join-Path "$(Terminal.BinDir)" "terminal-0.0.1.0")
|
||||
& tar.exe -x -v -f (Get-Item "$(Terminal.BinDir)/_unpackaged/*.zip") -C $TargetDirectory.FullName --strip-components=1
|
||||
displayName: Extract the unpackaged build for PGO
|
||||
|
||||
- template: steps-ensure-nuget-version.yml
|
||||
|
||||
- powershell: |-
|
||||
$Package = 'Microsoft.Internal.Windows.Terminal.TestContent'
|
||||
$Version = '1.0.1'
|
||||
& nuget.exe install $Package -Version $Version
|
||||
Write-Host "##vso[task.setvariable variable=TerminalTestContentPath]$(Build.SourcesDirectory)\packages\${Package}.${Version}\content"
|
||||
displayName: Install Test Content
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Run PGO Tests'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: >-
|
||||
-MatchPattern '*UIA.Tests.dll'
|
||||
-Platform '$(OutputBuildPlatform)'
|
||||
-Configuration '$(BuildConfiguration)'
|
||||
-LogPath '${{ parameters.testLogPath }}'
|
||||
-Root "$(Terminal.BinDir)"
|
||||
-AdditionalTaefArguments '/select:(@IsPGO=true)','/p:WTTestContent=$(TerminalTestContentPath)'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy PGO outputs to Artifacts'
|
||||
condition: always()
|
||||
inputs:
|
||||
Contents: |
|
||||
**/*.pgc
|
||||
${{ parameters.testLogPath }}
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/pgc'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
|
||||
- publish: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/pgc'
|
||||
artifact: pgc-intermediates-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
|
||||
condition: always()
|
||||
@@ -1,81 +0,0 @@
|
||||
parameters:
|
||||
- name: buildConfiguration
|
||||
type: string
|
||||
- name: generateSbom
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: publishArtifacts
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
jobs:
|
||||
- job: VPack
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
displayName: Create and Submit Windows vPack
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
variables:
|
||||
JobOutputDirectory: $(XES_VPACKMANIFESTDIRECTORY)
|
||||
JobOutputArtifactName: vpack-manifest${{ parameters.artifactStem }}
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download MSIX Bundle Artifact
|
||||
inputs:
|
||||
artifactName: appxbundle-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
downloadPath: '$(Build.SourcesDirectory)/bundle'
|
||||
|
||||
# Rename to known/fixed name for Windows build system
|
||||
- powershell: |-
|
||||
# Create vpack directory and place item inside
|
||||
$TargetFolder = New-Item -Type Directory '$(Build.SourcesDirectory)/WindowsTerminal.app'
|
||||
Get-ChildItem bundle/Microsoft.WindowsTerminal_*.msixbundle | Move-Item (Join-Path $TargetFolder.FullName 'Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle') -Verbose
|
||||
displayName: Stage packages for vpack
|
||||
|
||||
- task: PkgESVPack@12
|
||||
displayName: 'Package ES - VPack'
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
inputs:
|
||||
sourceDirectory: '$(Build.SourcesDirectory)/WindowsTerminal.app'
|
||||
description: VPack for the Windows Terminal Application
|
||||
pushPkgName: WindowsTerminal.app
|
||||
owner: conhost
|
||||
githubToken: $(GitHubTokenForVpackProvenance)
|
||||
|
||||
- ${{ if eq(parameters.publishArtifacts, true) }}:
|
||||
- publish: $(JobOutputDirectory)
|
||||
artifact: $(JobOutputArtifactName)
|
||||
displayName: 'Publish VPack Manifest to Drop'
|
||||
|
||||
- task: PkgESFCIBGit@12
|
||||
displayName: 'Submit VPack Manifest to Windows'
|
||||
inputs:
|
||||
configPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
|
||||
artifactsDirectory: $(XES_VPACKMANIFESTDIRECTORY)
|
||||
prTimeOut: 5
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
platform: ''
|
||||
testLogPath: '$(Build.BinariesDirectory)\$(BuildPlatform)\$(BuildConfiguration)\testsOnBuildMachine.wtl'
|
||||
inputArtifactStem: ''
|
||||
outputArtifactStem: ''
|
||||
|
||||
jobs:
|
||||
- job: Test${{ parameters.platform }}${{ parameters.configuration }}
|
||||
displayName: Test ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
${{ if eq(parameters.platform, 'x86') }}:
|
||||
OutputBuildPlatform: Win32
|
||||
${{ else }}:
|
||||
OutputBuildPlatform: ${{ parameters.platform }}
|
||||
Terminal.BinDir: $(Build.SourcesDirectory)/bin/$(OutputBuildPlatform)/$(BuildConfiguration)
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
${{ if ne(parameters.platform, 'ARM64') }}:
|
||||
name: SHINE-OSS-Testing-x64
|
||||
${{ else }}:
|
||||
name: SHINE-OSS-Testing-arm64
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
${{ if ne(parameters.platform, 'ARM64') }}:
|
||||
name: SHINE-INT-Testing-x64
|
||||
${{ else }}:
|
||||
name: SHINE-INT-Testing-arm64
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: false
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download artifacts
|
||||
inputs:
|
||||
artifactName: build-${{ parameters.platform }}-$(BuildConfiguration)${{ parameters.inputArtifactStem }}
|
||||
downloadPath: $(Terminal.BinDir)
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Run Unit Tests'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(OutputBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(Terminal.BinDir)"
|
||||
|
||||
- ${{ if or(eq(parameters.platform, 'x64'), eq(parameters.platform, 'arm64')) }}:
|
||||
- task: PowerShell@2
|
||||
displayName: 'Run Feature Tests'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(OutputBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(Terminal.BinDir)"
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Convert Test Logs from WTL to xUnit format'
|
||||
condition: always()
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\ConvertWttLogToXUnit.ps1
|
||||
arguments: -WttInputPath '${{ parameters.testLogPath }}' -WttSingleRerunInputPath 'unused.wtl' -WttMultipleRerunInputPath 'unused2.wtl' -XUnitOutputPath 'onBuildMachineResults.xml' -TestNamePrefix '$(BuildConfiguration).$(BuildPlatform)'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Upload converted test logs'
|
||||
condition: always()
|
||||
inputs:
|
||||
testResultsFormat: 'xUnit' # Options: JUnit, NUnit, VSTest, xUnit, cTest
|
||||
testResultsFiles: '**/onBuildMachineResults.xml'
|
||||
testRunTitle: 'On Build Machine Tests' # Optional
|
||||
buildPlatform: $(BuildPlatform) # Optional
|
||||
buildConfiguration: $(BuildConfiguration) # Optional
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy result logs to Artifacts'
|
||||
condition: always()
|
||||
inputs:
|
||||
Contents: |
|
||||
**/*.wtl
|
||||
**/*onBuildMachineResults.xml
|
||||
${{ parameters.testLogPath }}
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test-logs'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
|
||||
- publish: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test-logs'
|
||||
artifact: test-logs-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.outputArtifactStem }}
|
||||
condition: always()
|
||||
@@ -1,173 +0,0 @@
|
||||
# This build should never run as CI or against a pull request.
|
||||
trigger: none
|
||||
|
||||
parameters:
|
||||
- name: branding
|
||||
type: string
|
||||
default: Release
|
||||
- name: buildTerminal
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildConPTY
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildWPF
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pgoBuildMode
|
||||
type: string
|
||||
default: Optimize
|
||||
values:
|
||||
- Optimize
|
||||
- Instrument
|
||||
- None
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
default:
|
||||
- Release
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
- name: codeSign
|
||||
type: boolean
|
||||
default: true
|
||||
- name: generateSbom
|
||||
type: boolean
|
||||
default: true
|
||||
- name: terminalInternalPackageVersion
|
||||
type: string
|
||||
default: '0.0.8'
|
||||
|
||||
- name: publishSymbolsToPublic
|
||||
type: boolean
|
||||
default: true
|
||||
- name: symbolExpiryTime
|
||||
type: string
|
||||
default: 36530 # This is the default from PublishSymbols@2
|
||||
- name: publishVpackToWindows
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
- name: pool
|
||||
type: object
|
||||
default:
|
||||
name: SHINE-INT-S # By default, send jobs to the small agent pool.
|
||||
demands: ImageOverride -equals SHINE-VS17-Latest
|
||||
|
||||
variables:
|
||||
- template: variables-nuget-package-version.yml
|
||||
parameters:
|
||||
branding: ${{ parameters.branding }}
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
- repository: self
|
||||
type: git
|
||||
ref: main
|
||||
|
||||
stages:
|
||||
- stage: Build
|
||||
displayName: Build
|
||||
pool: ${{ parameters.pool }}
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./job-build-project.yml
|
||||
parameters:
|
||||
pool:
|
||||
name: SHINE-INT-L # Run the compilation on the large agent pool, rather than the default small one.
|
||||
demands: ImageOverride -equals SHINE-VS17-Latest
|
||||
branding: ${{ parameters.branding }}
|
||||
buildTerminal: ${{ parameters.buildTerminal }}
|
||||
buildConPTY: ${{ parameters.buildConPTY }}
|
||||
buildWPF: ${{ parameters.buildWPF }}
|
||||
pgoBuildMode: ${{ parameters.pgoBuildMode }}
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
beforeBuildSteps: # Right before we build, lay down the universal package and localizations
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download terminal-internal Universal Package
|
||||
inputs:
|
||||
feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
|
||||
packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
|
||||
versionListDownload: ${{ parameters.terminalInternalPackageVersion }}
|
||||
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
# Add an Any CPU build flavor for the WPF control bits
|
||||
- template: ./job-build-project.yml
|
||||
parameters:
|
||||
# This job is allowed to run on the default small pool.
|
||||
jobName: BuildWPF
|
||||
branding: ${{ parameters.branding }}
|
||||
buildTerminal: false
|
||||
buildWPFDotNetComponents: true
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms:
|
||||
- Any CPU
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
beforeBuildSteps:
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
# WPF doesn't need the localizations or the universal package, but if it does... put them here.
|
||||
|
||||
- stage: Package
|
||||
displayName: Package
|
||||
pool: ${{ parameters.pool }}
|
||||
dependsOn: [Build]
|
||||
jobs:
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- template: ./job-merge-msix-into-bundle.yml
|
||||
parameters:
|
||||
jobName: Bundle
|
||||
branding: ${{ parameters.branding }}
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
|
||||
- ${{ if eq(parameters.buildConPTY, true) }}:
|
||||
- template: ./job-package-conpty.yml
|
||||
parameters:
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- template: ./job-build-package-wpf.yml
|
||||
parameters:
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
|
||||
- stage: Publish
|
||||
displayName: Publish
|
||||
pool: ${{ parameters.pool }}
|
||||
dependsOn: [Build, Package]
|
||||
jobs:
|
||||
# We only support the vpack for Release builds that include Terminal
|
||||
- ${{ if and(containsValue(parameters.buildConfigurations, 'Release'), parameters.buildTerminal, parameters.publishVpackToWindows) }}:
|
||||
- template: ./job-submit-windows-vpack.yml
|
||||
parameters:
|
||||
buildConfiguration: Release
|
||||
generateSbom: ${{ parameters.generateSbom }}
|
||||
|
||||
- template: ./job-publish-symbols.yml
|
||||
parameters:
|
||||
includePublicSymbolServer: ${{ parameters.publishSymbolsToPublic }}
|
||||
symbolExpiryTime: ${{ parameters.symbolExpiryTime }}
|
||||
|
||||
...
|
||||
@@ -1,252 +0,0 @@
|
||||
parameters:
|
||||
- name: official
|
||||
type: boolean
|
||||
default: false
|
||||
- name: branding
|
||||
type: string
|
||||
default: Release
|
||||
values:
|
||||
- Release
|
||||
- Preview
|
||||
- Canary
|
||||
- Dev
|
||||
- name: buildTerminal
|
||||
type: boolean
|
||||
default: true
|
||||
- name: buildConPTY
|
||||
type: boolean
|
||||
default: false
|
||||
- name: buildWPF
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pgoBuildMode
|
||||
type: string
|
||||
default: Optimize
|
||||
values:
|
||||
- Optimize
|
||||
- Instrument
|
||||
- None
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
default:
|
||||
- Release
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
default:
|
||||
- x64
|
||||
- x86
|
||||
- arm64
|
||||
- name: codeSign
|
||||
type: boolean
|
||||
default: true
|
||||
- name: terminalInternalPackageVersion
|
||||
type: string
|
||||
default: '0.0.8'
|
||||
|
||||
- name: publishSymbolsToPublic
|
||||
type: boolean
|
||||
default: true
|
||||
- name: publishVpackToWindows
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
- name: extraPublishJobs
|
||||
type: object
|
||||
default: []
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
- repository: templates
|
||||
type: git
|
||||
name: OneBranch.Pipelines/GovernedTemplates
|
||||
ref: refs/heads/main
|
||||
|
||||
extends:
|
||||
${{ if eq(parameters.official, true) }}:
|
||||
template: v2/Microsoft.Official.yml@templates # https://aka.ms/obpipelines/templates
|
||||
${{ else }}:
|
||||
template: v2/Microsoft.NonOfficial.yml@templates
|
||||
parameters:
|
||||
featureFlags:
|
||||
WindowsHostVersion: 1ESWindows2022
|
||||
platform:
|
||||
name: 'windows_undocked'
|
||||
product: 'Windows Terminal'
|
||||
cloudvault: # https://aka.ms/obpipelines/cloudvault
|
||||
enabled: false
|
||||
globalSdl: # https://aka.ms/obpipelines/sdl
|
||||
tsa:
|
||||
enabled: true
|
||||
configFile: '$(Build.SourcesDirectory)\build\config\tsa.json'
|
||||
binskim:
|
||||
break: false
|
||||
scanOutputDirectoryOnly: true
|
||||
policheck:
|
||||
break: false
|
||||
severity: Note
|
||||
baseline:
|
||||
baselineFile: '$(Build.SourcesDirectory)\build\config\release.gdnbaselines'
|
||||
suppressionSet: default
|
||||
|
||||
stages:
|
||||
- stage: Build
|
||||
displayName: Build
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: ./build/pipelines/templates-v2/job-build-project.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: $(JobOutputDirectory)
|
||||
ob_artifactBaseName: $(JobOutputArtifactName)
|
||||
publishArtifacts: false # Handled by OneBranch
|
||||
branding: ${{ parameters.branding }}
|
||||
buildTerminal: ${{ parameters.buildTerminal }}
|
||||
buildConPTY: ${{ parameters.buildConPTY }}
|
||||
buildWPF: ${{ parameters.buildWPF }}
|
||||
pgoBuildMode: ${{ parameters.pgoBuildMode }}
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: false # this is handled by onebranch
|
||||
removeAllNonSignedFiles: true # appease the overlords
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
beforeBuildSteps: # Right before we build, lay down the universal package and localizations
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download terminal-internal Universal Package
|
||||
inputs:
|
||||
feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
|
||||
packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
|
||||
versionListDownload: ${{ parameters.terminalInternalPackageVersion }}
|
||||
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
# Add an Any CPU build flavor for the WPF control bits
|
||||
- template: ./build/pipelines/templates-v2/job-build-project.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: $(JobOutputDirectory)
|
||||
ob_artifactBaseName: $(JobOutputArtifactName)
|
||||
publishArtifacts: false # Handled by OneBranch
|
||||
jobName: BuildWPF
|
||||
branding: ${{ parameters.branding }}
|
||||
buildTerminal: false
|
||||
buildWPFDotNetComponents: true
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms:
|
||||
- Any CPU
|
||||
generateSbom: false # this is handled by onebranch
|
||||
removeAllNonSignedFiles: true # appease the overlords
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
beforeBuildSteps:
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
# WPF doesn't need the localizations or the universal package, but if it does... put them here.
|
||||
|
||||
- stage: Package
|
||||
displayName: Package
|
||||
dependsOn: [Build]
|
||||
jobs:
|
||||
- ${{ if eq(parameters.buildTerminal, true) }}:
|
||||
- template: ./build/pipelines/templates-v2/job-merge-msix-into-bundle.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: $(JobOutputDirectory)
|
||||
ob_artifactBaseName: $(JobOutputArtifactName)
|
||||
### This job is also in charge of submitting the vpack to Windows if it's enabled
|
||||
ob_createvpack_enabled: ${{ and(parameters.buildTerminal, parameters.publishVpackToWindows) }}
|
||||
ob_updateOSManifest_enabled: ${{ and(parameters.buildTerminal, parameters.publishVpackToWindows) }}
|
||||
### If enabled above, these options are in play.
|
||||
ob_createvpack_packagename: 'WindowsTerminal.app'
|
||||
ob_createvpack_owneralias: 'conhost@microsoft.com'
|
||||
ob_createvpack_description: 'VPack for the Windows Terminal Application'
|
||||
ob_createvpack_targetDestinationDirectory: '$(Destination)'
|
||||
ob_createvpack_propsFile: false
|
||||
ob_createvpack_provData: true
|
||||
ob_createvpack_metadata: '$(Build.SourceVersion)'
|
||||
ob_createvpack_topLevelRetries: 0
|
||||
ob_createvpack_failOnStdErr: true
|
||||
ob_createvpack_taskLogVerbosity: Detailed
|
||||
ob_createvpack_verbose: true
|
||||
ob_createvpack_vpackdirectory: '$(JobOutputDirectory)\vpack'
|
||||
ob_updateOSManifest_gitcheckinConfigPath: '$(Build.SourcesDirectory)\build\config\GitCheckin.json'
|
||||
# We're skipping the 'fetch' part of the OneBranch rules, but that doesn't mean
|
||||
# that it doesn't expect to have downloaded a manifest directly to some 'destination'
|
||||
# folder that it can then update and upload.
|
||||
# Effectively: it says "destination" but it means "source"
|
||||
# DH: Don't ask why.
|
||||
ob_updateOSManifest_destination: $(XES_VPACKMANIFESTDIRECTORY)
|
||||
ob_updateOSManifest_skipFetch: true
|
||||
publishArtifacts: false # Handled by OneBranch
|
||||
jobName: Bundle
|
||||
branding: ${{ parameters.branding }}
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: false # Handled by onebranch
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
afterBuildSteps:
|
||||
- pwsh: |-
|
||||
$d = New-Item "$(JobOutputDirectory)/vpack" -Type Directory
|
||||
Copy-Item -Verbose -Path "$(MsixBundlePath)" -Destination (Join-Path $d 'Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle')
|
||||
displayName: Stage msixbundle for vpack
|
||||
|
||||
- ${{ if eq(parameters.buildConPTY, true) }}:
|
||||
- template: ./build/pipelines/templates-v2/job-package-conpty.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: $(JobOutputDirectory)
|
||||
ob_artifactBaseName: $(JobOutputArtifactName)
|
||||
publishArtifacts: false # Handled by OneBranch
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: false # this is handled by onebranch
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
|
||||
- ${{ if eq(parameters.buildWPF, true) }}:
|
||||
- template: ./build/pipelines/templates-v2/job-build-package-wpf.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: $(JobOutputDirectory)
|
||||
ob_artifactBaseName: $(JobOutputArtifactName)
|
||||
publishArtifacts: false # Handled by OneBranch
|
||||
buildConfigurations: ${{ parameters.buildConfigurations }}
|
||||
buildPlatforms: ${{ parameters.buildPlatforms }}
|
||||
generateSbom: false # this is handled by onebranch
|
||||
codeSign: ${{ parameters.codeSign }}
|
||||
|
||||
- stage: Publish
|
||||
displayName: Publish
|
||||
dependsOn: [Build, Package]
|
||||
jobs:
|
||||
- template: ./build/pipelines/templates-v2/job-publish-symbols.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
includePublicSymbolServer: ${{ parameters.publishSymbolsToPublic }}
|
||||
symbolPatGoesInTaskInputs: true # onebranch tries to muck with the PAT variable, so we need to change how it get the PAT
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
ob_outputDirectory: $(Build.ArtifactStagingDirectory)
|
||||
# Without this, OneBranch will nerf our symbol tasks
|
||||
ob_symbolsPublishing_enabled: true
|
||||
|
||||
- ${{ parameters.extraPublishJobs }}
|
||||
@@ -1,35 +0,0 @@
|
||||
parameters:
|
||||
- name: stage
|
||||
type: string
|
||||
- name: outFile
|
||||
type: string
|
||||
- name: fragments
|
||||
type: string
|
||||
|
||||
# This build step template takes all files named "esrp.STAGE.batch.*.json"
|
||||
# and merges them into a single output signing config.
|
||||
#
|
||||
# We generate the batch signing config by sticking together multiple "batches".
|
||||
# The filter below (with Fragments) works by splitting the filename, esrp.s.batch.x.json,
|
||||
# to get 'x' and then checking whether x is in Fragments.
|
||||
# We have to manually strip comments out of the batch fragments due to https://github.com/PowerShell/PowerShell/issues/14553
|
||||
|
||||
steps:
|
||||
- pwsh: |-
|
||||
$SignBatchFiles = (Get-Item build/config/esrp.${{ parameters.stage }}.batch.*.json)
|
||||
$Fragments = "${{ parameters.fragments }}"
|
||||
If (-Not [String]::IsNullOrWhiteSpace($Fragments)) {
|
||||
$FragmentList = $Fragments -Split ";"
|
||||
If ($FragmentList.Length -Gt 0) {
|
||||
$SignBatchFiles = $SignBatchFiles | Where-Object { ($_.Name -Split '\.')[3] -In $FragmentList }
|
||||
}
|
||||
}
|
||||
Write-Host "Found $(@($SignBatchFiles).Length) Signing Configs"
|
||||
Write-Host ($SignBatchFiles.Name -Join ";")
|
||||
$FinalSignConfig = @{
|
||||
Version = "1.0.0";
|
||||
UseMinimatch = $false;
|
||||
SignBatches = @($SignBatchFiles | ForEach-Object { Get-Content $_ | Where-Object { $_ -NotMatch "^\s*\/\/" } | ConvertFrom-Json -Depth 10 });
|
||||
}
|
||||
$FinalSignConfig | ConvertTo-Json -Depth 10 | Out-File -Encoding utf8 "${{ parameters.outFile }}"
|
||||
displayName: Merge ${{ parameters.stage }} signing configs (${{ parameters.outFile }})
|
||||
@@ -1,24 +0,0 @@
|
||||
parameters:
|
||||
- name: buildConfigurations
|
||||
type: object
|
||||
- name: buildPlatforms
|
||||
type: object
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
steps:
|
||||
- ${{ each configuration in parameters.buildConfigurations }}:
|
||||
- ${{ each platform in parameters.buildPlatforms }}:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download artifacts for ${{ platform }} ${{ configuration }}
|
||||
inputs:
|
||||
# Make sure to download the entire artifact, because it includes the SPDX SBOM
|
||||
artifactName: build-${{ platform }}-${{ configuration }}${{ parameters.artifactStem }}
|
||||
# Downloading to the source directory should ensure that the later SBOM generator can see the earlier SBOMs.
|
||||
${{ if eq(platform, 'x86') }}:
|
||||
downloadPath: '$(Build.SourcesDirectory)/bin/Win32/${{ configuration }}'
|
||||
${{ elseif eq(platform, 'Any CPU') }}:
|
||||
downloadPath: '$(Build.SourcesDirectory)/bin/AnyCPU/${{ configuration }}'
|
||||
${{ else }}:
|
||||
downloadPath: '$(Build.SourcesDirectory)/bin/${{ platform }}/${{ configuration }}'
|
||||
@@ -1,5 +0,0 @@
|
||||
steps:
|
||||
- task: NuGetToolInstaller@1
|
||||
displayName: Use NuGet 6.6.1
|
||||
inputs:
|
||||
versionSpec: 6.6.1
|
||||
@@ -1,27 +0,0 @@
|
||||
parameters:
|
||||
- name: branding
|
||||
type: string
|
||||
|
||||
variables:
|
||||
# If we are building a branch called "release-*", change the NuGet suffix
|
||||
# to "preview". If we don't do that, XES will set the suffix to "release1"
|
||||
# because it truncates the value after the first period.
|
||||
# We also want to disable the suffix entirely if we're Release branded while
|
||||
# on a release branch.
|
||||
# main is special, however. XES ignores main. Since we never produce actual
|
||||
# shipping builds from main, we want to force it to have a beta label as
|
||||
# well.
|
||||
#
|
||||
# In effect:
|
||||
# BRANCH / BRANDING | Release | Preview
|
||||
# ------------------|----------------------------|-----------------------------
|
||||
# release-* | 1.12.20220427 | 1.13.20220427-preview
|
||||
# main | 1.14.20220427-experimental | 1.14.20220427-experimental
|
||||
# all others | 1.14.20220427-mybranch | 1.14.20220427-mybranch
|
||||
${{ if startsWith(variables['Build.SourceBranchName'], 'release-') }}:
|
||||
${{ if eq(parameters.branding, 'Release') }}:
|
||||
NoNuGetPackBetaVersion: true
|
||||
${{ else }}:
|
||||
NuGetPackBetaVersion: preview
|
||||
${{ elseif eq(variables['Build.SourceBranchName'], 'main') }}:
|
||||
NuGetPackBetaVersion: experimental
|
||||
@@ -1,2 +0,0 @@
|
||||
variables:
|
||||
WindowsContainerImage: 'onebranch.azurecr.io/windows/ltsc2022/vse2022:latest'
|
||||
34
build/pipelines/templates/build-console-audit-job.yml
Normal file
34
build/pipelines/templates/build-console-audit-job.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
parameters:
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}AuditMode
|
||||
displayName: Static Analysis Build ${{ parameters.platform }}
|
||||
variables:
|
||||
BuildConfiguration: AuditMode
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS17-latest
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: true
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
|
||||
- template: restore-nuget-steps.yml
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: 'Build solution **\OpenConsole.sln'
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: ${{ parameters.additionalBuildArguments }}
|
||||
clean: true
|
||||
maximumCpuCount: true
|
||||
31
build/pipelines/templates/build-console-ci.yml
Normal file
31
build/pipelines/templates/build-console-ci.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
branding: 'Dev'
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}${{ parameters.configuration }}${{ parameters.branding }}
|
||||
displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }} ${{ parameters.branding }}
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
WindowsTerminalBranding: ${{ parameters.branding }}
|
||||
EnableRichCodeNavigation: true
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS17-latest
|
||||
|
||||
steps:
|
||||
- template: build-console-steps.yml
|
||||
parameters:
|
||||
additionalBuildArguments: ${{ parameters.additionalBuildArguments }}
|
||||
|
||||
# It appears that the Component Governance build task that gets automatically injected stopped working
|
||||
# when we renamed our main branch.
|
||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||
displayName: 'Component Detection'
|
||||
condition: and(succeededOrFailed(), not(eq(variables['Build.Reason'], 'PullRequest')))
|
||||
203
build/pipelines/templates/build-console-compliance-job.yml
Normal file
203
build/pipelines/templates/build-console-compliance-job.yml
Normal file
@@ -0,0 +1,203 @@
|
||||
jobs:
|
||||
- job: Compliance
|
||||
# We don't *need* a matrix but there's no other way to set parameters on a "job"
|
||||
# in the AzDO YAML syntax. It would have to be a "stage" or a "template".
|
||||
# Doesn't matter. We're going to do compliance on Release x64 because
|
||||
# that's the one all the tooling works against for sure.
|
||||
strategy:
|
||||
matrix:
|
||||
Release_x64:
|
||||
BuildConfiguration: Release
|
||||
BuildPlatform: x64
|
||||
displayName: Validate Security and Compliance
|
||||
timeoutInMinutes: 240
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
- task: PowerShell@2
|
||||
displayName: Rationalize Build Platform
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Arch = "$(BuildPlatform)"
|
||||
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
- template: restore-nuget-steps.yml
|
||||
- task: UniversalPackages@0
|
||||
displayName: Download terminal-internal Universal Package
|
||||
inputs:
|
||||
feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
|
||||
packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
|
||||
versionListDownload: $(TerminalInternalPackageVersion)
|
||||
- task: TouchdownBuildTask@1
|
||||
displayName: Download Localization Files
|
||||
inputs:
|
||||
teamId: 7105
|
||||
authId: $(TouchdownAppId)
|
||||
authKey: $(TouchdownAppKey)
|
||||
resourceFilePath: >-
|
||||
src\cascadia\TerminalApp\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalControl\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalConnection\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalSettingsModel\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\TerminalSettingsEditor\Resources\en-US\Resources.resw
|
||||
|
||||
src\cascadia\CascadiaPackage\Resources\en-US\Resources.resw
|
||||
appendRelativeDir: true
|
||||
localizationTarget: false
|
||||
pseudoSetting: Included
|
||||
- task: PowerShell@2
|
||||
displayName: Move Loc files one level up
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: >-
|
||||
$Files = Get-ChildItem . -R -Filter 'Resources.resw' | ? FullName -Like '*en-US\*\Resources.resw'
|
||||
|
||||
$Files | % { Move-Item -Verbose $_.Directory $_.Directory.Parent.Parent -EA:Ignore }
|
||||
pwsh: true
|
||||
|
||||
# 1ES Component Governance onboarding (Detects open source components). See https://docs.opensource.microsoft.com/tools/cg.html
|
||||
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
|
||||
displayName: Component Detection
|
||||
|
||||
# # PREfast and PoliCheck need Node. Install that first.
|
||||
- task: NodeTool@0
|
||||
|
||||
# !!! NOTE !!! Run PREfast first. Some of the other tasks are going to run on a completed build.
|
||||
# PREfast is going to build the code as a part of its analysis and the generated sources
|
||||
# and output binaries will be sufficient for the rest of the analysis.
|
||||
# If you disable this, the other tasks won't likely work. You would have to add a build
|
||||
# step instead that builds the code normally before calling them.
|
||||
# Also... PREfast will rebuild anyway so that's why we're not running a normal build first.
|
||||
# Waste of time to build twice.
|
||||
# PREfast. See https://www.1eswiki.com/wiki/SDL_Native_Rules_Build_Task
|
||||
|
||||
# The following 1ES tasks all operate completely differently and have a different syntax for usage.
|
||||
# Most notable is every one of them has a different way of excluding things.
|
||||
# Go see their 1eswiki.com pages to figure out how to exclude things.
|
||||
# When writing exclusions, try to make them narrow so when new projects/binaries are added, they
|
||||
# cause an error here and have to be explicitly pulled out. Don't write an exclusion so broad
|
||||
# that it will catch other new stuff.
|
||||
|
||||
# https://www.1eswiki.com/wiki/PREfast_Build_Task
|
||||
# Builds the project with C/C++ static analysis tools to find coding flaws and vulnerabilities
|
||||
# !!! WARNING !!! It doesn't work with WAPPROJ packaging projects. Build the sub-projects instead.
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-prefast.SDLNativeRules@3
|
||||
displayName: 'Run the PREfast SDL Native Rules for MSBuild'
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
setupCommandlines: '"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsMSBuildCmd.bat"'
|
||||
msBuildCommandline: msbuild.exe /nologo /m /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }} /p:WindowsTerminalReleaseBuild=true /p:platform=$(BuildPlatform) /p:configuration=$(BuildConfiguration) /t:Terminal\Window\WindowsTerminal /p:VisualStudioVersion=17.0 $(Build.SourcesDirectory)\OpenConsole.sln
|
||||
msBuildVersion: "17.0"
|
||||
|
||||
# Copies output from PREfast SDL Native Rules task to expected location for consumption by PkgESSecComp
|
||||
- task: CopyFiles@1
|
||||
displayName: 'Copy PREfast xml files to SDLNativeRulesDir'
|
||||
inputs:
|
||||
SourceFolder: '$(Agent.BuildDirectory)'
|
||||
Contents: |
|
||||
**\*.nativecodeanalysis.xml
|
||||
TargetFolder: '$(Agent.BuildDirectory)\_sdt\logs\SDLNativeRules'
|
||||
|
||||
# https://www.1eswiki.com/index.php?title=PoliCheck_Build_Task
|
||||
# Scans the text of source code, comments, and content for terminology that could be sensitive for legal, cultural, or geopolitical reasons.
|
||||
# (Also finds vulgarities... takes all the fun out of everything.)
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@2
|
||||
displayName: 'Run PoliCheck'
|
||||
inputs:
|
||||
targetType: F
|
||||
targetArgument: $(Build.SourcesDirectory)
|
||||
result: PoliCheck.xml
|
||||
optionsFC: 1
|
||||
optionsXS: 1
|
||||
optionsUEPath: $(Build.SourcesDirectory)\build\config\PolicheckExclusions.xml
|
||||
optionsHMENABLE: 0
|
||||
continueOnError: true
|
||||
|
||||
# https://www.1eswiki.com/wiki/CredScan_Azure_DevOps_Build_Task
|
||||
# Searches through source code and build outputs for a credential left behind in the open
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@3
|
||||
displayName: 'Run CredScan'
|
||||
inputs:
|
||||
outputFormat: pre
|
||||
# suppressionsFile: LocalSuppressions.json
|
||||
batchSize: 20
|
||||
debugMode: false
|
||||
continueOnError: true
|
||||
|
||||
# https://www.1eswiki.com/wiki/BinSkim_Build_Task
|
||||
# Searches managed and unmanaged binaries for known security vulnerabilities.
|
||||
- task: securedevelopmentteam.vss-secure-development-tools.build-task-binskim.BinSkim@4
|
||||
displayName: 'Run BinSkim'
|
||||
inputs:
|
||||
TargetPattern: guardianGlob
|
||||
# See https://aka.ms/gdn-globs for how to do match patterns
|
||||
AnalyzeTargetGlob: $(Build.SourcesDirectory)\bin\**\*.dll;$(Build.SourcesDirectory)\bin\**\*.exe;-:file|**\Microsoft.UI.Xaml.dll;-:file|**\Microsoft.Toolkit.Win32.UI.XamlHost.dll;-:file|**\vcruntime*.dll;-:file|**\vcomp*.dll;-:file|**\vccorlib*.dll;-:file|**\vcamp*.dll;-:file|**\msvcp*.dll;-:file|**\concrt*.dll;-:file|**\TerminalThemeHelpers*.dll
|
||||
continueOnError: true
|
||||
|
||||
# Set XES_SERIALPOSTBUILDREADY to run Security and Compliance task once per build
|
||||
- powershell: Write-Host "##vso[task.setvariable variable=XES_SERIALPOSTBUILDREADY;]true"
|
||||
displayName: 'Set XES_SERIALPOSTBUILDREADY Vars'
|
||||
|
||||
# https://www.osgwiki.com/wiki/Package_ES_Security_and_Compliance
|
||||
# Does a few things:
|
||||
# - Ensures that Windows-required compliance tasks are run either inside this task
|
||||
# or were run as a previous step prior to this one
|
||||
# (PREfast, PoliCheck, Credscan)
|
||||
# - Runs Windows-specific compliance tasks inside the task
|
||||
# + CheckCFlags - ensures that compiler and linker flags meet Windows standards
|
||||
# + CFGCheck/XFGCheck - ensures that Control Flow Guard (CFG) or
|
||||
# eXtended Flow Guard (XFG) are enabled on binaries
|
||||
# NOTE: CFG is deprecated and XFG isn't fully ready yet.
|
||||
# NOTE2: CFG fails on an XFG'd binary
|
||||
# - Brokers all security/compliance task logs to "Trust Services Automation (TSA)" (https://aka.ms/tsa)
|
||||
# which is a system that maps all errors into the appropriate bug database
|
||||
# template for each organization since they all vary. It should also suppress
|
||||
# new bugs when one already exists for the product.
|
||||
# This one is set up to go to the OS repository and use the given parameters
|
||||
# to file bugs to our AzDO product path.
|
||||
# If we don't use PkgESSecComp to do this for us, we need to install the TSA task
|
||||
# ourselves in this pipeline to finalize data upload and bug creation.
|
||||
# !!! NOTE !!! This task goes *LAST* after any other compliance tasks so it catches their logs
|
||||
- task: PkgESSecComp@10
|
||||
displayName: 'Security and Compliance tasks'
|
||||
inputs:
|
||||
fileNewBugs: false
|
||||
areaPath: 'OS\WDX\DXP\WinDev\Terminal'
|
||||
teamProject: 'OS'
|
||||
iterationPath: 'OS\Future'
|
||||
bugTags: 'TerminalReleaseCompliance'
|
||||
scanAll: true
|
||||
errOnBugs: false
|
||||
failOnStdErr: true
|
||||
taskLogVerbosity: Diagnostic
|
||||
secCompConfigFromTask: |
|
||||
# Overrides default build sources directory
|
||||
sourceTargetOverrideAll: $(Build.SourcesDirectory)
|
||||
# Overrides default build binaries directory when "Scan all" option is specified
|
||||
binariesTargetOverrideAll: $(Build.SourcesDirectory)\bin
|
||||
|
||||
# Set the tools to false if they should not run in the build
|
||||
tools:
|
||||
- toolName: CheckCFlags
|
||||
enable: true
|
||||
- toolName: CFGCheck
|
||||
enable: true
|
||||
- toolName: Policheck
|
||||
enable: false
|
||||
- toolName: CredScan
|
||||
enable: false
|
||||
- toolName: XFGCheck
|
||||
enable: false
|
||||
90
build/pipelines/templates/build-console-fuzzing.yml
Normal file
90
build/pipelines/templates/build-console-fuzzing.yml
Normal file
@@ -0,0 +1,90 @@
|
||||
parameters:
|
||||
configuration: 'Fuzzing'
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}${{ parameters.configuration }}
|
||||
displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS17-latest
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: true
|
||||
clean: true
|
||||
|
||||
- template: restore-nuget-steps.yml
|
||||
|
||||
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
|
||||
- script: |
|
||||
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
|
||||
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
|
||||
del %TEMP%\vsinstalldir.txt
|
||||
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
|
||||
echo VCToolsInstallDir = %VCToolsInstallDir%
|
||||
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
|
||||
displayName: 'Retrieve VC tools directory'
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: 'Build solution **\OpenConsole.sln'
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: "${{ parameters.additionalBuildArguments }}"
|
||||
clean: true
|
||||
maximumCpuCount: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Rationalize build platform'
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
$Arch = "$(BuildPlatform)"
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy result logs to Artifacts'
|
||||
inputs:
|
||||
Contents: |
|
||||
**/*.wtl
|
||||
**/*onBuildMachineResults.xml
|
||||
${{ parameters.testLogPath }}
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy outputs needed for test runs to Artifacts'
|
||||
inputs:
|
||||
Contents: |
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.exe
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.dll
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.xml
|
||||
**/Microsoft.VCLibs.*.appx
|
||||
**/TestHostApp/*.exe
|
||||
**/TestHostApp/*.dll
|
||||
**/TestHostApp/*.xml
|
||||
!**/*.pdb
|
||||
!**/*.ipdb
|
||||
!**/*.obj
|
||||
!**/*.pch
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
condition: succeeded()
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish All Build Artifacts'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
ArtifactName: 'fuzzingBuildOutput'
|
||||
55
build/pipelines/templates/build-console-pgo.yml
Normal file
55
build/pipelines/templates/build-console-pgo.yml
Normal file
@@ -0,0 +1,55 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
minimumExpectedTestsExecutedCount: 1 # Sanity check for minimum expected tests to be reported
|
||||
rerunPassesRequiredToAvoidFailure: 5
|
||||
|
||||
jobs:
|
||||
- job: Build${{ parameters.platform }}${{ parameters.configuration }}
|
||||
displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
PGOBuildMode: 'Instrument'
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS17-latest
|
||||
|
||||
steps:
|
||||
- template: build-console-steps.yml
|
||||
parameters:
|
||||
additionalBuildArguments: '${{ parameters.additionalBuildArguments }}'
|
||||
|
||||
- template: helix-runtests-job.yml
|
||||
parameters:
|
||||
name: 'RunTestsInHelix'
|
||||
dependsOn: Build${{ parameters.platform }}${{ parameters.configuration }}
|
||||
condition: succeeded()
|
||||
testSuite: 'PgoInstrumentationSuite'
|
||||
taefQuery: '@IsPgo=true'
|
||||
configuration: ${{ parameters.configuration }}
|
||||
platform: ${{ parameters.platform }}
|
||||
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
|
||||
|
||||
- template: helix-processtestresults-job.yml
|
||||
parameters:
|
||||
name: 'ProcessTestResults'
|
||||
pgoArtifact: 'PGO'
|
||||
dependsOn:
|
||||
- RunTestsInHelix
|
||||
condition: succeededOrFailed()
|
||||
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
|
||||
minimumExpectedTestsExecutedCount: ${{ parameters.minimumExpectedTestsExecutedCount }}
|
||||
|
||||
- template: pgo-merge-pgd-job.yml
|
||||
parameters:
|
||||
name: 'MergePGD'
|
||||
dependsOn:
|
||||
- ProcessTestResults
|
||||
pgoArtifact: 'PGO'
|
||||
platform: ${{ parameters.platform }}
|
||||
configuration: ${{ parameters.configuration }}
|
||||
137
build/pipelines/templates/build-console-steps.yml
Normal file
137
build/pipelines/templates/build-console-steps.yml
Normal file
@@ -0,0 +1,137 @@
|
||||
parameters:
|
||||
additionalBuildArguments: ''
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: true
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
|
||||
- template: restore-nuget-steps.yml
|
||||
|
||||
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
|
||||
- script: |
|
||||
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
|
||||
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
|
||||
del %TEMP%\vsinstalldir.txt
|
||||
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
|
||||
echo VCToolsInstallDir = %VCToolsInstallDir%
|
||||
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
|
||||
displayName: 'Retrieve VC tools directory'
|
||||
|
||||
- task: CmdLine@1
|
||||
displayName: 'Display build machine environment variables'
|
||||
inputs:
|
||||
filename: 'set'
|
||||
|
||||
- task: VSBuild@1
|
||||
displayName: 'Build solution **\OpenConsole.sln'
|
||||
inputs:
|
||||
solution: '**\OpenConsole.sln'
|
||||
platform: '$(BuildPlatform)'
|
||||
configuration: '$(BuildConfiguration)'
|
||||
msbuildArgs: "${{ parameters.additionalBuildArguments }} /p:PGOBuildMode=$(PGOBuildMode) /bl:$(Build.SourcesDirectory)\\msbuild.binlog"
|
||||
clean: true
|
||||
maximumCpuCount: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Check MSIX for common regressions'
|
||||
# PGO runtime needs its own CRT and it's in the package for convenience.
|
||||
# That will make this script mad so skip since we're not shipping the PGO Instrumentation one anyway.
|
||||
condition: ne(variables['PGOBuildMode'], 'Instrument')
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
$Package = Get-ChildItem -Recurse -Filter "CascadiaPackage_*.msix"
|
||||
.\build\scripts\Test-WindowsTerminalPackage.ps1 -Verbose -Path $Package.FullName
|
||||
|
||||
- task: powershell@2
|
||||
displayName: 'Source Index PDBs'
|
||||
condition: ne(variables['PGOBuildMode'], 'Instrument')
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Index-Pdbs.ps1
|
||||
arguments: -SearchDir '$(Build.SourcesDirectory)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
|
||||
errorActionPreference: silentlyContinue
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Rationalize build platform'
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
$Arch = "$(BuildPlatform)"
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy *.msix to Artifacts'
|
||||
inputs:
|
||||
Contents: |
|
||||
**/*.msix
|
||||
**/*.appxsym
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/appx'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
|
||||
- pwsh: |-
|
||||
$TerminalMsixPath = (Get-Item "$(Build.ArtifactStagingDirectory)\appx\Cascadia*.msix").FullName
|
||||
$XamlAppxPath = (Get-Item "src\cascadia\CascadiaPackage\AppPackages\*\Dependencies\$(BuildPlatform)\Microsoft.UI.Xaml*.appx").FullName
|
||||
& .\build\scripts\New-UnpackagedTerminalDistribution.ps1 -TerminalAppX $TerminalMsixPath -XamlAppX $XamlAppxPath -Destination "$(Build.ArtifactStagingDirectory)/unpackaged"
|
||||
displayName: Build Unpackaged Distribution
|
||||
|
||||
- publish: $(Build.ArtifactStagingDirectory)/unpackaged
|
||||
artifact: unpackaged-$(BuildPlatform)-$(BuildConfiguration)
|
||||
displayName: Publish Artifact (unpackaged)
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy outputs needed for test runs to Artifacts'
|
||||
inputs:
|
||||
Contents: |
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.exe
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.dll
|
||||
$(Build.SourcesDirectory)/bin/$(RationalizedBuildPlatform)/$(BuildConfiguration)/*.xml
|
||||
**/Microsoft.VCLibs.*.appx
|
||||
**/*unit.test*.dll
|
||||
**/*unit.test*.manifest
|
||||
**/TestHostApp/*.exe
|
||||
**/TestHostApp/*.dll
|
||||
**/TestHostApp/*.xml
|
||||
!**/*.pdb
|
||||
!**/*.ipdb
|
||||
!**/*.obj
|
||||
!**/*.pch
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
condition: succeeded()
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish All Build Artifacts'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
ArtifactName: 'drop'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy PGO databases needed for PGO instrumentation run'
|
||||
inputs:
|
||||
Contents: |
|
||||
**/*.pgd
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/PGO/$(BuildPlatform)'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
condition: and(succeeded(), eq(variables['PGOBuildMode'], 'Instrument'))
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish All PGO Artifacts'
|
||||
inputs:
|
||||
PathtoPublish: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/PGO'
|
||||
ArtifactName: 'PGO'
|
||||
condition: and(succeeded(), eq(variables['PGOBuildMode'], 'Instrument'))
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Artifact: binlog'
|
||||
condition: always()
|
||||
continueOnError: True
|
||||
inputs:
|
||||
PathtoPublish: $(Build.SourcesDirectory)\msbuild.binlog
|
||||
ArtifactName: binlog-$(BuildPlatform)
|
||||
17
build/pipelines/templates/check-formatting.yml
Normal file
17
build/pipelines/templates/check-formatting.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
jobs:
|
||||
- job: CodeFormatCheck
|
||||
displayName: Proper Code Formatting Check
|
||||
pool: { vmImage: windows-2022 }
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
submodules: false
|
||||
clean: true
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Code Formatting Check'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: '.\build\scripts\Invoke-FormattingCheck.ps1'
|
||||
@@ -1,15 +1,21 @@
|
||||
parameters:
|
||||
artifactName: 'drop'
|
||||
|
||||
jobs:
|
||||
- job: CodeNavIndexer
|
||||
displayName: Run Github CodeNav Indexer
|
||||
pool: { vmImage: windows-2022 }
|
||||
pool: { vmImage: windows-2019 }
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: false
|
||||
clean: true
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
inputs:
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
|
||||
- task: RichCodeNavIndexer@0
|
||||
inputs:
|
||||
languages: 'cpp,csharp'
|
||||
25
build/pipelines/templates/console-ci-helix-job.yml
Normal file
25
build/pipelines/templates/console-ci-helix-job.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
platform: ''
|
||||
minimumExpectedTestsExecutedCount: 10 # Sanity check for minimum expected tests to be reported
|
||||
rerunPassesRequiredToAvoidFailure: 5
|
||||
|
||||
jobs:
|
||||
- template: helix-runtests-job.yml
|
||||
parameters:
|
||||
name: 'RunTestsInHelix'
|
||||
# We're not setting dependsOn as we want to rely on the "stage" dependency above us
|
||||
testSuite: 'DevTestSuite'
|
||||
platform: ${{ parameters.platform }}
|
||||
configuration: ${{ parameters.configuration }}
|
||||
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
|
||||
|
||||
- template: helix-processtestresults-job.yml
|
||||
parameters:
|
||||
dependsOn:
|
||||
- RunTestsInHelix
|
||||
# the default condition is succeededOrFailed(), and the "stage" condition ensures we only run as needed
|
||||
platform: ${{ parameters.platform }}
|
||||
configuration: ${{ parameters.configuration }}
|
||||
rerunPassesRequiredToAvoidFailure: ${{ parameters.rerunPassesRequiredToAvoidFailure }}
|
||||
minimumExpectedTestsExecutedCount: ${{ parameters.minimumExpectedTestsExecutedCount }}
|
||||
15
build/pipelines/templates/helix-createprojfile-steps.yml
Normal file
15
build/pipelines/templates/helix-createprojfile-steps.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
parameters:
|
||||
condition: ''
|
||||
testFilePath: ''
|
||||
outputProjFileName: ''
|
||||
testSuite: ''
|
||||
taefQuery: ''
|
||||
|
||||
steps:
|
||||
- task: powershell@2
|
||||
displayName: 'Create ${{ parameters.outputProjFileName }}'
|
||||
condition: ${{ parameters.condition }}
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\GenerateTestProjFile.ps1
|
||||
arguments: -TestFile '${{ parameters.testFilePath }}' -OutputProjFile '$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\$(BuildPlatform)\${{ parameters.outputProjFileName }}' -JobTestSuiteName '${{ parameters.testSuite }}' -TaefPath '$(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.60.210621002\build\Binaries\x86' -TaefQuery '${{ parameters.taefQuery }}'
|
||||
71
build/pipelines/templates/helix-processtestresults-job.yml
Normal file
71
build/pipelines/templates/helix-processtestresults-job.yml
Normal file
@@ -0,0 +1,71 @@
|
||||
parameters:
|
||||
condition: 'succeededOrFailed()'
|
||||
dependsOn: ''
|
||||
rerunPassesRequiredToAvoidFailure: 5
|
||||
minimumExpectedTestsExecutedCount: 10
|
||||
checkJobAttempt: false
|
||||
pgoArtifact: ''
|
||||
|
||||
jobs:
|
||||
- job: ProcessTestResults
|
||||
displayName: Process Helix Results ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||
condition: ${{ parameters.condition }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
timeoutInMinutes: 120
|
||||
variables:
|
||||
helixOutputFolder: $(Build.SourcesDirectory)\HelixOutput
|
||||
|
||||
steps:
|
||||
- task: powershell@2
|
||||
displayName: 'UpdateUnreliableTests.ps1'
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
HelixAccessToken: $(HelixApiAccessToken)
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\UpdateUnreliableTests.ps1
|
||||
arguments: -RerunPassesRequiredToAvoidFailure '${{ parameters.rerunPassesRequiredToAvoidFailure }}'
|
||||
|
||||
- task: powershell@2
|
||||
displayName: 'OutputTestResults.ps1'
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
HelixAccessToken: $(HelixApiAccessToken)
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\OutputTestResults.ps1
|
||||
arguments: -MinimumExpectedTestsExecutedCount '${{ parameters.minimumExpectedTestsExecutedCount }}' -CheckJobAttempt $${{ parameters.checkJobAttempt }}
|
||||
|
||||
- task: powershell@2
|
||||
displayName: 'ProcessHelixFiles.ps1'
|
||||
condition: succeededOrFailed()
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
HelixAccessToken: $(HelixApiAccessToken)
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\ProcessHelixFiles.ps1
|
||||
arguments: -OutputFolder '$(helixOutputFolder)'
|
||||
|
||||
- ${{if ne(parameters.pgoArtifact, '') }}:
|
||||
- script: move /y $(helixOutputFolder)\PGO $(Build.ArtifactStagingDirectory)
|
||||
displayName: 'Move pgc files to PGO artifact'
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Helix files'
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
PathtoPublish: $(helixOutputFolder)
|
||||
artifactName: drop
|
||||
|
||||
- ${{if ne(parameters.pgoArtifact, '') }}:
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish pgc files'
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)\PGO\Release
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
164
build/pipelines/templates/helix-runtests-job.yml
Normal file
164
build/pipelines/templates/helix-runtests-job.yml
Normal file
@@ -0,0 +1,164 @@
|
||||
parameters:
|
||||
name: 'RunTestsInHelix'
|
||||
dependsOn: ''
|
||||
condition: ''
|
||||
testSuite: ''
|
||||
# If a Pipeline runs this template more than once, this parameter should be unique per build flavor to differentiate the
|
||||
# the different test runs:
|
||||
helixType: 'test/devtest'
|
||||
artifactName: 'drop'
|
||||
maxParallel: 4
|
||||
rerunPassesRequiredToAvoidFailure: 5
|
||||
taefQuery: ''
|
||||
configuration: ''
|
||||
platform: ''
|
||||
# if 'useBuildOutputFromBuildId' is set, we will default to using a build from this pipeline:
|
||||
useBuildOutputFromPipeline: $(System.DefinitionId)
|
||||
openHelixTargetQueues: 'windows.11.amd64.client.open.reunion'
|
||||
closedHelixTargetQueues: 'windows.11.amd64.client.reunion'
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.name }}
|
||||
displayName: Submit Helix ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
condition: ${{ parameters.condition }}
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
timeoutInMinutes: 120
|
||||
strategy:
|
||||
maxParallel: ${{ parameters.maxParallel }}
|
||||
variables:
|
||||
buildConfiguration: ${{ parameters.configuration }}
|
||||
buildPlatform: ${{ parameters.platform }}
|
||||
openHelixTargetQueues: ${{ parameters.openHelixTargetQueues }}
|
||||
closedHelixTargetQueues: ${{ parameters.closedHelixTargetQueues }}
|
||||
artifactsDir: $(Build.SourcesDirectory)\Artifacts
|
||||
taefPath: $(Build.SourcesDirectory)\build\Helix\packages\Microsoft.Taef.10.60.210621002\build\Binaries\$(buildPlatform)
|
||||
helixCommonArgs: '/binaryLogger:$(Build.SourcesDirectory)/${{parameters.name}}.$(buildPlatform).$(buildConfiguration).binlog /p:HelixBuild=$(Build.BuildId).$(buildPlatform).$(buildConfiguration) /p:Platform=$(buildPlatform) /p:Configuration=$(buildConfiguration) /p:HelixType=${{parameters.helixType}} /p:TestSuite=${{parameters.testSuite}} /p:ProjFilesPath=$(Build.ArtifactStagingDirectory) /p:rerunPassesRequiredToAvoidFailure=${{parameters.rerunPassesRequiredToAvoidFailure}}'
|
||||
|
||||
steps:
|
||||
- task: CmdLine@1
|
||||
displayName: 'Display build machine environment variables'
|
||||
inputs:
|
||||
filename: 'set'
|
||||
|
||||
- task: NuGetToolInstaller@0
|
||||
displayName: 'Use NuGet 6.3.0'
|
||||
inputs:
|
||||
versionSpec: 6.3.0
|
||||
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: 'NuGet restore build/Helix/packages.config'
|
||||
inputs:
|
||||
restoreSolution: build/Helix/packages.config
|
||||
feedsToUse: config
|
||||
nugetConfigPath: nuget.config
|
||||
restoreDirectory: packages
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
condition:
|
||||
and(succeeded(),eq(variables['useBuildOutputFromBuildId'],''))
|
||||
inputs:
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
downloadPath: '$(artifactsDir)'
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
condition:
|
||||
and(succeeded(),ne(variables['useBuildOutputFromBuildId'],''))
|
||||
inputs:
|
||||
buildType: specific
|
||||
buildVersionToDownload: specific
|
||||
project: $(System.TeamProjectId)
|
||||
pipeline: ${{ parameters.useBuildOutputFromPipeline }}
|
||||
buildId: $(useBuildOutputFromBuildId)
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
downloadPath: '$(artifactsDir)'
|
||||
|
||||
- task: CmdLine@1
|
||||
displayName: 'Display Artifact Directory payload contents'
|
||||
inputs:
|
||||
filename: 'dir'
|
||||
arguments: '/s $(artifactsDir)'
|
||||
|
||||
- task: powershell@2
|
||||
displayName: 'PrepareHelixPayload.ps1'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\PrepareHelixPayload.ps1
|
||||
arguments: -Platform '$(buildPlatform)' -Configuration '$(buildConfiguration)' -ArtifactName '${{ parameters.artifactName }}'
|
||||
|
||||
- task: CmdLine@1
|
||||
displayName: 'Display Helix payload contents'
|
||||
inputs:
|
||||
filename: 'dir'
|
||||
arguments: '/s $(Build.SourcesDirectory)\HelixPayload'
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Make artifact directories'
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
New-Item -ItemType Directory -Force -Path "$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\"
|
||||
New-Item -ItemType Directory -Force -Path "$(Build.ArtifactStagingDirectory)\$(BuildConfiguration)\$(BuildPlatform)\"
|
||||
|
||||
- template: helix-createprojfile-steps.yml
|
||||
parameters:
|
||||
condition: and(succeeded(),eq('${{ parameters.testSuite }}','DevTestSuite'))
|
||||
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\TerminalApp.LocalTests.dll'
|
||||
outputProjFileName: 'RunTestsInHelix-TerminalAppLocalTests.proj'
|
||||
testSuite: '${{ parameters.testSuite }}'
|
||||
taefQuery: ${{ parameters.taefQuery }}
|
||||
|
||||
- template: helix-createprojfile-steps.yml
|
||||
parameters:
|
||||
condition: and(succeeded(),eq('${{ parameters.testSuite }}','DevTestSuite'))
|
||||
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\SettingsModel.LocalTests.dll'
|
||||
outputProjFileName: 'RunTestsInHelix-SettingsModelLocalTests.proj'
|
||||
testSuite: '${{ parameters.testSuite }}'
|
||||
taefQuery: ${{ parameters.taefQuery }}
|
||||
|
||||
|
||||
- template: helix-createprojfile-steps.yml
|
||||
parameters:
|
||||
condition: and(succeeded(),eq('${{ parameters.testSuite }}','DevTestSuite'))
|
||||
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\Conhost.UIA.Tests.dll'
|
||||
outputProjFileName: 'RunTestsInHelix-HostTestsUIA.proj'
|
||||
testSuite: '${{ parameters.testSuite }}'
|
||||
taefQuery: ${{ parameters.taefQuery }}
|
||||
|
||||
- template: helix-createprojfile-steps.yml
|
||||
parameters:
|
||||
condition: and(succeeded(),or(eq('${{ parameters.testSuite }}','PgoInstrumentationSuite'),eq('${{ parameters.testSuite }}','DevTestSuite')))
|
||||
testFilePath: '$(artifactsDir)\${{ parameters.artifactName }}\$(buildConfiguration)\$(buildPlatform)\Test\WindowsTerminal.UIA.Tests.dll'
|
||||
outputProjFileName: 'RunTestsInHelix-WindowsTerminalUIATests.proj'
|
||||
testSuite: '${{ parameters.testSuite }}'
|
||||
taefQuery: ${{ parameters.taefQuery }}
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish generated .proj files'
|
||||
inputs:
|
||||
PathtoPublish: $(Build.ArtifactStagingDirectory)
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Run tests in Helix (open queues)'
|
||||
condition: and(succeeded(),eq(variables['System.CollectionUri'],'https://dev.azure.com/ms/'))
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
inputs:
|
||||
command: custom
|
||||
projects: build\Helix\RunTestsInHelix.proj
|
||||
custom: msbuild
|
||||
arguments: '$(helixCommonArgs) /p:IsExternal=true /p:Creator=Terminal /p:HelixTargetQueues=$(openHelixTargetQueues)'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Run tests in Helix (closed queues)'
|
||||
condition: and(succeeded(),ne(variables['System.CollectionUri'],'https://dev.azure.com/ms/'))
|
||||
env:
|
||||
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
||||
HelixAccessToken: $(HelixApiAccessToken)
|
||||
inputs:
|
||||
command: custom
|
||||
projects: build\Helix\RunTestsInHelix.proj
|
||||
custom: msbuild
|
||||
arguments: '$(helixCommonArgs) /p:HelixTargetQueues=$(closedHelixTargetQueues)'
|
||||
@@ -1,26 +1,14 @@
|
||||
# From our friends at MUX: https://github.com/microsoft/microsoft-ui-xaml/blob/main/build/AzurePipelinesTemplates/MUX-BuildAndPublishPGONuGet-Job.yml
|
||||
|
||||
parameters:
|
||||
- name: buildConfiguration
|
||||
type: string
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: BuildAndPublishPGONuget
|
||||
dependsOn: ''
|
||||
pgoArtifact: PGO
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
- job: BuildAndPublishPGONuGet
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
displayName: Package and Publish PGO Databases
|
||||
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
variables:
|
||||
artifactsPath: $(Build.SourcesDirectory)\Artifacts
|
||||
pgoToolsPath: $(Build.SourcesDirectory)\build\PGO
|
||||
@@ -28,25 +16,20 @@ jobs:
|
||||
nuspecFilename: PGO.nuspec
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
# It is important that this be 0, otherwise git will not fetch the branch ref names that the PGO rules require.
|
||||
fetchDepth: 0
|
||||
submodules: false
|
||||
persistCredentials: false
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Final PGO Databases
|
||||
- task: DownloadBuildArtifacts@0
|
||||
inputs:
|
||||
artifact: pgd-merged-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
downloadPath: $(artifactsPath)
|
||||
|
||||
- template: steps-ensure-nuget-version.yml
|
||||
|
||||
- task: NuGetAuthenticate@1
|
||||
- task: NuGetAuthenticate@0
|
||||
inputs:
|
||||
nuGetServiceConnections: 'Terminal Public Artifact Feed'
|
||||
|
||||
- task: NuGetToolInstaller@0
|
||||
displayName: 'Use NuGet 5.8.0'
|
||||
inputs:
|
||||
versionSpec: 5.8.0
|
||||
|
||||
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
|
||||
# This should be `task: NuGetCommand@2`
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
@@ -62,11 +45,12 @@ jobs:
|
||||
displayName: 'Create PGO Nuget'
|
||||
inputs:
|
||||
solution: $(pgoToolsPath)\PGO.DB.proj
|
||||
msbuildArguments: '/t:CreatePGONuGet /p:PGOBuildMode=Instrument /p:PGDPathForAllArch=$(artifactsPath) /p:PGOOutputPath=$(Build.ArtifactStagingDirectory)'
|
||||
msbuildArguments: '/t:CreatePGONuGet /p:PGOBuildMode=Instrument /p:PGDPathForAllArch=$(artifactsPath)\${{ parameters.pgoArtifact }} /p:PGOOutputPath=$(Build.ArtifactStagingDirectory)'
|
||||
|
||||
- publish: $(Build.ArtifactStagingDirectory)
|
||||
artifact: pgo-nupkg-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
|
||||
displayName: "Publish Pipeline Artifact"
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathToPublish: $(Build.ArtifactStagingDirectory)
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: 'NuGet push'
|
||||
70
build/pipelines/templates/pgo-merge-pgd-job.yml
Normal file
70
build/pipelines/templates/pgo-merge-pgd-job.yml
Normal file
@@ -0,0 +1,70 @@
|
||||
parameters:
|
||||
dependsOn: ''
|
||||
pgoArtifact: PGO
|
||||
platform: ''
|
||||
configuration: ''
|
||||
|
||||
jobs:
|
||||
- job: MergePGD
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
variables:
|
||||
artifactsPath: $(Build.SourcesDirectory)\Artifacts
|
||||
pgoArtifactsPath: $(artifactsPath)\${{ parameters.pgoArtifact }}
|
||||
buildPlatform: ${{ parameters.platform }}
|
||||
buildConfiguration: ${{ parameters.configuration }}
|
||||
|
||||
steps:
|
||||
# The environment variable VCToolsInstallDir isn't defined on lab machines, so we need to retrieve it ourselves.
|
||||
- script: |
|
||||
"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -Latest -requires Microsoft.Component.MSBuild -property InstallationPath > %TEMP%\vsinstalldir.txt
|
||||
set /p _VSINSTALLDIR15=<%TEMP%\vsinstalldir.txt
|
||||
del %TEMP%\vsinstalldir.txt
|
||||
call "%_VSINSTALLDIR15%\Common7\Tools\VsDevCmd.bat"
|
||||
echo VCToolsInstallDir = %VCToolsInstallDir%
|
||||
echo ##vso[task.setvariable variable=VCToolsInstallDir]%VCToolsInstallDir%
|
||||
displayName: 'Retrieve VC tools directory'
|
||||
|
||||
- task: NuGetToolInstaller@0
|
||||
displayName: 'Use NuGet 6.3.0'
|
||||
inputs:
|
||||
versionSpec: 6.3.0
|
||||
|
||||
- task: NuGetAuthenticate@0
|
||||
|
||||
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
|
||||
# This should be `task: NuGetCommand@2`
|
||||
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
|
||||
displayName: Restore NuGet packages for extraneous build actions
|
||||
inputs:
|
||||
command: restore
|
||||
feedsToUse: config
|
||||
configPath: NuGet.config
|
||||
restoreSolution: build/packages.config
|
||||
restoreDirectory: '$(Build.SourcesDirectory)\packages'
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
inputs:
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
downloadPath: $(artifactsPath)
|
||||
|
||||
- task: MSBuild@1
|
||||
displayName: Merge counts into PGD
|
||||
inputs:
|
||||
solution: $(Build.SourcesDirectory)\OpenConsole.sln
|
||||
platform: $(buildPlatform)
|
||||
configuration: $(buildConfiguration)
|
||||
msbuildArguments: '/t:MergePGOCounts /p:PGOBuildMode=Instrument /p:PGDPath=$(pgoArtifactsPath)\$(buildPlatform) /p:PGCRootPath=$(pgoArtifactsPath)\$(buildPlatform)'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy merged pgd to artifact staging'
|
||||
inputs:
|
||||
sourceFolder: $(pgoArtifactsPath)
|
||||
contents: '**\$(buildPlatform)\*.pgd'
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)
|
||||
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathToPublish: $(Build.ArtifactStagingDirectory)
|
||||
artifactName: ${{ parameters.pgoArtifact }}
|
||||
@@ -1,12 +1,14 @@
|
||||
steps:
|
||||
- template: steps-ensure-nuget-version.yml
|
||||
- task: NuGetToolInstaller@0
|
||||
displayName: 'Use NuGet 6.3.0'
|
||||
inputs:
|
||||
versionSpec: 6.3.0
|
||||
|
||||
- task: NuGetAuthenticate@1
|
||||
- task: NuGetAuthenticate@0
|
||||
|
||||
- script: |-
|
||||
echo ##vso[task.setvariable variable=NUGET_RESTORE_MSBUILD_ARGS]/p:Platform=$(BuildPlatform)
|
||||
displayName: Ensure NuGet restores for $(BuildPlatform)
|
||||
condition: and(succeeded(), ne(variables['BuildPlatform'], 'Any CPU'))
|
||||
|
||||
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
|
||||
# This should be `task: NuGetCommand@2`
|
||||
90
build/pipelines/templates/test-console-ci.yml
Normal file
90
build/pipelines/templates/test-console-ci.yml
Normal file
@@ -0,0 +1,90 @@
|
||||
parameters:
|
||||
configuration: 'Release'
|
||||
platform: ''
|
||||
additionalBuildArguments: ''
|
||||
artifactName: 'drop'
|
||||
testLogPath: '$(Build.BinariesDirectory)\$(BuildPlatform)\$(BuildConfiguration)\testsOnBuildMachine.wtl'
|
||||
|
||||
jobs:
|
||||
- job: Test${{ parameters.platform }}${{ parameters.configuration }}
|
||||
displayName: Test ${{ parameters.platform }} ${{ parameters.configuration }}
|
||||
variables:
|
||||
BuildConfiguration: ${{ parameters.configuration }}
|
||||
BuildPlatform: ${{ parameters.platform }}
|
||||
pool:
|
||||
${{ if eq(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPoolOSS-L
|
||||
${{ if ne(variables['System.CollectionUri'], 'https://dev.azure.com/ms/') }}:
|
||||
name: WinDevPool-L
|
||||
demands: ImageOverride -equals WinDevVS17-latest
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: true
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
|
||||
- task: DownloadBuildArtifacts@0
|
||||
inputs:
|
||||
artifactName: ${{ parameters.artifactName }}
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Rationalize build platform'
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: |
|
||||
$Arch = "$(BuildPlatform)"
|
||||
If ($Arch -Eq "x86") { $Arch = "Win32" }
|
||||
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Run Unit Tests'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(System.ArtifactsDirectory)\\${{ parameters.artifactName }}\\$(BuildConfiguration)\\$(BuildPlatform)\\test"
|
||||
condition: and(and(succeeded(), ne(variables['PGOBuildMode'], 'Instrument')), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Run Feature Tests (x64 only)'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\scripts\Run-Tests.ps1
|
||||
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(System.ArtifactsDirectory)\\${{ parameters.artifactName }}\\$(BuildConfiguration)\\$(BuildPlatform)\\test"
|
||||
condition: and(and(succeeded(), ne(variables['PGOBuildMode'], 'Instrument')), eq(variables['BuildPlatform'], 'x64'))
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Convert Test Logs from WTL to xUnit format'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: build\Helix\ConvertWttLogToXUnit.ps1
|
||||
arguments: -WttInputPath '${{ parameters.testLogPath }}' -WttSingleRerunInputPath 'unused.wtl' -WttMultipleRerunInputPath 'unused2.wtl' -XUnitOutputPath 'onBuildMachineResults.xml' -TestNamePrefix '$(BuildConfiguration).$(BuildPlatform)'
|
||||
condition: and(ne(variables['PGOBuildMode'], 'Instrument'),or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Upload converted test logs'
|
||||
condition: ne(variables['PGOBuildMode'], 'Instrument')
|
||||
inputs:
|
||||
testResultsFormat: 'xUnit' # Options: JUnit, NUnit, VSTest, xUnit, cTest
|
||||
testResultsFiles: '**/onBuildMachineResults.xml'
|
||||
#searchFolder: '$(System.DefaultWorkingDirectory)' # Optional
|
||||
#mergeTestResults: false # Optional
|
||||
#failTaskOnFailedTests: false # Optional
|
||||
testRunTitle: 'On Build Machine Tests' # Optional
|
||||
buildPlatform: $(BuildPlatform) # Optional
|
||||
buildConfiguration: $(BuildConfiguration) # Optional
|
||||
#publishRunAttachments: true # Optional
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Copy result logs to Artifacts'
|
||||
inputs:
|
||||
Contents: |
|
||||
**/*.wtl
|
||||
**/*onBuildMachineResults.xml
|
||||
${{ parameters.testLogPath }}
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test-logs'
|
||||
OverWrite: true
|
||||
flattenFolders: true
|
||||
|
||||
- publish: '$(Build.ArtifactStagingDirectory)/$(BuildConfiguration)/$(BuildPlatform)/test-logs'
|
||||
artifact: TestLogs$(BuildPlatform)$(BuildConfiguration)
|
||||
@@ -30,7 +30,7 @@
|
||||
DependsOnTargets="_ConsoleMapWinmdsToManifestFiles">
|
||||
|
||||
<!-- This target is batched and a new Exec is spawned for each entry in _ConsoleWinmdManifest. -->
|
||||
<Exec Command="mt.exe -winmd:%(_ConsoleWinmdManifest.WinMDPath) -dll:%(_ConsoleWinmdManifest.Implementation) -out:%(_ConsoleWinmdManifest.Identity)" />
|
||||
<Exec Command="mt.exe -winmd:"%(_ConsoleWinmdManifest.WinMDPath)" -dll:%(_ConsoleWinmdManifest.Implementation) -out:"%(_ConsoleWinmdManifest.Identity)"" />
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Emit the generated manifest into the Link inputs. -->
|
||||
|
||||
@@ -10,12 +10,11 @@ $LocalizationsFromContextMenu | ForEach-Object {
|
||||
ForEach ($pair in $Languages.GetEnumerator()) {
|
||||
$LanguageDir = "./src/cascadia/CascadiaPackage/Resources/$($pair.Key)"
|
||||
$ResPath = "$LanguageDir/Resources.resw"
|
||||
$XmlDocument = $null
|
||||
$PreexistingResw = Get-Item $ResPath -EA:Ignore
|
||||
If ($null -eq $PreexistingResw) {
|
||||
Write-Host "Copying $($pair.Value.FullName) to $ResPath"
|
||||
$XmlDocument = [xml](Get-Content $pair.Value.FullName)
|
||||
New-Item -type Directory $LanguageDir -EA:Ignore
|
||||
Copy-Item $pair.Value.FullName $ResPath
|
||||
} Else {
|
||||
# Merge Them!
|
||||
Write-Host "Merging $($pair.Value.FullName) into $ResPath"
|
||||
@@ -30,19 +29,6 @@ ForEach ($pair in $Languages.GetEnumerator()) {
|
||||
$newXml.root.data | % {
|
||||
$null = $existingXml.root.AppendChild($existingXml.ImportNode($_, $true))
|
||||
}
|
||||
$XmlDocument = $existingXml # (which has been updated)
|
||||
$existingXml.Save($PreexistingResw.FullName)
|
||||
}
|
||||
|
||||
# Reset paths to be absolute (for .NET)
|
||||
$LanguageDir = (Get-Item $LanguageDir).FullName
|
||||
$ResPath = "$LanguageDir/Resources.resw"
|
||||
# Force the "new" and "preexisting" paths to serialize with XmlWriter,
|
||||
# to ensure consistency.
|
||||
$writerSettings = [System.Xml.XmlWriterSettings]::new()
|
||||
$writerSettings.NewLineChars = "`r`n"
|
||||
$writerSettings.Indent = $true
|
||||
$writer = [System.Xml.XmlWriter]::Create($ResPath, $writerSettings)
|
||||
$XmlDocument.Save($writer)
|
||||
$writer.Flush()
|
||||
$writer.Close()
|
||||
}
|
||||
|
||||
@@ -1,37 +1,27 @@
|
||||
[CmdLetBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true, Position=0)]
|
||||
[string]$MatchPattern,
|
||||
[Parameter(Mandatory=$true, Position=1)]
|
||||
[string]$Platform,
|
||||
[Parameter(Mandatory=$true, Position=2)]
|
||||
[string]$Configuration,
|
||||
[Parameter(Mandatory=$false, Position=3)]
|
||||
[string]$LogPath,
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$Root = ".\bin\$Platform\$Configuration",
|
||||
[string[]]$AdditionalTaefArguments
|
||||
[Parameter(Mandatory=$true, Position=0)][string]$MatchPattern,
|
||||
[Parameter(Mandatory=$true, Position=1)][string]$Platform,
|
||||
[Parameter(Mandatory=$true, Position=2)][string]$Configuration,
|
||||
[Parameter(Mandatory=$false, Position=3)][string]$LogPath,
|
||||
[Parameter(Mandatory=$false)][string]$Root = ".\bin\$Platform\$Configuration"
|
||||
)
|
||||
|
||||
# Find test DLLs based on the provided root, match pattern, and recursion
|
||||
$testDlls = Get-ChildItem -Path $Root -Recurse -Filter $MatchPattern
|
||||
$testdlls = Get-ChildItem -Path "$Root" -Recurse -Filter $MatchPattern
|
||||
|
||||
$args = @()
|
||||
|
||||
# Check if the LogPath parameter is provided and enable WTT logging
|
||||
if ($LogPath) {
|
||||
$args += '/enablewttlogging'
|
||||
$args += '/appendwttlogging'
|
||||
$args += "/logFile:$LogPath"
|
||||
Write-Host "WTT Logging Enabled"
|
||||
$args = @();
|
||||
|
||||
if ($LogPath)
|
||||
{
|
||||
$args += '/enablewttlogging';
|
||||
$args += '/appendwttlogging';
|
||||
$args += "/logFile:$LogPath";
|
||||
Write-Host "Wtt Logging Enabled";
|
||||
}
|
||||
|
||||
# Invoke the te.exe executable with arguments and test DLLs
|
||||
& "$Root\te.exe" $args $testDlls.FullName $AdditionalTaefArguments
|
||||
&"$Root\te.exe" $args $testdlls.FullName
|
||||
|
||||
# Check the exit code of the te.exe process and exit accordingly
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Exit $LASTEXITCODE
|
||||
}
|
||||
if ($lastexitcode -Ne 0) { Exit $lastexitcode }
|
||||
|
||||
Exit 0
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
|
||||
<XesBaseYearForStoreVersion>2023</XesBaseYearForStoreVersion>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>18</VersionMinor>
|
||||
<VersionMinor>19</VersionMinor>
|
||||
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<package id="Microsoft.Internal.PGO-Helpers.Cpp" version="0.2.34" targetFramework="native" />
|
||||
<package id="Microsoft.Taef" version="10.60.210621002" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.230207.1" targetFramework="native" />
|
||||
<package id="Microsoft.Internal.Windows.Terminal.ThemeHelpers" version="0.7.230706001" targetFramework="native" />
|
||||
<package id="Microsoft.Internal.Windows.Terminal.ThemeHelpers" version="0.6.220404001" targetFramework="native" />
|
||||
<package id="Microsoft.VisualStudio.Setup.Configuration.Native" version="2.3.2262" targetFramework="native" developmentDependency="true" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.8.4" targetFramework="native" />
|
||||
<package id="Microsoft.Web.WebView2" version="1.0.1661.34" targetFramework="native" />
|
||||
|
||||
@@ -260,8 +260,7 @@
|
||||
"description": "Name of the scheme to use when the app is using dark theme",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"FontConfig": {
|
||||
"properties": {
|
||||
@@ -640,7 +639,7 @@
|
||||
},
|
||||
"allowEmpty": {
|
||||
"description": "Whether to render a folder without entries, or to hide it",
|
||||
"default": false,
|
||||
"default": "false",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
@@ -1814,6 +1813,19 @@
|
||||
"description": "True if the Terminal should use a Mica backdrop for the window. This will apply underneath all controls (including the terminal panes and the titlebar)",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"experimental.rainbowFrame": {
|
||||
"description": "When enabled, the frame of the window will cycle through all the colors. Enabling this will override the `frame` and `unfocusedFrame` settings.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"frame": {
|
||||
"description": "The color of the window frame when the window is inactive. This only works on Windows 11",
|
||||
"$ref": "#/$defs/ThemeColor"
|
||||
},
|
||||
"unfocusedFrame": {
|
||||
"description": "The color of the window frame when the window is inactive. This only works on Windows 11",
|
||||
"$ref": "#/$defs/ThemeColor"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2171,6 +2183,11 @@
|
||||
"description": "When set to true, the background image for the currently focused profile is expanded to encompass the entire window, beneath other panes.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"compatibility.reloadEnvironmentVariables": {
|
||||
"default": true,
|
||||
"description": "When set to true, when opening a new tab or pane it will get reloaded environment variables.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"initialCols": {
|
||||
"default": 120,
|
||||
"description": "The number of columns displayed in the window upon first load. If \"launchMode\" is set to \"maximized\" (or \"maximizedFocus\"), this property is ignored.",
|
||||
@@ -2419,11 +2436,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"compatibility.reloadEnvironmentVariables": {
|
||||
"default": true,
|
||||
"description": "When set to true, when opening a new tab or pane it will get reloaded environment variables.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"unfocusedAppearance": {
|
||||
"$ref": "#/$defs/AppearanceConfig",
|
||||
"description": "Sets the appearance of the terminal when it is unfocused.",
|
||||
|
||||
57
oss/tracy/TracyClient.cpp
Normal file
57
oss/tracy/TracyClient.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// Tracy profiler
|
||||
// ----------------
|
||||
//
|
||||
// For fast integration, compile and
|
||||
// link with this source file (and none
|
||||
// other) in your executable (or in the
|
||||
// main DLL / shared object on multi-DLL
|
||||
// projects).
|
||||
//
|
||||
|
||||
// Define TRACY_ENABLE to enable profiler.
|
||||
|
||||
#include "common/TracySystem.cpp"
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#include "common/tracy_lz4.cpp"
|
||||
#include "client/TracyProfiler.cpp"
|
||||
#include "client/TracyCallstack.cpp"
|
||||
#include "client/TracySysTime.cpp"
|
||||
#include "client/TracySysTrace.cpp"
|
||||
#include "common/TracySocket.cpp"
|
||||
#include "client/tracy_rpmalloc.cpp"
|
||||
#include "client/TracyDxt1.cpp"
|
||||
#include "client/TracyAlloc.cpp"
|
||||
#include "client/TracyOverride.cpp"
|
||||
|
||||
#if TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6
|
||||
# include "libbacktrace/alloc.cpp"
|
||||
# include "libbacktrace/dwarf.cpp"
|
||||
# include "libbacktrace/fileline.cpp"
|
||||
# include "libbacktrace/mmapio.cpp"
|
||||
# include "libbacktrace/posix.cpp"
|
||||
# include "libbacktrace/sort.cpp"
|
||||
# include "libbacktrace/state.cpp"
|
||||
# if TRACY_HAS_CALLSTACK == 4
|
||||
# include "libbacktrace/macho.cpp"
|
||||
# else
|
||||
# include "libbacktrace/elf.cpp"
|
||||
# endif
|
||||
# include "common/TracyStackFrames.cpp"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma comment(lib, "ws2_32.lib")
|
||||
# pragma comment(lib, "dbghelp.lib")
|
||||
# pragma comment(lib, "advapi32.lib")
|
||||
# pragma comment(lib, "user32.lib")
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
43
oss/tracy/client/TracyAlloc.cpp
Normal file
43
oss/tracy/client/TracyAlloc.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "../common/TracyAlloc.hpp"
|
||||
|
||||
#ifdef TRACY_USE_RPMALLOC
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "../common/TracyForceInline.hpp"
|
||||
#include "../common/TracyYield.hpp"
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
extern thread_local bool RpThreadInitDone;
|
||||
extern std::atomic<int> RpInitDone;
|
||||
extern std::atomic<int> RpInitLock;
|
||||
|
||||
tracy_no_inline static void InitRpmallocPlumbing()
|
||||
{
|
||||
const auto done = RpInitDone.load( std::memory_order_acquire );
|
||||
if( !done )
|
||||
{
|
||||
int expected = 0;
|
||||
while( !RpInitLock.compare_exchange_weak( expected, 1, std::memory_order_release, std::memory_order_relaxed ) ) { expected = 0; YieldThread(); }
|
||||
const auto done = RpInitDone.load( std::memory_order_acquire );
|
||||
if( !done )
|
||||
{
|
||||
rpmalloc_initialize();
|
||||
RpInitDone.store( 1, std::memory_order_release );
|
||||
}
|
||||
RpInitLock.store( 0, std::memory_order_release );
|
||||
}
|
||||
rpmalloc_thread_initialize();
|
||||
RpThreadInitDone = true;
|
||||
}
|
||||
|
||||
TRACY_API void InitRpmalloc()
|
||||
{
|
||||
if( !RpThreadInitDone ) InitRpmallocPlumbing();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
401
oss/tracy/client/TracyArmCpuTable.hpp
Normal file
401
oss/tracy/client/TracyArmCpuTable.hpp
Normal file
@@ -0,0 +1,401 @@
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
#if defined __linux__ && defined __ARM_ARCH
|
||||
|
||||
static const char* DecodeArmImplementer( uint32_t v )
|
||||
{
|
||||
static char buf[16];
|
||||
switch( v )
|
||||
{
|
||||
case 0x41: return "ARM";
|
||||
case 0x42: return "Broadcom";
|
||||
case 0x43: return "Cavium";
|
||||
case 0x44: return "DEC";
|
||||
case 0x46: return "Fujitsu";
|
||||
case 0x48: return "HiSilicon";
|
||||
case 0x49: return "Infineon";
|
||||
case 0x4d: return "Motorola";
|
||||
case 0x4e: return "Nvidia";
|
||||
case 0x50: return "Applied Micro";
|
||||
case 0x51: return "Qualcomm";
|
||||
case 0x53: return "Samsung";
|
||||
case 0x54: return "Texas Instruments";
|
||||
case 0x56: return "Marvell";
|
||||
case 0x61: return "Apple";
|
||||
case 0x66: return "Faraday";
|
||||
case 0x68: return "HXT";
|
||||
case 0x69: return "Intel";
|
||||
case 0xc0: return "Ampere Computing";
|
||||
default: break;
|
||||
}
|
||||
sprintf( buf, "0x%x", v );
|
||||
return buf;
|
||||
}
|
||||
|
||||
static const char* DecodeArmPart( uint32_t impl, uint32_t part )
|
||||
{
|
||||
static char buf[16];
|
||||
switch( impl )
|
||||
{
|
||||
case 0x41: // ARM
|
||||
switch( part )
|
||||
{
|
||||
case 0x810: return "810";
|
||||
case 0x920: return "920";
|
||||
case 0x922: return "922";
|
||||
case 0x926: return "926";
|
||||
case 0x940: return "940";
|
||||
case 0x946: return "946";
|
||||
case 0x966: return "966";
|
||||
case 0xa20: return "1020";
|
||||
case 0xa22: return "1022";
|
||||
case 0xa26: return "1026";
|
||||
case 0xb02: return "11 MPCore";
|
||||
case 0xb36: return "1136";
|
||||
case 0xb56: return "1156";
|
||||
case 0xb76: return "1176";
|
||||
case 0xc05: return " Cortex-A5";
|
||||
case 0xc07: return " Cortex-A7";
|
||||
case 0xc08: return " Cortex-A8";
|
||||
case 0xc09: return " Cortex-A9";
|
||||
case 0xc0c: return " Cortex-A12";
|
||||
case 0xc0d: return " Rockchip RK3288";
|
||||
case 0xc0e: return " Cortex-A17";
|
||||
case 0xc0f: return " Cortex-A15";
|
||||
case 0xc14: return " Cortex-R4";
|
||||
case 0xc15: return " Cortex-R5";
|
||||
case 0xc17: return " Cortex-R7";
|
||||
case 0xc18: return " Cortex-R8";
|
||||
case 0xc20: return " Cortex-M0";
|
||||
case 0xc21: return " Cortex-M1";
|
||||
case 0xc23: return " Cortex-M3";
|
||||
case 0xc24: return " Cortex-M4";
|
||||
case 0xc27: return " Cortex-M7";
|
||||
case 0xc60: return " Cortex-M0+";
|
||||
case 0xd00: return " AArch64 simulator";
|
||||
case 0xd01: return " Cortex-A32";
|
||||
case 0xd02: return " Cortex-A34";
|
||||
case 0xd03: return " Cortex-A53";
|
||||
case 0xd04: return " Cortex-A35";
|
||||
case 0xd05: return " Cortex-A55";
|
||||
case 0xd06: return " Cortex-A65";
|
||||
case 0xd07: return " Cortex-A57";
|
||||
case 0xd08: return " Cortex-A72";
|
||||
case 0xd09: return " Cortex-A73";
|
||||
case 0xd0a: return " Cortex-A75";
|
||||
case 0xd0b: return " Cortex-A76";
|
||||
case 0xd0c: return " Neoverse N1";
|
||||
case 0xd0d: return " Cortex-A77";
|
||||
case 0xd0e: return " Cortex-A76AE";
|
||||
case 0xd0f: return " AEMv8";
|
||||
case 0xd13: return " Cortex-R52";
|
||||
case 0xd20: return " Cortex-M23";
|
||||
case 0xd21: return " Cortex-M33";
|
||||
case 0xd22: return " Cortex-M55";
|
||||
case 0xd40: return " Neoverse V1";
|
||||
case 0xd41: return " Cortex-A78";
|
||||
case 0xd42: return " Cortex-A78AE";
|
||||
case 0xd43: return " Cortex-A65AE";
|
||||
case 0xd44: return " Cortex-X1";
|
||||
case 0xd47: return " Cortex-A710";
|
||||
case 0xd48: return " Cortex-X2";
|
||||
case 0xd49: return " Neoverse N2";
|
||||
case 0xd4a: return " Neoverse E1";
|
||||
case 0xd4b: return " Cortex-A78C";
|
||||
case 0xd4c: return " Cortex-X1C";
|
||||
default: break;
|
||||
}
|
||||
case 0x42: // Broadcom
|
||||
switch( part )
|
||||
{
|
||||
case 0xf: return " Brahma B15";
|
||||
case 0x100: return " Brahma B53";
|
||||
case 0x516: return " ThunderX2";
|
||||
default: break;
|
||||
}
|
||||
case 0x43: // Cavium
|
||||
switch( part )
|
||||
{
|
||||
case 0xa0: return " ThunderX";
|
||||
case 0xa1: return " ThunderX 88XX";
|
||||
case 0xa2: return " ThunderX 81XX";
|
||||
case 0xa3: return " ThunderX 83XX";
|
||||
case 0xaf: return " ThunderX2 99xx";
|
||||
case 0xb0: return " OcteonTX2";
|
||||
case 0xb1: return " OcteonTX2 T98";
|
||||
case 0xb2: return " OcteonTX2 T96";
|
||||
case 0xb3: return " OcteonTX2 F95";
|
||||
case 0xb4: return " OcteonTX2 F95N";
|
||||
case 0xb5: return " OcteonTX2 F95MM";
|
||||
case 0xb6: return " OcteonTX2 F95O";
|
||||
case 0xb8: return " ThunderX3 T110";
|
||||
default: break;
|
||||
}
|
||||
case 0x44: // DEC
|
||||
switch( part )
|
||||
{
|
||||
case 0xa10: return " SA110";
|
||||
case 0xa11: return " SA1100";
|
||||
default: break;
|
||||
}
|
||||
case 0x46: // Fujitsu
|
||||
switch( part )
|
||||
{
|
||||
case 0x1: return " A64FX";
|
||||
default: break;
|
||||
}
|
||||
case 0x48: // HiSilicon
|
||||
switch( part )
|
||||
{
|
||||
case 0xd01: return " TSV100";
|
||||
case 0xd40: return " Kirin 980";
|
||||
default: break;
|
||||
}
|
||||
case 0x4e: // Nvidia
|
||||
switch( part )
|
||||
{
|
||||
case 0x0: return " Denver";
|
||||
case 0x3: return " Denver 2";
|
||||
case 0x4: return " Carmel";
|
||||
default: break;
|
||||
}
|
||||
case 0x50: // Applied Micro
|
||||
switch( part )
|
||||
{
|
||||
case 0x0: return " X-Gene";
|
||||
default: break;
|
||||
}
|
||||
case 0x51: // Qualcomm
|
||||
switch( part )
|
||||
{
|
||||
case 0xf: return " Scorpion";
|
||||
case 0x2d: return " Scorpion";
|
||||
case 0x4d: return " Krait";
|
||||
case 0x6f: return " Krait";
|
||||
case 0x200: return " Kryo";
|
||||
case 0x201: return " Kryo Silver (Snapdragon 821)";
|
||||
case 0x205: return " Kryo Gold";
|
||||
case 0x211: return " Kryo Silver (Snapdragon 820)";
|
||||
case 0x800: return " Kryo 260 / 280 Gold";
|
||||
case 0x801: return " Kryo 260 / 280 Silver";
|
||||
case 0x802: return " Kryo 385 Gold";
|
||||
case 0x803: return " Kryo 385 Silver";
|
||||
case 0x804: return " Kryo 485 Gold";
|
||||
case 0x805: return " Kryo 4xx/5xx Silver";
|
||||
case 0xc00: return " Falkor";
|
||||
case 0xc01: return " Saphira";
|
||||
default: break;
|
||||
}
|
||||
case 0x53: // Samsung
|
||||
switch( part )
|
||||
{
|
||||
case 0x1: return " Exynos M1/M2";
|
||||
case 0x2: return " Exynos M3";
|
||||
case 0x3: return " Exynos M4";
|
||||
case 0x4: return " Exynos M5";
|
||||
default: break;
|
||||
}
|
||||
case 0x54: // Texas Instruments
|
||||
switch( part )
|
||||
{
|
||||
case 0x925: return " TI925";
|
||||
default: break;
|
||||
}
|
||||
case 0x56: // Marvell
|
||||
switch( part )
|
||||
{
|
||||
case 0x131: return " Feroceon 88FR131";
|
||||
case 0x581: return " PJ4 / PJ4B";
|
||||
case 0x584: return " PJ4B-MP / PJ4C";
|
||||
default: break;
|
||||
}
|
||||
case 0x61: // Apple
|
||||
switch( part )
|
||||
{
|
||||
case 0x1: return " Cyclone";
|
||||
case 0x2: return " Typhoon";
|
||||
case 0x3: return " Typhoon/Capri";
|
||||
case 0x4: return " Twister";
|
||||
case 0x5: return " Twister/Elba/Malta";
|
||||
case 0x6: return " Hurricane";
|
||||
case 0x7: return " Hurricane/Myst";
|
||||
case 0x22: return " M1 Icestorm";
|
||||
case 0x23: return " M1 Firestorm";
|
||||
case 0x24: return " M1 Icestorm Pro";
|
||||
case 0x25: return " M1 Firestorm Pro";
|
||||
case 0x28: return " M1 Icestorm Max";
|
||||
case 0x29: return " M1 Firestorm Max";
|
||||
default: break;
|
||||
}
|
||||
case 0x66: // Faraday
|
||||
switch( part )
|
||||
{
|
||||
case 0x526: return " FA526";
|
||||
case 0x626: return " FA626";
|
||||
default: break;
|
||||
}
|
||||
case 0x68: // HXT
|
||||
switch( part )
|
||||
{
|
||||
case 0x0: return " Phecda";
|
||||
default: break;
|
||||
}
|
||||
case 0xc0: // Ampere Computing
|
||||
switch( part )
|
||||
{
|
||||
case 0xac3: return " Ampere1";
|
||||
default: break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
sprintf( buf, " 0x%x", part );
|
||||
return buf;
|
||||
}
|
||||
|
||||
#elif defined __APPLE__ && TARGET_OS_IPHONE == 1
|
||||
|
||||
static const char* DecodeIosDevice( const char* id )
|
||||
{
|
||||
static const char* DeviceTable[] = {
|
||||
"i386", "32-bit simulator",
|
||||
"x86_64", "64-bit simulator",
|
||||
"iPhone1,1", "iPhone",
|
||||
"iPhone1,2", "iPhone 3G",
|
||||
"iPhone2,1", "iPhone 3GS",
|
||||
"iPhone3,1", "iPhone 4 (GSM)",
|
||||
"iPhone3,2", "iPhone 4 (GSM)",
|
||||
"iPhone3,3", "iPhone 4 (CDMA)",
|
||||
"iPhone4,1", "iPhone 4S",
|
||||
"iPhone5,1", "iPhone 5 (A1428)",
|
||||
"iPhone5,2", "iPhone 5 (A1429)",
|
||||
"iPhone5,3", "iPhone 5c (A1456/A1532)",
|
||||
"iPhone5,4", "iPhone 5c (A1507/A1516/1526/A1529)",
|
||||
"iPhone6,1", "iPhone 5s (A1433/A1533)",
|
||||
"iPhone6,2", "iPhone 5s (A1457/A1518/A1528/A1530)",
|
||||
"iPhone7,1", "iPhone 6 Plus",
|
||||
"iPhone7,2", "iPhone 6",
|
||||
"iPhone8,1", "iPhone 6S",
|
||||
"iPhone8,2", "iPhone 6S Plus",
|
||||
"iPhone8,4", "iPhone SE",
|
||||
"iPhone9,1", "iPhone 7 (CDMA)",
|
||||
"iPhone9,2", "iPhone 7 Plus (CDMA)",
|
||||
"iPhone9,3", "iPhone 7 (GSM)",
|
||||
"iPhone9,4", "iPhone 7 Plus (GSM)",
|
||||
"iPhone10,1", "iPhone 8 (CDMA)",
|
||||
"iPhone10,2", "iPhone 8 Plus (CDMA)",
|
||||
"iPhone10,3", "iPhone X (CDMA)",
|
||||
"iPhone10,4", "iPhone 8 (GSM)",
|
||||
"iPhone10,5", "iPhone 8 Plus (GSM)",
|
||||
"iPhone10,6", "iPhone X (GSM)",
|
||||
"iPhone11,2", "iPhone XS",
|
||||
"iPhone11,4", "iPhone XS Max",
|
||||
"iPhone11,6", "iPhone XS Max China",
|
||||
"iPhone11,8", "iPhone XR",
|
||||
"iPhone12,1", "iPhone 11",
|
||||
"iPhone12,3", "iPhone 11 Pro",
|
||||
"iPhone12,5", "iPhone 11 Pro Max",
|
||||
"iPhone12,8", "iPhone SE 2nd Gen",
|
||||
"iPhone13,1", "iPhone 12 Mini",
|
||||
"iPhone13,2", "iPhone 12",
|
||||
"iPhone13,3", "iPhone 12 Pro",
|
||||
"iPhone13,4", "iPhone 12 Pro Max",
|
||||
"iPhone14,2", "iPhone 13 Pro",
|
||||
"iPhone14,3", "iPhone 13 Pro Max",
|
||||
"iPhone14,4", "iPhone 13 Mini",
|
||||
"iPhone14,5", "iPhone 13",
|
||||
"iPhone14,6", "iPhone SE 3rd Gen",
|
||||
"iPad1,1", "iPad (A1219/A1337)",
|
||||
"iPad2,1", "iPad 2 (A1395)",
|
||||
"iPad2,2", "iPad 2 (A1396)",
|
||||
"iPad2,3", "iPad 2 (A1397)",
|
||||
"iPad2,4", "iPad 2 (A1395)",
|
||||
"iPad2,5", "iPad Mini (A1432)",
|
||||
"iPad2,6", "iPad Mini (A1454)",
|
||||
"iPad2,7", "iPad Mini (A1455)",
|
||||
"iPad3,1", "iPad 3 (A1416)",
|
||||
"iPad3,2", "iPad 3 (A1403)",
|
||||
"iPad3,3", "iPad 3 (A1430)",
|
||||
"iPad3,4", "iPad 4 (A1458)",
|
||||
"iPad3,5", "iPad 4 (A1459)",
|
||||
"iPad3,6", "iPad 4 (A1460)",
|
||||
"iPad4,1", "iPad Air (A1474)",
|
||||
"iPad4,2", "iPad Air (A1475)",
|
||||
"iPad4,3", "iPad Air (A1476)",
|
||||
"iPad4,4", "iPad Mini 2 (A1489)",
|
||||
"iPad4,5", "iPad Mini 2 (A1490)",
|
||||
"iPad4,6", "iPad Mini 2 (A1491)",
|
||||
"iPad4,7", "iPad Mini 3 (A1599)",
|
||||
"iPad4,8", "iPad Mini 3 (A1600)",
|
||||
"iPad4,9", "iPad Mini 3 (A1601)",
|
||||
"iPad5,1", "iPad Mini 4 (A1538)",
|
||||
"iPad5,2", "iPad Mini 4 (A1550)",
|
||||
"iPad5,3", "iPad Air 2 (A1566)",
|
||||
"iPad5,4", "iPad Air 2 (A1567)",
|
||||
"iPad6,3", "iPad Pro 9.7\" (A1673)",
|
||||
"iPad6,4", "iPad Pro 9.7\" (A1674)",
|
||||
"iPad6,5", "iPad Pro 9.7\" (A1675)",
|
||||
"iPad6,7", "iPad Pro 12.9\" (A1584)",
|
||||
"iPad6,8", "iPad Pro 12.9\" (A1652)",
|
||||
"iPad6,11", "iPad 5th gen (A1822)",
|
||||
"iPad6,12", "iPad 5th gen (A1823)",
|
||||
"iPad7,1", "iPad Pro 12.9\" 2nd gen (A1670)",
|
||||
"iPad7,2", "iPad Pro 12.9\" 2nd gen (A1671/A1821)",
|
||||
"iPad7,3", "iPad Pro 10.5\" (A1701)",
|
||||
"iPad7,4", "iPad Pro 10.5\" (A1709)",
|
||||
"iPad7,5", "iPad 6th gen (A1893)",
|
||||
"iPad7,6", "iPad 6th gen (A1954)",
|
||||
"iPad7,11", "iPad 7th gen 10.2\" (Wifi)",
|
||||
"iPad7,12", "iPad 7th gen 10.2\" (Wifi+Cellular)",
|
||||
"iPad8,1", "iPad Pro 11\" (A1980)",
|
||||
"iPad8,2", "iPad Pro 11\" (A1980)",
|
||||
"iPad8,3", "iPad Pro 11\" (A1934/A1979/A2013)",
|
||||
"iPad8,4", "iPad Pro 11\" (A1934/A1979/A2013)",
|
||||
"iPad8,5", "iPad Pro 12.9\" 3rd gen (A1876)",
|
||||
"iPad8,6", "iPad Pro 12.9\" 3rd gen (A1876)",
|
||||
"iPad8,7", "iPad Pro 12.9\" 3rd gen (A1895/A1983/A2014)",
|
||||
"iPad8,8", "iPad Pro 12.9\" 3rd gen (A1895/A1983/A2014)",
|
||||
"iPad8,9", "iPad Pro 11\" 2nd gen (Wifi)",
|
||||
"iPad8,10", "iPad Pro 11\" 2nd gen (Wifi+Cellular)",
|
||||
"iPad8,11", "iPad Pro 12.9\" 4th gen (Wifi)",
|
||||
"iPad8,12", "iPad Pro 12.9\" 4th gen (Wifi+Cellular)",
|
||||
"iPad11,1", "iPad Mini 5th gen (A2133)",
|
||||
"iPad11,2", "iPad Mini 5th gen (A2124/A2125/A2126)",
|
||||
"iPad11,3", "iPad Air 3rd gen (A2152)",
|
||||
"iPad11,4", "iPad Air 3rd gen (A2123/A2153/A2154)",
|
||||
"iPad11,6", "iPad 8th gen (WiFi)",
|
||||
"iPad11,7", "iPad 8th gen (WiFi+Cellular)",
|
||||
"iPad13,1", "iPad Air 4th gen (WiFi)",
|
||||
"iPad13,2", "iPad Air 4th gen (WiFi+Cellular)",
|
||||
"iPad13,4", "iPad Pro 11\" 3rd gen",
|
||||
"iPad13,5", "iPad Pro 11\" 3rd gen",
|
||||
"iPad13,6", "iPad Pro 11\" 3rd gen",
|
||||
"iPad13,7", "iPad Pro 11\" 3rd gen",
|
||||
"iPad13,8", "iPad Pro 12.9\" 5th gen",
|
||||
"iPad13,9", "iPad Pro 12.9\" 5th gen",
|
||||
"iPad13,10", "iPad Pro 12.9\" 5th gen",
|
||||
"iPad13,11", "iPad Pro 12.9\" 5th gen",
|
||||
"iPad13,16", "iPad Air 5th Gen (WiFi)",
|
||||
"iPad13,17", "iPad Air 5th Gen (WiFi+Cellular)",
|
||||
"iPod1,1", "iPod Touch",
|
||||
"iPod2,1", "iPod Touch 2nd gen",
|
||||
"iPod3,1", "iPod Touch 3rd gen",
|
||||
"iPod4,1", "iPod Touch 4th gen",
|
||||
"iPod5,1", "iPod Touch 5th gen",
|
||||
"iPod7,1", "iPod Touch 6th gen",
|
||||
"iPod9,1", "iPod Touch 7th gen",
|
||||
nullptr
|
||||
};
|
||||
|
||||
auto ptr = DeviceTable;
|
||||
while( *ptr )
|
||||
{
|
||||
if( strcmp( ptr[0], id ) == 0 ) return ptr[1];
|
||||
ptr += 2;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
1066
oss/tracy/client/TracyCallstack.cpp
Normal file
1066
oss/tracy/client/TracyCallstack.cpp
Normal file
File diff suppressed because it is too large
Load Diff
35
oss/tracy/client/TracyCallstack.h
Normal file
35
oss/tracy/client/TracyCallstack.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef __TRACYCALLSTACK_H__
|
||||
#define __TRACYCALLSTACK_H__
|
||||
|
||||
#ifndef TRACY_NO_CALLSTACK
|
||||
|
||||
# if !defined _WIN32
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
|
||||
# if defined _WIN32
|
||||
# include "../common/TracyUwp.hpp"
|
||||
# ifndef TRACY_UWP
|
||||
# define TRACY_HAS_CALLSTACK 1
|
||||
# endif
|
||||
# elif defined __ANDROID__
|
||||
# if !defined __arm__ || __ANDROID_API__ >= 21
|
||||
# define TRACY_HAS_CALLSTACK 2
|
||||
# else
|
||||
# define TRACY_HAS_CALLSTACK 5
|
||||
# endif
|
||||
# elif defined __linux
|
||||
# if defined _GNU_SOURCE && defined __GLIBC__
|
||||
# define TRACY_HAS_CALLSTACK 3
|
||||
# else
|
||||
# define TRACY_HAS_CALLSTACK 2
|
||||
# endif
|
||||
# elif defined __APPLE__
|
||||
# define TRACY_HAS_CALLSTACK 4
|
||||
# elif defined BSD
|
||||
# define TRACY_HAS_CALLSTACK 6
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
142
oss/tracy/client/TracyCallstack.hpp
Normal file
142
oss/tracy/client/TracyCallstack.hpp
Normal file
@@ -0,0 +1,142 @@
|
||||
#ifndef __TRACYCALLSTACK_HPP__
|
||||
#define __TRACYCALLSTACK_HPP__
|
||||
|
||||
#include "../common/TracyApi.h"
|
||||
#include "../common/TracyForceInline.hpp"
|
||||
#include "TracyCallstack.h"
|
||||
|
||||
#if TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5
|
||||
# include <unwind.h>
|
||||
#elif TRACY_HAS_CALLSTACK >= 3
|
||||
# include <execinfo.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef TRACY_HAS_CALLSTACK
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
static tracy_force_inline void* Callstack( int depth ) { return nullptr; }
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef TRACY_DEBUGINFOD
|
||||
# include <elfutils/debuginfod.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../common/TracyAlloc.hpp"
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
struct CallstackSymbolData
|
||||
{
|
||||
const char* file;
|
||||
uint32_t line;
|
||||
bool needFree;
|
||||
uint64_t symAddr;
|
||||
};
|
||||
|
||||
struct CallstackEntry
|
||||
{
|
||||
const char* name;
|
||||
const char* file;
|
||||
uint32_t line;
|
||||
uint32_t symLen;
|
||||
uint64_t symAddr;
|
||||
};
|
||||
|
||||
struct CallstackEntryData
|
||||
{
|
||||
const CallstackEntry* data;
|
||||
uint8_t size;
|
||||
const char* imageName;
|
||||
};
|
||||
|
||||
CallstackSymbolData DecodeSymbolAddress( uint64_t ptr );
|
||||
const char* DecodeCallstackPtrFast( uint64_t ptr );
|
||||
CallstackEntryData DecodeCallstackPtr( uint64_t ptr );
|
||||
void InitCallstack();
|
||||
void InitCallstackCritical();
|
||||
void EndCallstack();
|
||||
const char* GetKernelModulePath( uint64_t addr );
|
||||
|
||||
#ifdef TRACY_DEBUGINFOD
|
||||
const uint8_t* GetBuildIdForImage( const char* image, size_t& size );
|
||||
debuginfod_client* GetDebuginfodClient();
|
||||
#endif
|
||||
|
||||
#if TRACY_HAS_CALLSTACK == 1
|
||||
|
||||
extern "C"
|
||||
{
|
||||
typedef unsigned long (__stdcall *___tracy_t_RtlWalkFrameChain)( void**, unsigned long, unsigned long );
|
||||
TRACY_API extern ___tracy_t_RtlWalkFrameChain ___tracy_RtlWalkFrameChain;
|
||||
}
|
||||
|
||||
static tracy_force_inline void* Callstack( int depth )
|
||||
{
|
||||
assert( depth >= 1 && depth < 63 );
|
||||
auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) );
|
||||
const auto num = ___tracy_RtlWalkFrameChain( (void**)( trace + 1 ), depth, 0 );
|
||||
*trace = num;
|
||||
return trace;
|
||||
}
|
||||
|
||||
#elif TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5
|
||||
|
||||
struct BacktraceState
|
||||
{
|
||||
void** current;
|
||||
void** end;
|
||||
};
|
||||
|
||||
static _Unwind_Reason_Code tracy_unwind_callback( struct _Unwind_Context* ctx, void* arg )
|
||||
{
|
||||
auto state = (BacktraceState*)arg;
|
||||
uintptr_t pc = _Unwind_GetIP( ctx );
|
||||
if( pc )
|
||||
{
|
||||
if( state->current == state->end ) return _URC_END_OF_STACK;
|
||||
*state->current++ = (void*)pc;
|
||||
}
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
static tracy_force_inline void* Callstack( int depth )
|
||||
{
|
||||
assert( depth >= 1 && depth < 63 );
|
||||
|
||||
auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) );
|
||||
BacktraceState state = { (void**)(trace+1), (void**)(trace+1+depth) };
|
||||
_Unwind_Backtrace( tracy_unwind_callback, &state );
|
||||
|
||||
*trace = (uintptr_t*)state.current - trace + 1;
|
||||
|
||||
return trace;
|
||||
}
|
||||
|
||||
#elif TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6
|
||||
|
||||
static tracy_force_inline void* Callstack( int depth )
|
||||
{
|
||||
assert( depth >= 1 );
|
||||
|
||||
auto trace = (uintptr_t*)tracy_malloc( ( 1 + (size_t)depth ) * sizeof( uintptr_t ) );
|
||||
const auto num = (size_t)backtrace( (void**)(trace+1), depth );
|
||||
*trace = num;
|
||||
|
||||
return trace;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
12
oss/tracy/client/TracyCpuid.hpp
Normal file
12
oss/tracy/client/TracyCpuid.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef __TRACYCPUID_HPP__
|
||||
#define __TRACYCPUID_HPP__
|
||||
|
||||
// Prior to GCC 11 the cpuid.h header did not have any include guards and thus
|
||||
// including it more than once would cause a compiler error due to symbol
|
||||
// redefinitions. In order to support older GCC versions, we have to wrap this
|
||||
// include between custom include guards to prevent this issue.
|
||||
// See also https://github.com/wolfpld/tracy/issues/452
|
||||
|
||||
#include <cpuid.h>
|
||||
|
||||
#endif
|
||||
11
oss/tracy/client/TracyDebug.hpp
Normal file
11
oss/tracy/client/TracyDebug.hpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef __TRACYPRINT_HPP__
|
||||
#define __TRACYPRINT_HPP__
|
||||
|
||||
#ifdef TRACY_VERBOSE
|
||||
# include <stdio.h>
|
||||
# define TracyDebug(...) fprintf( stderr, __VA_ARGS__ );
|
||||
#else
|
||||
# define TracyDebug(...)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
644
oss/tracy/client/TracyDxt1.cpp
Normal file
644
oss/tracy/client/TracyDxt1.cpp
Normal file
@@ -0,0 +1,644 @@
|
||||
#include "TracyDxt1.hpp"
|
||||
#include "../common/TracyForceInline.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __ARM_NEON
|
||||
# include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
#if defined __AVX__ && !defined __SSE4_1__
|
||||
# define __SSE4_1__
|
||||
#endif
|
||||
|
||||
#if defined __SSE4_1__ || defined __AVX2__
|
||||
# ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# else
|
||||
# include <x86intrin.h>
|
||||
# ifndef _mm256_cvtsi256_si32
|
||||
# define _mm256_cvtsi256_si32( v ) ( _mm_cvtsi128_si32( _mm256_castsi256_si128( v ) ) )
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
static inline uint16_t to565( uint8_t r, uint8_t g, uint8_t b )
|
||||
{
|
||||
return ( ( r & 0xF8 ) << 8 ) | ( ( g & 0xFC ) << 3 ) | ( b >> 3 );
|
||||
}
|
||||
|
||||
static inline uint16_t to565( uint32_t c )
|
||||
{
|
||||
return
|
||||
( ( c & 0xF80000 ) >> 19 ) |
|
||||
( ( c & 0x00FC00 ) >> 5 ) |
|
||||
( ( c & 0x0000F8 ) << 8 );
|
||||
}
|
||||
|
||||
static const uint16_t DivTable[255*3+1] = {
|
||||
0xffff, 0xffff, 0xffff, 0xffff, 0xcccc, 0xaaaa, 0x9249, 0x8000, 0x71c7, 0x6666, 0x5d17, 0x5555, 0x4ec4, 0x4924, 0x4444, 0x4000,
|
||||
0x3c3c, 0x38e3, 0x35e5, 0x3333, 0x30c3, 0x2e8b, 0x2c85, 0x2aaa, 0x28f5, 0x2762, 0x25ed, 0x2492, 0x234f, 0x2222, 0x2108, 0x2000,
|
||||
0x1f07, 0x1e1e, 0x1d41, 0x1c71, 0x1bac, 0x1af2, 0x1a41, 0x1999, 0x18f9, 0x1861, 0x17d0, 0x1745, 0x16c1, 0x1642, 0x15c9, 0x1555,
|
||||
0x14e5, 0x147a, 0x1414, 0x13b1, 0x1352, 0x12f6, 0x129e, 0x1249, 0x11f7, 0x11a7, 0x115b, 0x1111, 0x10c9, 0x1084, 0x1041, 0x1000,
|
||||
0x0fc0, 0x0f83, 0x0f48, 0x0f0f, 0x0ed7, 0x0ea0, 0x0e6c, 0x0e38, 0x0e07, 0x0dd6, 0x0da7, 0x0d79, 0x0d4c, 0x0d20, 0x0cf6, 0x0ccc,
|
||||
0x0ca4, 0x0c7c, 0x0c56, 0x0c30, 0x0c0c, 0x0be8, 0x0bc5, 0x0ba2, 0x0b81, 0x0b60, 0x0b40, 0x0b21, 0x0b02, 0x0ae4, 0x0ac7, 0x0aaa,
|
||||
0x0a8e, 0x0a72, 0x0a57, 0x0a3d, 0x0a23, 0x0a0a, 0x09f1, 0x09d8, 0x09c0, 0x09a9, 0x0991, 0x097b, 0x0964, 0x094f, 0x0939, 0x0924,
|
||||
0x090f, 0x08fb, 0x08e7, 0x08d3, 0x08c0, 0x08ad, 0x089a, 0x0888, 0x0876, 0x0864, 0x0853, 0x0842, 0x0831, 0x0820, 0x0810, 0x0800,
|
||||
0x07f0, 0x07e0, 0x07d1, 0x07c1, 0x07b3, 0x07a4, 0x0795, 0x0787, 0x0779, 0x076b, 0x075d, 0x0750, 0x0743, 0x0736, 0x0729, 0x071c,
|
||||
0x070f, 0x0703, 0x06f7, 0x06eb, 0x06df, 0x06d3, 0x06c8, 0x06bc, 0x06b1, 0x06a6, 0x069b, 0x0690, 0x0685, 0x067b, 0x0670, 0x0666,
|
||||
0x065c, 0x0652, 0x0648, 0x063e, 0x0634, 0x062b, 0x0621, 0x0618, 0x060f, 0x0606, 0x05fd, 0x05f4, 0x05eb, 0x05e2, 0x05d9, 0x05d1,
|
||||
0x05c9, 0x05c0, 0x05b8, 0x05b0, 0x05a8, 0x05a0, 0x0598, 0x0590, 0x0588, 0x0581, 0x0579, 0x0572, 0x056b, 0x0563, 0x055c, 0x0555,
|
||||
0x054e, 0x0547, 0x0540, 0x0539, 0x0532, 0x052b, 0x0525, 0x051e, 0x0518, 0x0511, 0x050b, 0x0505, 0x04fe, 0x04f8, 0x04f2, 0x04ec,
|
||||
0x04e6, 0x04e0, 0x04da, 0x04d4, 0x04ce, 0x04c8, 0x04c3, 0x04bd, 0x04b8, 0x04b2, 0x04ad, 0x04a7, 0x04a2, 0x049c, 0x0497, 0x0492,
|
||||
0x048d, 0x0487, 0x0482, 0x047d, 0x0478, 0x0473, 0x046e, 0x0469, 0x0465, 0x0460, 0x045b, 0x0456, 0x0452, 0x044d, 0x0448, 0x0444,
|
||||
0x043f, 0x043b, 0x0436, 0x0432, 0x042d, 0x0429, 0x0425, 0x0421, 0x041c, 0x0418, 0x0414, 0x0410, 0x040c, 0x0408, 0x0404, 0x0400,
|
||||
0x03fc, 0x03f8, 0x03f4, 0x03f0, 0x03ec, 0x03e8, 0x03e4, 0x03e0, 0x03dd, 0x03d9, 0x03d5, 0x03d2, 0x03ce, 0x03ca, 0x03c7, 0x03c3,
|
||||
0x03c0, 0x03bc, 0x03b9, 0x03b5, 0x03b2, 0x03ae, 0x03ab, 0x03a8, 0x03a4, 0x03a1, 0x039e, 0x039b, 0x0397, 0x0394, 0x0391, 0x038e,
|
||||
0x038b, 0x0387, 0x0384, 0x0381, 0x037e, 0x037b, 0x0378, 0x0375, 0x0372, 0x036f, 0x036c, 0x0369, 0x0366, 0x0364, 0x0361, 0x035e,
|
||||
0x035b, 0x0358, 0x0355, 0x0353, 0x0350, 0x034d, 0x034a, 0x0348, 0x0345, 0x0342, 0x0340, 0x033d, 0x033a, 0x0338, 0x0335, 0x0333,
|
||||
0x0330, 0x032e, 0x032b, 0x0329, 0x0326, 0x0324, 0x0321, 0x031f, 0x031c, 0x031a, 0x0317, 0x0315, 0x0313, 0x0310, 0x030e, 0x030c,
|
||||
0x0309, 0x0307, 0x0305, 0x0303, 0x0300, 0x02fe, 0x02fc, 0x02fa, 0x02f7, 0x02f5, 0x02f3, 0x02f1, 0x02ef, 0x02ec, 0x02ea, 0x02e8,
|
||||
0x02e6, 0x02e4, 0x02e2, 0x02e0, 0x02de, 0x02dc, 0x02da, 0x02d8, 0x02d6, 0x02d4, 0x02d2, 0x02d0, 0x02ce, 0x02cc, 0x02ca, 0x02c8,
|
||||
0x02c6, 0x02c4, 0x02c2, 0x02c0, 0x02be, 0x02bc, 0x02bb, 0x02b9, 0x02b7, 0x02b5, 0x02b3, 0x02b1, 0x02b0, 0x02ae, 0x02ac, 0x02aa,
|
||||
0x02a8, 0x02a7, 0x02a5, 0x02a3, 0x02a1, 0x02a0, 0x029e, 0x029c, 0x029b, 0x0299, 0x0297, 0x0295, 0x0294, 0x0292, 0x0291, 0x028f,
|
||||
0x028d, 0x028c, 0x028a, 0x0288, 0x0287, 0x0285, 0x0284, 0x0282, 0x0280, 0x027f, 0x027d, 0x027c, 0x027a, 0x0279, 0x0277, 0x0276,
|
||||
0x0274, 0x0273, 0x0271, 0x0270, 0x026e, 0x026d, 0x026b, 0x026a, 0x0268, 0x0267, 0x0265, 0x0264, 0x0263, 0x0261, 0x0260, 0x025e,
|
||||
0x025d, 0x025c, 0x025a, 0x0259, 0x0257, 0x0256, 0x0255, 0x0253, 0x0252, 0x0251, 0x024f, 0x024e, 0x024d, 0x024b, 0x024a, 0x0249,
|
||||
0x0247, 0x0246, 0x0245, 0x0243, 0x0242, 0x0241, 0x0240, 0x023e, 0x023d, 0x023c, 0x023b, 0x0239, 0x0238, 0x0237, 0x0236, 0x0234,
|
||||
0x0233, 0x0232, 0x0231, 0x0230, 0x022e, 0x022d, 0x022c, 0x022b, 0x022a, 0x0229, 0x0227, 0x0226, 0x0225, 0x0224, 0x0223, 0x0222,
|
||||
0x0220, 0x021f, 0x021e, 0x021d, 0x021c, 0x021b, 0x021a, 0x0219, 0x0218, 0x0216, 0x0215, 0x0214, 0x0213, 0x0212, 0x0211, 0x0210,
|
||||
0x020f, 0x020e, 0x020d, 0x020c, 0x020b, 0x020a, 0x0209, 0x0208, 0x0207, 0x0206, 0x0205, 0x0204, 0x0203, 0x0202, 0x0201, 0x0200,
|
||||
0x01ff, 0x01fe, 0x01fd, 0x01fc, 0x01fb, 0x01fa, 0x01f9, 0x01f8, 0x01f7, 0x01f6, 0x01f5, 0x01f4, 0x01f3, 0x01f2, 0x01f1, 0x01f0,
|
||||
0x01ef, 0x01ee, 0x01ed, 0x01ec, 0x01eb, 0x01ea, 0x01e9, 0x01e9, 0x01e8, 0x01e7, 0x01e6, 0x01e5, 0x01e4, 0x01e3, 0x01e2, 0x01e1,
|
||||
0x01e0, 0x01e0, 0x01df, 0x01de, 0x01dd, 0x01dc, 0x01db, 0x01da, 0x01da, 0x01d9, 0x01d8, 0x01d7, 0x01d6, 0x01d5, 0x01d4, 0x01d4,
|
||||
0x01d3, 0x01d2, 0x01d1, 0x01d0, 0x01cf, 0x01cf, 0x01ce, 0x01cd, 0x01cc, 0x01cb, 0x01cb, 0x01ca, 0x01c9, 0x01c8, 0x01c7, 0x01c7,
|
||||
0x01c6, 0x01c5, 0x01c4, 0x01c3, 0x01c3, 0x01c2, 0x01c1, 0x01c0, 0x01c0, 0x01bf, 0x01be, 0x01bd, 0x01bd, 0x01bc, 0x01bb, 0x01ba,
|
||||
0x01ba, 0x01b9, 0x01b8, 0x01b7, 0x01b7, 0x01b6, 0x01b5, 0x01b4, 0x01b4, 0x01b3, 0x01b2, 0x01b2, 0x01b1, 0x01b0, 0x01af, 0x01af,
|
||||
0x01ae, 0x01ad, 0x01ad, 0x01ac, 0x01ab, 0x01aa, 0x01aa, 0x01a9, 0x01a8, 0x01a8, 0x01a7, 0x01a6, 0x01a6, 0x01a5, 0x01a4, 0x01a4,
|
||||
0x01a3, 0x01a2, 0x01a2, 0x01a1, 0x01a0, 0x01a0, 0x019f, 0x019e, 0x019e, 0x019d, 0x019c, 0x019c, 0x019b, 0x019a, 0x019a, 0x0199,
|
||||
0x0198, 0x0198, 0x0197, 0x0197, 0x0196, 0x0195, 0x0195, 0x0194, 0x0193, 0x0193, 0x0192, 0x0192, 0x0191, 0x0190, 0x0190, 0x018f,
|
||||
0x018f, 0x018e, 0x018d, 0x018d, 0x018c, 0x018b, 0x018b, 0x018a, 0x018a, 0x0189, 0x0189, 0x0188, 0x0187, 0x0187, 0x0186, 0x0186,
|
||||
0x0185, 0x0184, 0x0184, 0x0183, 0x0183, 0x0182, 0x0182, 0x0181, 0x0180, 0x0180, 0x017f, 0x017f, 0x017e, 0x017e, 0x017d, 0x017d,
|
||||
0x017c, 0x017b, 0x017b, 0x017a, 0x017a, 0x0179, 0x0179, 0x0178, 0x0178, 0x0177, 0x0177, 0x0176, 0x0175, 0x0175, 0x0174, 0x0174,
|
||||
0x0173, 0x0173, 0x0172, 0x0172, 0x0171, 0x0171, 0x0170, 0x0170, 0x016f, 0x016f, 0x016e, 0x016e, 0x016d, 0x016d, 0x016c, 0x016c,
|
||||
0x016b, 0x016b, 0x016a, 0x016a, 0x0169, 0x0169, 0x0168, 0x0168, 0x0167, 0x0167, 0x0166, 0x0166, 0x0165, 0x0165, 0x0164, 0x0164,
|
||||
0x0163, 0x0163, 0x0162, 0x0162, 0x0161, 0x0161, 0x0160, 0x0160, 0x015f, 0x015f, 0x015e, 0x015e, 0x015d, 0x015d, 0x015d, 0x015c,
|
||||
0x015c, 0x015b, 0x015b, 0x015a, 0x015a, 0x0159, 0x0159, 0x0158, 0x0158, 0x0158, 0x0157, 0x0157, 0x0156, 0x0156
|
||||
};
|
||||
|
||||
#if defined __ARM_NEON && defined __aarch64__
|
||||
static const uint16_t DivTableNEON[255*3+1] = {
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x1c71, 0x1af2, 0x1999, 0x1861, 0x1745, 0x1642, 0x1555, 0x147a, 0x13b1, 0x12f6, 0x1249, 0x11a7, 0x1111, 0x1084, 0x1000,
|
||||
0x0f83, 0x0f0f, 0x0ea0, 0x0e38, 0x0dd6, 0x0d79, 0x0d20, 0x0ccc, 0x0c7c, 0x0c30, 0x0be8, 0x0ba2, 0x0b60, 0x0b21, 0x0ae4, 0x0aaa,
|
||||
0x0a72, 0x0a3d, 0x0a0a, 0x09d8, 0x09a9, 0x097b, 0x094f, 0x0924, 0x08fb, 0x08d3, 0x08ad, 0x0888, 0x0864, 0x0842, 0x0820, 0x0800,
|
||||
0x07e0, 0x07c1, 0x07a4, 0x0787, 0x076b, 0x0750, 0x0736, 0x071c, 0x0703, 0x06eb, 0x06d3, 0x06bc, 0x06a6, 0x0690, 0x067b, 0x0666,
|
||||
0x0652, 0x063e, 0x062b, 0x0618, 0x0606, 0x05f4, 0x05e2, 0x05d1, 0x05c0, 0x05b0, 0x05a0, 0x0590, 0x0581, 0x0572, 0x0563, 0x0555,
|
||||
0x0547, 0x0539, 0x052b, 0x051e, 0x0511, 0x0505, 0x04f8, 0x04ec, 0x04e0, 0x04d4, 0x04c8, 0x04bd, 0x04b2, 0x04a7, 0x049c, 0x0492,
|
||||
0x0487, 0x047d, 0x0473, 0x0469, 0x0460, 0x0456, 0x044d, 0x0444, 0x043b, 0x0432, 0x0429, 0x0421, 0x0418, 0x0410, 0x0408, 0x0400,
|
||||
0x03f8, 0x03f0, 0x03e8, 0x03e0, 0x03d9, 0x03d2, 0x03ca, 0x03c3, 0x03bc, 0x03b5, 0x03ae, 0x03a8, 0x03a1, 0x039b, 0x0394, 0x038e,
|
||||
0x0387, 0x0381, 0x037b, 0x0375, 0x036f, 0x0369, 0x0364, 0x035e, 0x0358, 0x0353, 0x034d, 0x0348, 0x0342, 0x033d, 0x0338, 0x0333,
|
||||
0x032e, 0x0329, 0x0324, 0x031f, 0x031a, 0x0315, 0x0310, 0x030c, 0x0307, 0x0303, 0x02fe, 0x02fa, 0x02f5, 0x02f1, 0x02ec, 0x02e8,
|
||||
0x02e4, 0x02e0, 0x02dc, 0x02d8, 0x02d4, 0x02d0, 0x02cc, 0x02c8, 0x02c4, 0x02c0, 0x02bc, 0x02b9, 0x02b5, 0x02b1, 0x02ae, 0x02aa,
|
||||
0x02a7, 0x02a3, 0x02a0, 0x029c, 0x0299, 0x0295, 0x0292, 0x028f, 0x028c, 0x0288, 0x0285, 0x0282, 0x027f, 0x027c, 0x0279, 0x0276,
|
||||
0x0273, 0x0270, 0x026d, 0x026a, 0x0267, 0x0264, 0x0261, 0x025e, 0x025c, 0x0259, 0x0256, 0x0253, 0x0251, 0x024e, 0x024b, 0x0249,
|
||||
0x0246, 0x0243, 0x0241, 0x023e, 0x023c, 0x0239, 0x0237, 0x0234, 0x0232, 0x0230, 0x022d, 0x022b, 0x0229, 0x0226, 0x0224, 0x0222,
|
||||
0x021f, 0x021d, 0x021b, 0x0219, 0x0216, 0x0214, 0x0212, 0x0210, 0x020e, 0x020c, 0x020a, 0x0208, 0x0206, 0x0204, 0x0202, 0x0200,
|
||||
0x01fe, 0x01fc, 0x01fa, 0x01f8, 0x01f6, 0x01f4, 0x01f2, 0x01f0, 0x01ee, 0x01ec, 0x01ea, 0x01e9, 0x01e7, 0x01e5, 0x01e3, 0x01e1,
|
||||
0x01e0, 0x01de, 0x01dc, 0x01da, 0x01d9, 0x01d7, 0x01d5, 0x01d4, 0x01d2, 0x01d0, 0x01cf, 0x01cd, 0x01cb, 0x01ca, 0x01c8, 0x01c7,
|
||||
0x01c5, 0x01c3, 0x01c2, 0x01c0, 0x01bf, 0x01bd, 0x01bc, 0x01ba, 0x01b9, 0x01b7, 0x01b6, 0x01b4, 0x01b3, 0x01b2, 0x01b0, 0x01af,
|
||||
0x01ad, 0x01ac, 0x01aa, 0x01a9, 0x01a8, 0x01a6, 0x01a5, 0x01a4, 0x01a2, 0x01a1, 0x01a0, 0x019e, 0x019d, 0x019c, 0x019a, 0x0199,
|
||||
0x0198, 0x0197, 0x0195, 0x0194, 0x0193, 0x0192, 0x0190, 0x018f, 0x018e, 0x018d, 0x018b, 0x018a, 0x0189, 0x0188, 0x0187, 0x0186,
|
||||
0x0184, 0x0183, 0x0182, 0x0181, 0x0180, 0x017f, 0x017e, 0x017d, 0x017b, 0x017a, 0x0179, 0x0178, 0x0177, 0x0176, 0x0175, 0x0174,
|
||||
0x0173, 0x0172, 0x0171, 0x0170, 0x016f, 0x016e, 0x016d, 0x016c, 0x016b, 0x016a, 0x0169, 0x0168, 0x0167, 0x0166, 0x0165, 0x0164,
|
||||
0x0163, 0x0162, 0x0161, 0x0160, 0x015f, 0x015e, 0x015d, 0x015c, 0x015b, 0x015a, 0x0159, 0x0158, 0x0158, 0x0157, 0x0156, 0x0155,
|
||||
0x0154, 0x0153, 0x0152, 0x0151, 0x0150, 0x0150, 0x014f, 0x014e, 0x014d, 0x014c, 0x014b, 0x014a, 0x014a, 0x0149, 0x0148, 0x0147,
|
||||
0x0146, 0x0146, 0x0145, 0x0144, 0x0143, 0x0142, 0x0142, 0x0141, 0x0140, 0x013f, 0x013e, 0x013e, 0x013d, 0x013c, 0x013b, 0x013b,
|
||||
0x013a, 0x0139, 0x0138, 0x0138, 0x0137, 0x0136, 0x0135, 0x0135, 0x0134, 0x0133, 0x0132, 0x0132, 0x0131, 0x0130, 0x0130, 0x012f,
|
||||
0x012e, 0x012e, 0x012d, 0x012c, 0x012b, 0x012b, 0x012a, 0x0129, 0x0129, 0x0128, 0x0127, 0x0127, 0x0126, 0x0125, 0x0125, 0x0124,
|
||||
0x0123, 0x0123, 0x0122, 0x0121, 0x0121, 0x0120, 0x0120, 0x011f, 0x011e, 0x011e, 0x011d, 0x011c, 0x011c, 0x011b, 0x011b, 0x011a,
|
||||
0x0119, 0x0119, 0x0118, 0x0118, 0x0117, 0x0116, 0x0116, 0x0115, 0x0115, 0x0114, 0x0113, 0x0113, 0x0112, 0x0112, 0x0111, 0x0111,
|
||||
0x0110, 0x010f, 0x010f, 0x010e, 0x010e, 0x010d, 0x010d, 0x010c, 0x010c, 0x010b, 0x010a, 0x010a, 0x0109, 0x0109, 0x0108, 0x0108,
|
||||
0x0107, 0x0107, 0x0106, 0x0106, 0x0105, 0x0105, 0x0104, 0x0104, 0x0103, 0x0103, 0x0102, 0x0102, 0x0101, 0x0101, 0x0100, 0x0100,
|
||||
0x00ff, 0x00ff, 0x00fe, 0x00fe, 0x00fd, 0x00fd, 0x00fc, 0x00fc, 0x00fb, 0x00fb, 0x00fa, 0x00fa, 0x00f9, 0x00f9, 0x00f8, 0x00f8,
|
||||
0x00f7, 0x00f7, 0x00f6, 0x00f6, 0x00f5, 0x00f5, 0x00f4, 0x00f4, 0x00f4, 0x00f3, 0x00f3, 0x00f2, 0x00f2, 0x00f1, 0x00f1, 0x00f0,
|
||||
0x00f0, 0x00f0, 0x00ef, 0x00ef, 0x00ee, 0x00ee, 0x00ed, 0x00ed, 0x00ed, 0x00ec, 0x00ec, 0x00eb, 0x00eb, 0x00ea, 0x00ea, 0x00ea,
|
||||
0x00e9, 0x00e9, 0x00e8, 0x00e8, 0x00e7, 0x00e7, 0x00e7, 0x00e6, 0x00e6, 0x00e5, 0x00e5, 0x00e5, 0x00e4, 0x00e4, 0x00e3, 0x00e3,
|
||||
0x00e3, 0x00e2, 0x00e2, 0x00e1, 0x00e1, 0x00e1, 0x00e0, 0x00e0, 0x00e0, 0x00df, 0x00df, 0x00de, 0x00de, 0x00de, 0x00dd, 0x00dd,
|
||||
0x00dd, 0x00dc, 0x00dc, 0x00db, 0x00db, 0x00db, 0x00da, 0x00da, 0x00da, 0x00d9, 0x00d9, 0x00d9, 0x00d8, 0x00d8, 0x00d7, 0x00d7,
|
||||
0x00d7, 0x00d6, 0x00d6, 0x00d6, 0x00d5, 0x00d5, 0x00d5, 0x00d4, 0x00d4, 0x00d4, 0x00d3, 0x00d3, 0x00d3, 0x00d2, 0x00d2, 0x00d2,
|
||||
0x00d1, 0x00d1, 0x00d1, 0x00d0, 0x00d0, 0x00d0, 0x00cf, 0x00cf, 0x00cf, 0x00ce, 0x00ce, 0x00ce, 0x00cd, 0x00cd, 0x00cd, 0x00cc,
|
||||
0x00cc, 0x00cc, 0x00cb, 0x00cb, 0x00cb, 0x00ca, 0x00ca, 0x00ca, 0x00c9, 0x00c9, 0x00c9, 0x00c9, 0x00c8, 0x00c8, 0x00c8, 0x00c7,
|
||||
0x00c7, 0x00c7, 0x00c6, 0x00c6, 0x00c6, 0x00c5, 0x00c5, 0x00c5, 0x00c5, 0x00c4, 0x00c4, 0x00c4, 0x00c3, 0x00c3, 0x00c3, 0x00c3,
|
||||
0x00c2, 0x00c2, 0x00c2, 0x00c1, 0x00c1, 0x00c1, 0x00c1, 0x00c0, 0x00c0, 0x00c0, 0x00bf, 0x00bf, 0x00bf, 0x00bf, 0x00be, 0x00be,
|
||||
0x00be, 0x00bd, 0x00bd, 0x00bd, 0x00bd, 0x00bc, 0x00bc, 0x00bc, 0x00bc, 0x00bb, 0x00bb, 0x00bb, 0x00ba, 0x00ba, 0x00ba, 0x00ba,
|
||||
0x00b9, 0x00b9, 0x00b9, 0x00b9, 0x00b8, 0x00b8, 0x00b8, 0x00b8, 0x00b7, 0x00b7, 0x00b7, 0x00b7, 0x00b6, 0x00b6, 0x00b6, 0x00b6,
|
||||
0x00b5, 0x00b5, 0x00b5, 0x00b5, 0x00b4, 0x00b4, 0x00b4, 0x00b4, 0x00b3, 0x00b3, 0x00b3, 0x00b3, 0x00b2, 0x00b2, 0x00b2, 0x00b2,
|
||||
0x00b1, 0x00b1, 0x00b1, 0x00b1, 0x00b0, 0x00b0, 0x00b0, 0x00b0, 0x00af, 0x00af, 0x00af, 0x00af, 0x00ae, 0x00ae, 0x00ae, 0x00ae,
|
||||
0x00ae, 0x00ad, 0x00ad, 0x00ad, 0x00ad, 0x00ac, 0x00ac, 0x00ac, 0x00ac, 0x00ac, 0x00ab, 0x00ab, 0x00ab, 0x00ab,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static tracy_force_inline uint64_t ProcessRGB( const uint8_t* src )
|
||||
{
|
||||
#ifdef __SSE4_1__
|
||||
__m128i px0 = _mm_loadu_si128(((__m128i*)src) + 0);
|
||||
__m128i px1 = _mm_loadu_si128(((__m128i*)src) + 1);
|
||||
__m128i px2 = _mm_loadu_si128(((__m128i*)src) + 2);
|
||||
__m128i px3 = _mm_loadu_si128(((__m128i*)src) + 3);
|
||||
|
||||
__m128i smask = _mm_set1_epi32( 0xF8FCF8 );
|
||||
__m128i sd0 = _mm_and_si128( px0, smask );
|
||||
__m128i sd1 = _mm_and_si128( px1, smask );
|
||||
__m128i sd2 = _mm_and_si128( px2, smask );
|
||||
__m128i sd3 = _mm_and_si128( px3, smask );
|
||||
|
||||
__m128i sc = _mm_shuffle_epi32(sd0, _MM_SHUFFLE(0, 0, 0, 0));
|
||||
|
||||
__m128i sc0 = _mm_cmpeq_epi8(sd0, sc);
|
||||
__m128i sc1 = _mm_cmpeq_epi8(sd1, sc);
|
||||
__m128i sc2 = _mm_cmpeq_epi8(sd2, sc);
|
||||
__m128i sc3 = _mm_cmpeq_epi8(sd3, sc);
|
||||
|
||||
__m128i sm0 = _mm_and_si128(sc0, sc1);
|
||||
__m128i sm1 = _mm_and_si128(sc2, sc3);
|
||||
__m128i sm = _mm_and_si128(sm0, sm1);
|
||||
|
||||
if( _mm_testc_si128(sm, _mm_set1_epi32(-1)) )
|
||||
{
|
||||
return uint64_t( to565( src[0], src[1], src[2] ) ) << 16;
|
||||
}
|
||||
|
||||
__m128i amask = _mm_set1_epi32( 0xFFFFFF );
|
||||
px0 = _mm_and_si128( px0, amask );
|
||||
px1 = _mm_and_si128( px1, amask );
|
||||
px2 = _mm_and_si128( px2, amask );
|
||||
px3 = _mm_and_si128( px3, amask );
|
||||
|
||||
__m128i min0 = _mm_min_epu8( px0, px1 );
|
||||
__m128i min1 = _mm_min_epu8( px2, px3 );
|
||||
__m128i min2 = _mm_min_epu8( min0, min1 );
|
||||
|
||||
__m128i max0 = _mm_max_epu8( px0, px1 );
|
||||
__m128i max1 = _mm_max_epu8( px2, px3 );
|
||||
__m128i max2 = _mm_max_epu8( max0, max1 );
|
||||
|
||||
__m128i min3 = _mm_shuffle_epi32( min2, _MM_SHUFFLE( 2, 3, 0, 1 ) );
|
||||
__m128i max3 = _mm_shuffle_epi32( max2, _MM_SHUFFLE( 2, 3, 0, 1 ) );
|
||||
__m128i min4 = _mm_min_epu8( min2, min3 );
|
||||
__m128i max4 = _mm_max_epu8( max2, max3 );
|
||||
|
||||
__m128i min5 = _mm_shuffle_epi32( min4, _MM_SHUFFLE( 0, 0, 2, 2 ) );
|
||||
__m128i max5 = _mm_shuffle_epi32( max4, _MM_SHUFFLE( 0, 0, 2, 2 ) );
|
||||
__m128i rmin = _mm_min_epu8( min4, min5 );
|
||||
__m128i rmax = _mm_max_epu8( max4, max5 );
|
||||
|
||||
__m128i range1 = _mm_subs_epu8( rmax, rmin );
|
||||
__m128i range2 = _mm_sad_epu8( rmax, rmin );
|
||||
|
||||
uint32_t vrange = _mm_cvtsi128_si32( range2 ) >> 1;
|
||||
__m128i range = _mm_set1_epi16( DivTable[vrange] );
|
||||
|
||||
__m128i inset1 = _mm_srli_epi16( range1, 4 );
|
||||
__m128i inset = _mm_and_si128( inset1, _mm_set1_epi8( 0xF ) );
|
||||
__m128i min = _mm_adds_epu8( rmin, inset );
|
||||
__m128i max = _mm_subs_epu8( rmax, inset );
|
||||
|
||||
__m128i c0 = _mm_subs_epu8( px0, rmin );
|
||||
__m128i c1 = _mm_subs_epu8( px1, rmin );
|
||||
__m128i c2 = _mm_subs_epu8( px2, rmin );
|
||||
__m128i c3 = _mm_subs_epu8( px3, rmin );
|
||||
|
||||
__m128i is0 = _mm_maddubs_epi16( c0, _mm_set1_epi8( 1 ) );
|
||||
__m128i is1 = _mm_maddubs_epi16( c1, _mm_set1_epi8( 1 ) );
|
||||
__m128i is2 = _mm_maddubs_epi16( c2, _mm_set1_epi8( 1 ) );
|
||||
__m128i is3 = _mm_maddubs_epi16( c3, _mm_set1_epi8( 1 ) );
|
||||
|
||||
__m128i s0 = _mm_hadd_epi16( is0, is1 );
|
||||
__m128i s1 = _mm_hadd_epi16( is2, is3 );
|
||||
|
||||
__m128i m0 = _mm_mulhi_epu16( s0, range );
|
||||
__m128i m1 = _mm_mulhi_epu16( s1, range );
|
||||
|
||||
__m128i p0 = _mm_packus_epi16( m0, m1 );
|
||||
|
||||
__m128i p1 = _mm_or_si128( _mm_srai_epi32( p0, 6 ), _mm_srai_epi32( p0, 12 ) );
|
||||
__m128i p2 = _mm_or_si128( _mm_srai_epi32( p0, 18 ), p0 );
|
||||
__m128i p3 = _mm_or_si128( p1, p2 );
|
||||
__m128i p =_mm_shuffle_epi8( p3, _mm_set1_epi32( 0x0C080400 ) );
|
||||
|
||||
uint32_t vmin = _mm_cvtsi128_si32( min );
|
||||
uint32_t vmax = _mm_cvtsi128_si32( max );
|
||||
uint32_t vp = _mm_cvtsi128_si32( p );
|
||||
|
||||
return uint64_t( ( uint64_t( to565( vmin ) ) << 16 ) | to565( vmax ) | ( uint64_t( vp ) << 32 ) );
|
||||
#elif defined __ARM_NEON
|
||||
# ifdef __aarch64__
|
||||
uint8x16x4_t px = vld4q_u8( src );
|
||||
|
||||
uint8x16_t lr = px.val[0];
|
||||
uint8x16_t lg = px.val[1];
|
||||
uint8x16_t lb = px.val[2];
|
||||
|
||||
uint8_t rmaxr = vmaxvq_u8( lr );
|
||||
uint8_t rmaxg = vmaxvq_u8( lg );
|
||||
uint8_t rmaxb = vmaxvq_u8( lb );
|
||||
|
||||
uint8_t rminr = vminvq_u8( lr );
|
||||
uint8_t rming = vminvq_u8( lg );
|
||||
uint8_t rminb = vminvq_u8( lb );
|
||||
|
||||
int rr = rmaxr - rminr;
|
||||
int rg = rmaxg - rming;
|
||||
int rb = rmaxb - rminb;
|
||||
|
||||
int vrange1 = rr + rg + rb;
|
||||
uint16_t vrange2 = DivTableNEON[vrange1];
|
||||
|
||||
uint8_t insetr = rr >> 4;
|
||||
uint8_t insetg = rg >> 4;
|
||||
uint8_t insetb = rb >> 4;
|
||||
|
||||
uint8_t minr = rminr + insetr;
|
||||
uint8_t ming = rming + insetg;
|
||||
uint8_t minb = rminb + insetb;
|
||||
|
||||
uint8_t maxr = rmaxr - insetr;
|
||||
uint8_t maxg = rmaxg - insetg;
|
||||
uint8_t maxb = rmaxb - insetb;
|
||||
|
||||
uint8x16_t cr = vsubq_u8( lr, vdupq_n_u8( rminr ) );
|
||||
uint8x16_t cg = vsubq_u8( lg, vdupq_n_u8( rming ) );
|
||||
uint8x16_t cb = vsubq_u8( lb, vdupq_n_u8( rminb ) );
|
||||
|
||||
uint16x8_t is0l = vaddl_u8( vget_low_u8( cr ), vget_low_u8( cg ) );
|
||||
uint16x8_t is0h = vaddl_u8( vget_high_u8( cr ), vget_high_u8( cg ) );
|
||||
uint16x8_t is1l = vaddw_u8( is0l, vget_low_u8( cb ) );
|
||||
uint16x8_t is1h = vaddw_u8( is0h, vget_high_u8( cb ) );
|
||||
|
||||
int16x8_t range = vdupq_n_s16( vrange2 );
|
||||
uint16x8_t m0 = vreinterpretq_u16_s16( vqdmulhq_s16( vreinterpretq_s16_u16( is1l ), range ) );
|
||||
uint16x8_t m1 = vreinterpretq_u16_s16( vqdmulhq_s16( vreinterpretq_s16_u16( is1h ), range ) );
|
||||
|
||||
uint8x8_t p00 = vmovn_u16( m0 );
|
||||
uint8x8_t p01 = vmovn_u16( m1 );
|
||||
uint8x16_t p0 = vcombine_u8( p00, p01 );
|
||||
|
||||
uint32x4_t p1 = vaddq_u32( vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 6 ), vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 12 ) );
|
||||
uint32x4_t p2 = vaddq_u32( vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 18 ), vreinterpretq_u32_u8( p0 ) );
|
||||
uint32x4_t p3 = vaddq_u32( p1, p2 );
|
||||
|
||||
uint16x4x2_t p4 = vuzp_u16( vget_low_u16( vreinterpretq_u16_u32( p3 ) ), vget_high_u16( vreinterpretq_u16_u32( p3 ) ) );
|
||||
uint8x8x2_t p = vuzp_u8( vreinterpret_u8_u16( p4.val[0] ), vreinterpret_u8_u16( p4.val[0] ) );
|
||||
|
||||
uint32_t vp;
|
||||
vst1_lane_u32( &vp, vreinterpret_u32_u8( p.val[0] ), 0 );
|
||||
|
||||
return uint64_t( ( uint64_t( to565( minr, ming, minb ) ) << 16 ) | to565( maxr, maxg, maxb ) | ( uint64_t( vp ) << 32 ) );
|
||||
# else
|
||||
uint32x4_t px0 = vld1q_u32( (uint32_t*)src );
|
||||
uint32x4_t px1 = vld1q_u32( (uint32_t*)src + 4 );
|
||||
uint32x4_t px2 = vld1q_u32( (uint32_t*)src + 8 );
|
||||
uint32x4_t px3 = vld1q_u32( (uint32_t*)src + 12 );
|
||||
|
||||
uint32x4_t smask = vdupq_n_u32( 0xF8FCF8 );
|
||||
uint32x4_t sd0 = vandq_u32( smask, px0 );
|
||||
uint32x4_t sd1 = vandq_u32( smask, px1 );
|
||||
uint32x4_t sd2 = vandq_u32( smask, px2 );
|
||||
uint32x4_t sd3 = vandq_u32( smask, px3 );
|
||||
|
||||
uint32x4_t sc = vdupq_n_u32( sd0[0] );
|
||||
|
||||
uint32x4_t sc0 = vceqq_u32( sd0, sc );
|
||||
uint32x4_t sc1 = vceqq_u32( sd1, sc );
|
||||
uint32x4_t sc2 = vceqq_u32( sd2, sc );
|
||||
uint32x4_t sc3 = vceqq_u32( sd3, sc );
|
||||
|
||||
uint32x4_t sm0 = vandq_u32( sc0, sc1 );
|
||||
uint32x4_t sm1 = vandq_u32( sc2, sc3 );
|
||||
int64x2_t sm = vreinterpretq_s64_u32( vandq_u32( sm0, sm1 ) );
|
||||
|
||||
if( sm[0] == -1 && sm[1] == -1 )
|
||||
{
|
||||
return uint64_t( to565( src[0], src[1], src[2] ) ) << 16;
|
||||
}
|
||||
|
||||
uint32x4_t mask = vdupq_n_u32( 0xFFFFFF );
|
||||
uint8x16_t l0 = vreinterpretq_u8_u32( vandq_u32( mask, px0 ) );
|
||||
uint8x16_t l1 = vreinterpretq_u8_u32( vandq_u32( mask, px1 ) );
|
||||
uint8x16_t l2 = vreinterpretq_u8_u32( vandq_u32( mask, px2 ) );
|
||||
uint8x16_t l3 = vreinterpretq_u8_u32( vandq_u32( mask, px3 ) );
|
||||
|
||||
uint8x16_t min0 = vminq_u8( l0, l1 );
|
||||
uint8x16_t min1 = vminq_u8( l2, l3 );
|
||||
uint8x16_t min2 = vminq_u8( min0, min1 );
|
||||
|
||||
uint8x16_t max0 = vmaxq_u8( l0, l1 );
|
||||
uint8x16_t max1 = vmaxq_u8( l2, l3 );
|
||||
uint8x16_t max2 = vmaxq_u8( max0, max1 );
|
||||
|
||||
uint8x16_t min3 = vreinterpretq_u8_u32( vrev64q_u32( vreinterpretq_u32_u8( min2 ) ) );
|
||||
uint8x16_t max3 = vreinterpretq_u8_u32( vrev64q_u32( vreinterpretq_u32_u8( max2 ) ) );
|
||||
|
||||
uint8x16_t min4 = vminq_u8( min2, min3 );
|
||||
uint8x16_t max4 = vmaxq_u8( max2, max3 );
|
||||
|
||||
uint8x16_t min5 = vcombine_u8( vget_high_u8( min4 ), vget_low_u8( min4 ) );
|
||||
uint8x16_t max5 = vcombine_u8( vget_high_u8( max4 ), vget_low_u8( max4 ) );
|
||||
|
||||
uint8x16_t rmin = vminq_u8( min4, min5 );
|
||||
uint8x16_t rmax = vmaxq_u8( max4, max5 );
|
||||
|
||||
uint8x16_t range1 = vsubq_u8( rmax, rmin );
|
||||
uint8x8_t range2 = vget_low_u8( range1 );
|
||||
uint8x8x2_t range3 = vzip_u8( range2, vdup_n_u8( 0 ) );
|
||||
uint16x4_t range4 = vreinterpret_u16_u8( range3.val[0] );
|
||||
|
||||
uint16_t vrange1;
|
||||
uint16x4_t range5 = vpadd_u16( range4, range4 );
|
||||
uint16x4_t range6 = vpadd_u16( range5, range5 );
|
||||
vst1_lane_u16( &vrange1, range6, 0 );
|
||||
|
||||
uint32_t vrange2 = ( 2 << 16 ) / uint32_t( vrange1 + 1 );
|
||||
uint16x8_t range = vdupq_n_u16( vrange2 );
|
||||
|
||||
uint8x16_t inset = vshrq_n_u8( range1, 4 );
|
||||
uint8x16_t min = vaddq_u8( rmin, inset );
|
||||
uint8x16_t max = vsubq_u8( rmax, inset );
|
||||
|
||||
uint8x16_t c0 = vsubq_u8( l0, rmin );
|
||||
uint8x16_t c1 = vsubq_u8( l1, rmin );
|
||||
uint8x16_t c2 = vsubq_u8( l2, rmin );
|
||||
uint8x16_t c3 = vsubq_u8( l3, rmin );
|
||||
|
||||
uint16x8_t is0 = vpaddlq_u8( c0 );
|
||||
uint16x8_t is1 = vpaddlq_u8( c1 );
|
||||
uint16x8_t is2 = vpaddlq_u8( c2 );
|
||||
uint16x8_t is3 = vpaddlq_u8( c3 );
|
||||
|
||||
uint16x4_t is4 = vpadd_u16( vget_low_u16( is0 ), vget_high_u16( is0 ) );
|
||||
uint16x4_t is5 = vpadd_u16( vget_low_u16( is1 ), vget_high_u16( is1 ) );
|
||||
uint16x4_t is6 = vpadd_u16( vget_low_u16( is2 ), vget_high_u16( is2 ) );
|
||||
uint16x4_t is7 = vpadd_u16( vget_low_u16( is3 ), vget_high_u16( is3 ) );
|
||||
|
||||
uint16x8_t s0 = vcombine_u16( is4, is5 );
|
||||
uint16x8_t s1 = vcombine_u16( is6, is7 );
|
||||
|
||||
uint16x8_t m0 = vreinterpretq_u16_s16( vqdmulhq_s16( vreinterpretq_s16_u16( s0 ), vreinterpretq_s16_u16( range ) ) );
|
||||
uint16x8_t m1 = vreinterpretq_u16_s16( vqdmulhq_s16( vreinterpretq_s16_u16( s1 ), vreinterpretq_s16_u16( range ) ) );
|
||||
|
||||
uint8x8_t p00 = vmovn_u16( m0 );
|
||||
uint8x8_t p01 = vmovn_u16( m1 );
|
||||
uint8x16_t p0 = vcombine_u8( p00, p01 );
|
||||
|
||||
uint32x4_t p1 = vaddq_u32( vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 6 ), vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 12 ) );
|
||||
uint32x4_t p2 = vaddq_u32( vshrq_n_u32( vreinterpretq_u32_u8( p0 ), 18 ), vreinterpretq_u32_u8( p0 ) );
|
||||
uint32x4_t p3 = vaddq_u32( p1, p2 );
|
||||
|
||||
uint16x4x2_t p4 = vuzp_u16( vget_low_u16( vreinterpretq_u16_u32( p3 ) ), vget_high_u16( vreinterpretq_u16_u32( p3 ) ) );
|
||||
uint8x8x2_t p = vuzp_u8( vreinterpret_u8_u16( p4.val[0] ), vreinterpret_u8_u16( p4.val[0] ) );
|
||||
|
||||
uint32_t vmin, vmax, vp;
|
||||
vst1q_lane_u32( &vmin, vreinterpretq_u32_u8( min ), 0 );
|
||||
vst1q_lane_u32( &vmax, vreinterpretq_u32_u8( max ), 0 );
|
||||
vst1_lane_u32( &vp, vreinterpret_u32_u8( p.val[0] ), 0 );
|
||||
|
||||
return uint64_t( ( uint64_t( to565( vmin ) ) << 16 ) | to565( vmax ) | ( uint64_t( vp ) << 32 ) );
|
||||
# endif
|
||||
#else
|
||||
uint32_t ref;
|
||||
memcpy( &ref, src, 4 );
|
||||
uint32_t refMask = ref & 0xF8FCF8;
|
||||
auto stmp = src + 4;
|
||||
for( int i=1; i<16; i++ )
|
||||
{
|
||||
uint32_t px;
|
||||
memcpy( &px, stmp, 4 );
|
||||
if( ( px & 0xF8FCF8 ) != refMask ) break;
|
||||
stmp += 4;
|
||||
}
|
||||
if( stmp == src + 64 )
|
||||
{
|
||||
return uint64_t( to565( ref ) ) << 16;
|
||||
}
|
||||
|
||||
uint8_t min[3] = { src[0], src[1], src[2] };
|
||||
uint8_t max[3] = { src[0], src[1], src[2] };
|
||||
auto tmp = src + 4;
|
||||
for( int i=1; i<16; i++ )
|
||||
{
|
||||
for( int j=0; j<3; j++ )
|
||||
{
|
||||
if( tmp[j] < min[j] ) min[j] = tmp[j];
|
||||
else if( tmp[j] > max[j] ) max[j] = tmp[j];
|
||||
}
|
||||
tmp += 4;
|
||||
}
|
||||
|
||||
const uint32_t range = DivTable[max[0] - min[0] + max[1] - min[1] + max[2] - min[2]];
|
||||
const uint32_t rmin = min[0] + min[1] + min[2];
|
||||
for( int i=0; i<3; i++ )
|
||||
{
|
||||
const uint8_t inset = ( max[i] - min[i] ) >> 4;
|
||||
min[i] += inset;
|
||||
max[i] -= inset;
|
||||
}
|
||||
|
||||
uint32_t data = 0;
|
||||
for( int i=0; i<16; i++ )
|
||||
{
|
||||
const uint32_t c = src[0] + src[1] + src[2] - rmin;
|
||||
const uint8_t idx = ( c * range ) >> 16;
|
||||
data |= idx << (i*2);
|
||||
src += 4;
|
||||
}
|
||||
|
||||
return uint64_t( ( uint64_t( to565( min[0], min[1], min[2] ) ) << 16 ) | to565( max[0], max[1], max[2] ) | ( uint64_t( data ) << 32 ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __AVX2__
|
||||
static tracy_force_inline void ProcessRGB_AVX( const uint8_t* src, char*& dst )
|
||||
{
|
||||
__m256i px0 = _mm256_loadu_si256(((__m256i*)src) + 0);
|
||||
__m256i px1 = _mm256_loadu_si256(((__m256i*)src) + 1);
|
||||
__m256i px2 = _mm256_loadu_si256(((__m256i*)src) + 2);
|
||||
__m256i px3 = _mm256_loadu_si256(((__m256i*)src) + 3);
|
||||
|
||||
__m256i smask = _mm256_set1_epi32( 0xF8FCF8 );
|
||||
__m256i sd0 = _mm256_and_si256( px0, smask );
|
||||
__m256i sd1 = _mm256_and_si256( px1, smask );
|
||||
__m256i sd2 = _mm256_and_si256( px2, smask );
|
||||
__m256i sd3 = _mm256_and_si256( px3, smask );
|
||||
|
||||
__m256i sc = _mm256_shuffle_epi32(sd0, _MM_SHUFFLE(0, 0, 0, 0));
|
||||
|
||||
__m256i sc0 = _mm256_cmpeq_epi8( sd0, sc );
|
||||
__m256i sc1 = _mm256_cmpeq_epi8( sd1, sc );
|
||||
__m256i sc2 = _mm256_cmpeq_epi8( sd2, sc );
|
||||
__m256i sc3 = _mm256_cmpeq_epi8( sd3, sc );
|
||||
|
||||
__m256i sm0 = _mm256_and_si256( sc0, sc1 );
|
||||
__m256i sm1 = _mm256_and_si256( sc2, sc3 );
|
||||
__m256i sm = _mm256_and_si256( sm0, sm1 );
|
||||
|
||||
const int64_t solid0 = 1 - _mm_testc_si128( _mm256_castsi256_si128( sm ), _mm_set1_epi32( -1 ) );
|
||||
const int64_t solid1 = 1 - _mm_testc_si128( _mm256_extracti128_si256( sm, 1 ), _mm_set1_epi32( -1 ) );
|
||||
|
||||
if( solid0 + solid1 == 0 )
|
||||
{
|
||||
const auto c0 = uint64_t( to565( src[0], src[1], src[2] ) ) << 16;
|
||||
const auto c1 = uint64_t( to565( src[16], src[17], src[18] ) ) << 16;
|
||||
memcpy( dst, &c0, 8 );
|
||||
memcpy( dst+8, &c1, 8 );
|
||||
dst += 16;
|
||||
return;
|
||||
}
|
||||
|
||||
__m256i amask = _mm256_set1_epi32( 0xFFFFFF );
|
||||
px0 = _mm256_and_si256( px0, amask );
|
||||
px1 = _mm256_and_si256( px1, amask );
|
||||
px2 = _mm256_and_si256( px2, amask );
|
||||
px3 = _mm256_and_si256( px3, amask );
|
||||
|
||||
__m256i min0 = _mm256_min_epu8( px0, px1 );
|
||||
__m256i min1 = _mm256_min_epu8( px2, px3 );
|
||||
__m256i min2 = _mm256_min_epu8( min0, min1 );
|
||||
|
||||
__m256i max0 = _mm256_max_epu8( px0, px1 );
|
||||
__m256i max1 = _mm256_max_epu8( px2, px3 );
|
||||
__m256i max2 = _mm256_max_epu8( max0, max1 );
|
||||
|
||||
__m256i min3 = _mm256_shuffle_epi32( min2, _MM_SHUFFLE( 2, 3, 0, 1 ) );
|
||||
__m256i max3 = _mm256_shuffle_epi32( max2, _MM_SHUFFLE( 2, 3, 0, 1 ) );
|
||||
__m256i min4 = _mm256_min_epu8( min2, min3 );
|
||||
__m256i max4 = _mm256_max_epu8( max2, max3 );
|
||||
|
||||
__m256i min5 = _mm256_shuffle_epi32( min4, _MM_SHUFFLE( 0, 0, 2, 2 ) );
|
||||
__m256i max5 = _mm256_shuffle_epi32( max4, _MM_SHUFFLE( 0, 0, 2, 2 ) );
|
||||
__m256i rmin = _mm256_min_epu8( min4, min5 );
|
||||
__m256i rmax = _mm256_max_epu8( max4, max5 );
|
||||
|
||||
__m256i range1 = _mm256_subs_epu8( rmax, rmin );
|
||||
__m256i range2 = _mm256_sad_epu8( rmax, rmin );
|
||||
|
||||
uint16_t vrange0 = DivTable[_mm256_cvtsi256_si32( range2 ) >> 1];
|
||||
uint16_t vrange1 = DivTable[_mm256_extract_epi16( range2, 8 ) >> 1];
|
||||
__m256i range00 = _mm256_set1_epi16( vrange0 );
|
||||
__m256i range = _mm256_inserti128_si256( range00, _mm_set1_epi16( vrange1 ), 1 );
|
||||
|
||||
__m256i inset1 = _mm256_srli_epi16( range1, 4 );
|
||||
__m256i inset = _mm256_and_si256( inset1, _mm256_set1_epi8( 0xF ) );
|
||||
__m256i min = _mm256_adds_epu8( rmin, inset );
|
||||
__m256i max = _mm256_subs_epu8( rmax, inset );
|
||||
|
||||
__m256i c0 = _mm256_subs_epu8( px0, rmin );
|
||||
__m256i c1 = _mm256_subs_epu8( px1, rmin );
|
||||
__m256i c2 = _mm256_subs_epu8( px2, rmin );
|
||||
__m256i c3 = _mm256_subs_epu8( px3, rmin );
|
||||
|
||||
__m256i is0 = _mm256_maddubs_epi16( c0, _mm256_set1_epi8( 1 ) );
|
||||
__m256i is1 = _mm256_maddubs_epi16( c1, _mm256_set1_epi8( 1 ) );
|
||||
__m256i is2 = _mm256_maddubs_epi16( c2, _mm256_set1_epi8( 1 ) );
|
||||
__m256i is3 = _mm256_maddubs_epi16( c3, _mm256_set1_epi8( 1 ) );
|
||||
|
||||
__m256i s0 = _mm256_hadd_epi16( is0, is1 );
|
||||
__m256i s1 = _mm256_hadd_epi16( is2, is3 );
|
||||
|
||||
__m256i m0 = _mm256_mulhi_epu16( s0, range );
|
||||
__m256i m1 = _mm256_mulhi_epu16( s1, range );
|
||||
|
||||
__m256i p0 = _mm256_packus_epi16( m0, m1 );
|
||||
|
||||
__m256i p1 = _mm256_or_si256( _mm256_srai_epi32( p0, 6 ), _mm256_srai_epi32( p0, 12 ) );
|
||||
__m256i p2 = _mm256_or_si256( _mm256_srai_epi32( p0, 18 ), p0 );
|
||||
__m256i p3 = _mm256_or_si256( p1, p2 );
|
||||
__m256i p =_mm256_shuffle_epi8( p3, _mm256_set1_epi32( 0x0C080400 ) );
|
||||
|
||||
__m256i mm0 = _mm256_unpacklo_epi8( _mm256_setzero_si256(), min );
|
||||
__m256i mm1 = _mm256_unpacklo_epi8( _mm256_setzero_si256(), max );
|
||||
__m256i mm2 = _mm256_unpacklo_epi64( mm1, mm0 );
|
||||
__m256i mmr = _mm256_slli_epi64( _mm256_srli_epi64( mm2, 11 ), 11 );
|
||||
__m256i mmg = _mm256_slli_epi64( _mm256_srli_epi64( mm2, 26 ), 5 );
|
||||
__m256i mmb = _mm256_srli_epi64( _mm256_slli_epi64( mm2, 16 ), 59 );
|
||||
__m256i mm3 = _mm256_or_si256( mmr, mmg );
|
||||
__m256i mm4 = _mm256_or_si256( mm3, mmb );
|
||||
__m256i mm5 = _mm256_shuffle_epi8( mm4, _mm256_set1_epi32( 0x09080100 ) );
|
||||
|
||||
__m256i d0 = _mm256_unpacklo_epi32( mm5, p );
|
||||
__m256i d1 = _mm256_permute4x64_epi64( d0, _MM_SHUFFLE( 3, 2, 2, 0 ) );
|
||||
__m128i d2 = _mm256_castsi256_si128( d1 );
|
||||
|
||||
__m128i mask = _mm_set_epi64x( 0xFFFF0000 | -solid1, 0xFFFF0000 | -solid0 );
|
||||
__m128i d3 = _mm_and_si128( d2, mask );
|
||||
_mm_storeu_si128( (__m128i*)dst, d3 );
|
||||
dst += 16;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CompressImageDxt1( const char* src, char* dst, int w, int h )
|
||||
{
|
||||
assert( (w % 4) == 0 && (h % 4) == 0 );
|
||||
|
||||
#ifdef __AVX2__
|
||||
if( w%8 == 0 )
|
||||
{
|
||||
uint32_t buf[8*4];
|
||||
int i = 0;
|
||||
|
||||
auto blocks = w * h / 32;
|
||||
do
|
||||
{
|
||||
auto tmp = (char*)buf;
|
||||
memcpy( tmp, src, 8*4 );
|
||||
memcpy( tmp + 8*4, src + w * 4, 8*4 );
|
||||
memcpy( tmp + 16*4, src + w * 8, 8*4 );
|
||||
memcpy( tmp + 24*4, src + w * 12, 8*4 );
|
||||
src += 8*4;
|
||||
if( ++i == w/8 )
|
||||
{
|
||||
src += w * 3 * 4;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
ProcessRGB_AVX( (uint8_t*)buf, dst );
|
||||
}
|
||||
while( --blocks );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
uint32_t buf[4*4];
|
||||
int i = 0;
|
||||
|
||||
auto ptr = dst;
|
||||
auto blocks = w * h / 16;
|
||||
do
|
||||
{
|
||||
auto tmp = (char*)buf;
|
||||
memcpy( tmp, src, 4*4 );
|
||||
memcpy( tmp + 4*4, src + w * 4, 4*4 );
|
||||
memcpy( tmp + 8*4, src + w * 8, 4*4 );
|
||||
memcpy( tmp + 12*4, src + w * 12, 4*4 );
|
||||
src += 4*4;
|
||||
if( ++i == w/4 )
|
||||
{
|
||||
src += w * 3 * 4;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
const auto c = ProcessRGB( (uint8_t*)buf );
|
||||
memcpy( ptr, &c, sizeof( uint64_t ) );
|
||||
ptr += sizeof( uint64_t );
|
||||
}
|
||||
while( --blocks );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
11
oss/tracy/client/TracyDxt1.hpp
Normal file
11
oss/tracy/client/TracyDxt1.hpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef __TRACYDXT1_HPP__
|
||||
#define __TRACYDXT1_HPP__
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
void CompressImageDxt1( const char* src, char* dst, int w, int h );
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
118
oss/tracy/client/TracyFastVector.hpp
Normal file
118
oss/tracy/client/TracyFastVector.hpp
Normal file
@@ -0,0 +1,118 @@
|
||||
#ifndef __TRACYFASTVECTOR_HPP__
|
||||
#define __TRACYFASTVECTOR_HPP__
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../common/TracyAlloc.hpp"
|
||||
#include "../common/TracyForceInline.hpp"
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
class FastVector
|
||||
{
|
||||
public:
|
||||
using iterator = T*;
|
||||
using const_iterator = const T*;
|
||||
|
||||
FastVector( size_t capacity )
|
||||
: m_ptr( (T*)tracy_malloc( sizeof( T ) * capacity ) )
|
||||
, m_write( m_ptr )
|
||||
, m_end( m_ptr + capacity )
|
||||
{
|
||||
assert( capacity != 0 );
|
||||
}
|
||||
|
||||
FastVector( const FastVector& ) = delete;
|
||||
FastVector( FastVector&& ) = delete;
|
||||
|
||||
~FastVector()
|
||||
{
|
||||
tracy_free( m_ptr );
|
||||
}
|
||||
|
||||
FastVector& operator=( const FastVector& ) = delete;
|
||||
FastVector& operator=( FastVector&& ) = delete;
|
||||
|
||||
bool empty() const { return m_ptr == m_write; }
|
||||
size_t size() const { return m_write - m_ptr; }
|
||||
|
||||
T* data() { return m_ptr; }
|
||||
const T* data() const { return m_ptr; };
|
||||
|
||||
T* begin() { return m_ptr; }
|
||||
const T* begin() const { return m_ptr; }
|
||||
T* end() { return m_write; }
|
||||
const T* end() const { return m_write; }
|
||||
|
||||
T& front() { assert( !empty() ); return m_ptr[0]; }
|
||||
const T& front() const { assert( !empty() ); return m_ptr[0]; }
|
||||
|
||||
T& back() { assert( !empty() ); return m_write[-1]; }
|
||||
const T& back() const { assert( !empty() ); return m_write[-1]; }
|
||||
|
||||
T& operator[]( size_t idx ) { return m_ptr[idx]; }
|
||||
const T& operator[]( size_t idx ) const { return m_ptr[idx]; }
|
||||
|
||||
T* push_next()
|
||||
{
|
||||
if( m_write == m_end ) AllocMore();
|
||||
return m_write++;
|
||||
}
|
||||
|
||||
T* prepare_next()
|
||||
{
|
||||
if( m_write == m_end ) AllocMore();
|
||||
return m_write;
|
||||
}
|
||||
|
||||
void commit_next()
|
||||
{
|
||||
m_write++;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_write = m_ptr;
|
||||
}
|
||||
|
||||
void swap( FastVector& vec )
|
||||
{
|
||||
const auto ptr1 = m_ptr;
|
||||
const auto ptr2 = vec.m_ptr;
|
||||
const auto write1 = m_write;
|
||||
const auto write2 = vec.m_write;
|
||||
const auto end1 = m_end;
|
||||
const auto end2 = vec.m_end;
|
||||
|
||||
m_ptr = ptr2;
|
||||
vec.m_ptr = ptr1;
|
||||
m_write = write2;
|
||||
vec.m_write = write1;
|
||||
m_end = end2;
|
||||
vec.m_end = end1;
|
||||
}
|
||||
|
||||
private:
|
||||
tracy_no_inline void AllocMore()
|
||||
{
|
||||
const auto cap = size_t( m_end - m_ptr ) * 2;
|
||||
const auto size = size_t( m_write - m_ptr );
|
||||
T* ptr = (T*)tracy_malloc( sizeof( T ) * cap );
|
||||
memcpy( ptr, m_ptr, size * sizeof( T ) );
|
||||
tracy_free_fast( m_ptr );
|
||||
m_ptr = ptr;
|
||||
m_write = m_ptr + size;
|
||||
m_end = m_ptr + cap;
|
||||
}
|
||||
|
||||
T* m_ptr;
|
||||
T* m_write;
|
||||
T* m_end;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
546
oss/tracy/client/TracyLock.hpp
Normal file
546
oss/tracy/client/TracyLock.hpp
Normal file
@@ -0,0 +1,546 @@
|
||||
#ifndef __TRACYLOCK_HPP__
|
||||
#define __TRACYLOCK_HPP__
|
||||
|
||||
#include <atomic>
|
||||
#include <limits>
|
||||
|
||||
#include "../common/TracySystem.hpp"
|
||||
#include "../common/TracyAlign.hpp"
|
||||
#include "TracyProfiler.hpp"
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
class LockableCtx
|
||||
{
|
||||
public:
|
||||
tracy_force_inline LockableCtx( const SourceLocationData* srcloc )
|
||||
: m_id( GetLockCounter().fetch_add( 1, std::memory_order_relaxed ) )
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
, m_lockCount( 0 )
|
||||
, m_active( false )
|
||||
#endif
|
||||
{
|
||||
assert( m_id != std::numeric_limits<uint32_t>::max() );
|
||||
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockAnnounce );
|
||||
MemWrite( &item->lockAnnounce.id, m_id );
|
||||
MemWrite( &item->lockAnnounce.time, Profiler::GetTime() );
|
||||
MemWrite( &item->lockAnnounce.lckloc, (uint64_t)srcloc );
|
||||
MemWrite( &item->lockAnnounce.type, LockType::Lockable );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
LockableCtx( const LockableCtx& ) = delete;
|
||||
LockableCtx& operator=( const LockableCtx& ) = delete;
|
||||
|
||||
tracy_force_inline ~LockableCtx()
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockTerminate );
|
||||
MemWrite( &item->lockTerminate.id, m_id );
|
||||
MemWrite( &item->lockTerminate.time, Profiler::GetTime() );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline bool BeforeLock()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
bool queue = false;
|
||||
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||
const auto active = m_active.load( std::memory_order_relaxed );
|
||||
if( locks == 0 || active )
|
||||
{
|
||||
const bool connected = GetProfiler().IsConnected();
|
||||
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue ) return false;
|
||||
#endif
|
||||
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockWait );
|
||||
MemWrite( &item->lockWait.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockWait.id, m_id );
|
||||
MemWrite( &item->lockWait.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
return true;
|
||||
}
|
||||
|
||||
tracy_force_inline void AfterLock()
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockObtain.id, m_id );
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline void AfterUnlock()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
m_lockCount.fetch_sub( 1, std::memory_order_relaxed );
|
||||
if( !m_active.load( std::memory_order_relaxed ) ) return;
|
||||
if( !GetProfiler().IsConnected() )
|
||||
{
|
||||
m_active.store( false, std::memory_order_relaxed );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockRelease );
|
||||
MemWrite( &item->lockRelease.id, m_id );
|
||||
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline void AfterTryLock( bool acquired )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !acquired ) return;
|
||||
|
||||
bool queue = false;
|
||||
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||
const auto active = m_active.load( std::memory_order_relaxed );
|
||||
if( locks == 0 || active )
|
||||
{
|
||||
const bool connected = GetProfiler().IsConnected();
|
||||
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue ) return;
|
||||
#endif
|
||||
|
||||
if( acquired )
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockObtain.id, m_id );
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
}
|
||||
|
||||
tracy_force_inline void Mark( const SourceLocationData* srcloc )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
const auto active = m_active.load( std::memory_order_relaxed );
|
||||
if( !active ) return;
|
||||
const auto connected = GetProfiler().IsConnected();
|
||||
if( !connected )
|
||||
{
|
||||
if( active ) m_active.store( false, std::memory_order_relaxed );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockMark );
|
||||
MemWrite( &item->lockMark.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockMark.id, m_id );
|
||||
MemWrite( &item->lockMark.srcloc, (uint64_t)srcloc );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline void CustomName( const char* name, size_t size )
|
||||
{
|
||||
assert( size < std::numeric_limits<uint16_t>::max() );
|
||||
auto ptr = (char*)tracy_malloc( size );
|
||||
memcpy( ptr, name, size );
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockName );
|
||||
MemWrite( &item->lockNameFat.id, m_id );
|
||||
MemWrite( &item->lockNameFat.name, (uint64_t)ptr );
|
||||
MemWrite( &item->lockNameFat.size, (uint16_t)size );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t m_id;
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
std::atomic<uint32_t> m_lockCount;
|
||||
std::atomic<bool> m_active;
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class Lockable
|
||||
{
|
||||
public:
|
||||
tracy_force_inline Lockable( const SourceLocationData* srcloc )
|
||||
: m_ctx( srcloc )
|
||||
{
|
||||
}
|
||||
|
||||
Lockable( const Lockable& ) = delete;
|
||||
Lockable& operator=( const Lockable& ) = delete;
|
||||
|
||||
tracy_force_inline void lock()
|
||||
{
|
||||
const auto runAfter = m_ctx.BeforeLock();
|
||||
m_lockable.lock();
|
||||
if( runAfter ) m_ctx.AfterLock();
|
||||
}
|
||||
|
||||
tracy_force_inline void unlock()
|
||||
{
|
||||
m_lockable.unlock();
|
||||
m_ctx.AfterUnlock();
|
||||
}
|
||||
|
||||
tracy_force_inline bool try_lock()
|
||||
{
|
||||
const auto acquired = m_lockable.try_lock();
|
||||
m_ctx.AfterTryLock( acquired );
|
||||
return acquired;
|
||||
}
|
||||
|
||||
tracy_force_inline void Mark( const SourceLocationData* srcloc )
|
||||
{
|
||||
m_ctx.Mark( srcloc );
|
||||
}
|
||||
|
||||
tracy_force_inline void CustomName( const char* name, size_t size )
|
||||
{
|
||||
m_ctx.CustomName( name, size );
|
||||
}
|
||||
|
||||
private:
|
||||
T m_lockable;
|
||||
LockableCtx m_ctx;
|
||||
};
|
||||
|
||||
|
||||
class SharedLockableCtx
|
||||
{
|
||||
public:
|
||||
tracy_force_inline SharedLockableCtx( const SourceLocationData* srcloc )
|
||||
: m_id( GetLockCounter().fetch_add( 1, std::memory_order_relaxed ) )
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
, m_lockCount( 0 )
|
||||
, m_active( false )
|
||||
#endif
|
||||
{
|
||||
assert( m_id != std::numeric_limits<uint32_t>::max() );
|
||||
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockAnnounce );
|
||||
MemWrite( &item->lockAnnounce.id, m_id );
|
||||
MemWrite( &item->lockAnnounce.time, Profiler::GetTime() );
|
||||
MemWrite( &item->lockAnnounce.lckloc, (uint64_t)srcloc );
|
||||
MemWrite( &item->lockAnnounce.type, LockType::SharedLockable );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
SharedLockableCtx( const SharedLockableCtx& ) = delete;
|
||||
SharedLockableCtx& operator=( const SharedLockableCtx& ) = delete;
|
||||
|
||||
tracy_force_inline ~SharedLockableCtx()
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockTerminate );
|
||||
MemWrite( &item->lockTerminate.id, m_id );
|
||||
MemWrite( &item->lockTerminate.time, Profiler::GetTime() );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline bool BeforeLock()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
bool queue = false;
|
||||
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||
const auto active = m_active.load( std::memory_order_relaxed );
|
||||
if( locks == 0 || active )
|
||||
{
|
||||
const bool connected = GetProfiler().IsConnected();
|
||||
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue ) return false;
|
||||
#endif
|
||||
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockWait );
|
||||
MemWrite( &item->lockWait.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockWait.id, m_id );
|
||||
MemWrite( &item->lockWait.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
return true;
|
||||
}
|
||||
|
||||
tracy_force_inline void AfterLock()
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockObtain.id, m_id );
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline void AfterUnlock()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
m_lockCount.fetch_sub( 1, std::memory_order_relaxed );
|
||||
if( !m_active.load( std::memory_order_relaxed ) ) return;
|
||||
if( !GetProfiler().IsConnected() )
|
||||
{
|
||||
m_active.store( false, std::memory_order_relaxed );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockRelease );
|
||||
MemWrite( &item->lockRelease.id, m_id );
|
||||
MemWrite( &item->lockRelease.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline void AfterTryLock( bool acquired )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !acquired ) return;
|
||||
|
||||
bool queue = false;
|
||||
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||
const auto active = m_active.load( std::memory_order_relaxed );
|
||||
if( locks == 0 || active )
|
||||
{
|
||||
const bool connected = GetProfiler().IsConnected();
|
||||
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue ) return;
|
||||
#endif
|
||||
|
||||
if( acquired )
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockObtain );
|
||||
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockObtain.id, m_id );
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
}
|
||||
|
||||
tracy_force_inline bool BeforeLockShared()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
bool queue = false;
|
||||
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||
const auto active = m_active.load( std::memory_order_relaxed );
|
||||
if( locks == 0 || active )
|
||||
{
|
||||
const bool connected = GetProfiler().IsConnected();
|
||||
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue ) return false;
|
||||
#endif
|
||||
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockSharedWait );
|
||||
MemWrite( &item->lockWait.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockWait.id, m_id );
|
||||
MemWrite( &item->lockWait.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
return true;
|
||||
}
|
||||
|
||||
tracy_force_inline void AfterLockShared()
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockSharedObtain );
|
||||
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockObtain.id, m_id );
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline void AfterUnlockShared()
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
m_lockCount.fetch_sub( 1, std::memory_order_relaxed );
|
||||
if( !m_active.load( std::memory_order_relaxed ) ) return;
|
||||
if( !GetProfiler().IsConnected() )
|
||||
{
|
||||
m_active.store( false, std::memory_order_relaxed );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockSharedRelease );
|
||||
MemWrite( &item->lockReleaseShared.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockReleaseShared.id, m_id );
|
||||
MemWrite( &item->lockReleaseShared.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline void AfterTryLockShared( bool acquired )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !acquired ) return;
|
||||
|
||||
bool queue = false;
|
||||
const auto locks = m_lockCount.fetch_add( 1, std::memory_order_relaxed );
|
||||
const auto active = m_active.load( std::memory_order_relaxed );
|
||||
if( locks == 0 || active )
|
||||
{
|
||||
const bool connected = GetProfiler().IsConnected();
|
||||
if( active != connected ) m_active.store( connected, std::memory_order_relaxed );
|
||||
if( connected ) queue = true;
|
||||
}
|
||||
if( !queue ) return;
|
||||
#endif
|
||||
|
||||
if( acquired )
|
||||
{
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockSharedObtain );
|
||||
MemWrite( &item->lockObtain.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockObtain.id, m_id );
|
||||
MemWrite( &item->lockObtain.time, Profiler::GetTime() );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
}
|
||||
|
||||
tracy_force_inline void Mark( const SourceLocationData* srcloc )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
const auto active = m_active.load( std::memory_order_relaxed );
|
||||
if( !active ) return;
|
||||
const auto connected = GetProfiler().IsConnected();
|
||||
if( !connected )
|
||||
{
|
||||
if( active ) m_active.store( false, std::memory_order_relaxed );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockMark );
|
||||
MemWrite( &item->lockMark.thread, GetThreadHandle() );
|
||||
MemWrite( &item->lockMark.id, m_id );
|
||||
MemWrite( &item->lockMark.srcloc, (uint64_t)srcloc );
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
tracy_force_inline void CustomName( const char* name, size_t size )
|
||||
{
|
||||
assert( size < std::numeric_limits<uint16_t>::max() );
|
||||
auto ptr = (char*)tracy_malloc( size );
|
||||
memcpy( ptr, name, size );
|
||||
auto item = Profiler::QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::LockName );
|
||||
MemWrite( &item->lockNameFat.id, m_id );
|
||||
MemWrite( &item->lockNameFat.name, (uint64_t)ptr );
|
||||
MemWrite( &item->lockNameFat.size, (uint16_t)size );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
Profiler::QueueSerialFinish();
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t m_id;
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
std::atomic<uint32_t> m_lockCount;
|
||||
std::atomic<bool> m_active;
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class SharedLockable
|
||||
{
|
||||
public:
|
||||
tracy_force_inline SharedLockable( const SourceLocationData* srcloc )
|
||||
: m_ctx( srcloc )
|
||||
{
|
||||
}
|
||||
|
||||
SharedLockable( const SharedLockable& ) = delete;
|
||||
SharedLockable& operator=( const SharedLockable& ) = delete;
|
||||
|
||||
tracy_force_inline void lock()
|
||||
{
|
||||
const auto runAfter = m_ctx.BeforeLock();
|
||||
m_lockable.lock();
|
||||
if( runAfter ) m_ctx.AfterLock();
|
||||
}
|
||||
|
||||
tracy_force_inline void unlock()
|
||||
{
|
||||
m_lockable.unlock();
|
||||
m_ctx.AfterUnlock();
|
||||
}
|
||||
|
||||
tracy_force_inline bool try_lock()
|
||||
{
|
||||
const auto acquired = m_lockable.try_lock();
|
||||
m_ctx.AfterTryLock( acquired );
|
||||
return acquired;
|
||||
}
|
||||
|
||||
tracy_force_inline void lock_shared()
|
||||
{
|
||||
const auto runAfter = m_ctx.BeforeLockShared();
|
||||
m_lockable.lock_shared();
|
||||
if( runAfter ) m_ctx.AfterLockShared();
|
||||
}
|
||||
|
||||
tracy_force_inline void unlock_shared()
|
||||
{
|
||||
m_lockable.unlock_shared();
|
||||
m_ctx.AfterUnlockShared();
|
||||
}
|
||||
|
||||
tracy_force_inline bool try_lock_shared()
|
||||
{
|
||||
const auto acquired = m_lockable.try_lock_shared();
|
||||
m_ctx.AfterTryLockShared( acquired );
|
||||
return acquired;
|
||||
}
|
||||
|
||||
tracy_force_inline void Mark( const SourceLocationData* srcloc )
|
||||
{
|
||||
m_ctx.Mark( srcloc );
|
||||
}
|
||||
|
||||
tracy_force_inline void CustomName( const char* name, size_t size )
|
||||
{
|
||||
m_ctx.CustomName( name, size );
|
||||
}
|
||||
|
||||
private:
|
||||
T m_lockable;
|
||||
SharedLockableCtx m_ctx;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
26
oss/tracy/client/TracyOverride.cpp
Normal file
26
oss/tracy/client/TracyOverride.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifdef TRACY_ENABLE
|
||||
# ifdef __linux__
|
||||
# include "TracyDebug.hpp"
|
||||
# ifdef TRACY_VERBOSE
|
||||
# include <dlfcn.h>
|
||||
# include <link.h>
|
||||
# endif
|
||||
|
||||
extern "C" int dlclose( void* hnd )
|
||||
{
|
||||
#ifdef TRACY_VERBOSE
|
||||
struct link_map* lm;
|
||||
if( dlinfo( hnd, RTLD_DI_LINKMAP, &lm ) == 0 )
|
||||
{
|
||||
TracyDebug( "Overriding dlclose for %s\n", lm->l_name );
|
||||
}
|
||||
else
|
||||
{
|
||||
TracyDebug( "Overriding dlclose for unknown object (%s)\n", dlerror() );
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
# endif
|
||||
#endif
|
||||
4399
oss/tracy/client/TracyProfiler.cpp
Normal file
4399
oss/tracy/client/TracyProfiler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
966
oss/tracy/client/TracyProfiler.hpp
Normal file
966
oss/tracy/client/TracyProfiler.hpp
Normal file
@@ -0,0 +1,966 @@
|
||||
#ifndef __TRACYPROFILER_HPP__
|
||||
#define __TRACYPROFILER_HPP__
|
||||
|
||||
#include <assert.h>
|
||||
#include <atomic>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "tracy_concurrentqueue.h"
|
||||
#include "tracy_SPSCQueue.h"
|
||||
#include "TracyCallstack.hpp"
|
||||
#include "TracySysTime.hpp"
|
||||
#include "TracyFastVector.hpp"
|
||||
#include "../common/TracyQueue.hpp"
|
||||
#include "../common/TracyAlign.hpp"
|
||||
#include "../common/TracyAlloc.hpp"
|
||||
#include "../common/TracyMutex.hpp"
|
||||
#include "../common/TracyProtocol.hpp"
|
||||
|
||||
#if defined _WIN32
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
# include <TargetConditionals.h>
|
||||
# include <mach/mach_time.h>
|
||||
#endif
|
||||
|
||||
#if ( defined _WIN32 || ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) || ( defined TARGET_OS_IOS && TARGET_OS_IOS == 1 ) )
|
||||
# define TRACY_HW_TIMER
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
# include <signal.h>
|
||||
#endif
|
||||
|
||||
#if defined TRACY_TIMER_FALLBACK || !defined TRACY_HW_TIMER
|
||||
# include <chrono>
|
||||
#endif
|
||||
|
||||
#ifndef TracyConcat
|
||||
# define TracyConcat(x,y) TracyConcatIndirect(x,y)
|
||||
#endif
|
||||
#ifndef TracyConcatIndirect
|
||||
# define TracyConcatIndirect(x,y) x##y
|
||||
#endif
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
#if defined(TRACY_DELAYED_INIT) && defined(TRACY_MANUAL_LIFETIME)
|
||||
TRACY_API void StartupProfiler();
|
||||
TRACY_API void ShutdownProfiler();
|
||||
#endif
|
||||
|
||||
class GpuCtx;
|
||||
class Profiler;
|
||||
class Socket;
|
||||
class UdpBroadcast;
|
||||
|
||||
struct GpuCtxWrapper
|
||||
{
|
||||
GpuCtx* ptr;
|
||||
};
|
||||
|
||||
TRACY_API moodycamel::ConcurrentQueue<QueueItem>::ExplicitProducer* GetToken();
|
||||
TRACY_API Profiler& GetProfiler();
|
||||
TRACY_API std::atomic<uint32_t>& GetLockCounter();
|
||||
TRACY_API std::atomic<uint8_t>& GetGpuCtxCounter();
|
||||
TRACY_API GpuCtxWrapper& GetGpuCtx();
|
||||
TRACY_API uint32_t GetThreadHandle();
|
||||
TRACY_API bool ProfilerAvailable();
|
||||
TRACY_API bool ProfilerAllocatorAvailable();
|
||||
TRACY_API int64_t GetFrequencyQpc();
|
||||
|
||||
#if defined TRACY_TIMER_FALLBACK && defined TRACY_HW_TIMER && ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 )
|
||||
TRACY_API bool HardwareSupportsInvariantTSC(); // check, if we need fallback scenario
|
||||
#else
|
||||
# if defined TRACY_HW_TIMER
|
||||
tracy_force_inline bool HardwareSupportsInvariantTSC()
|
||||
{
|
||||
return true; // this is checked at startup
|
||||
}
|
||||
# else
|
||||
tracy_force_inline bool HardwareSupportsInvariantTSC()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
struct SourceLocationData
|
||||
{
|
||||
const char* name;
|
||||
const char* function;
|
||||
const char* file;
|
||||
uint32_t line;
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
struct LuaZoneState
|
||||
{
|
||||
uint32_t counter;
|
||||
bool active;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#define TracyLfqPrepare( _type ) \
|
||||
moodycamel::ConcurrentQueueDefaultTraits::index_t __magic; \
|
||||
auto __token = GetToken(); \
|
||||
auto& __tail = __token->get_tail_index(); \
|
||||
auto item = __token->enqueue_begin( __magic ); \
|
||||
MemWrite( &item->hdr.type, _type );
|
||||
|
||||
#define TracyLfqCommit \
|
||||
__tail.store( __magic + 1, std::memory_order_release );
|
||||
|
||||
#define TracyLfqPrepareC( _type ) \
|
||||
tracy::moodycamel::ConcurrentQueueDefaultTraits::index_t __magic; \
|
||||
auto __token = tracy::GetToken(); \
|
||||
auto& __tail = __token->get_tail_index(); \
|
||||
auto item = __token->enqueue_begin( __magic ); \
|
||||
tracy::MemWrite( &item->hdr.type, _type );
|
||||
|
||||
#define TracyLfqCommitC \
|
||||
__tail.store( __magic + 1, std::memory_order_release );
|
||||
|
||||
|
||||
#ifdef TRACY_FIBERS
|
||||
# define TracyQueuePrepare( _type ) \
|
||||
auto item = Profiler::QueueSerial(); \
|
||||
MemWrite( &item->hdr.type, _type );
|
||||
# define TracyQueueCommit( _name ) \
|
||||
MemWrite( &item->_name.thread, GetThreadHandle() ); \
|
||||
Profiler::QueueSerialFinish();
|
||||
# define TracyQueuePrepareC( _type ) \
|
||||
auto item = tracy::Profiler::QueueSerial(); \
|
||||
tracy::MemWrite( &item->hdr.type, _type );
|
||||
# define TracyQueueCommitC( _name ) \
|
||||
tracy::MemWrite( &item->_name.thread, tracy::GetThreadHandle() ); \
|
||||
tracy::Profiler::QueueSerialFinish();
|
||||
#else
|
||||
# define TracyQueuePrepare( _type ) TracyLfqPrepare( _type )
|
||||
# define TracyQueueCommit( _name ) TracyLfqCommit
|
||||
# define TracyQueuePrepareC( _type ) TracyLfqPrepareC( _type )
|
||||
# define TracyQueueCommitC( _name ) TracyLfqCommitC
|
||||
#endif
|
||||
|
||||
|
||||
typedef void(*ParameterCallback)( void* data, uint32_t idx, int32_t val );
|
||||
typedef char*(*SourceContentsCallback)( void* data, const char* filename, size_t& size );
|
||||
|
||||
class Profiler
|
||||
{
|
||||
struct FrameImageQueueItem
|
||||
{
|
||||
void* image;
|
||||
uint32_t frame;
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
bool flip;
|
||||
};
|
||||
|
||||
enum class SymbolQueueItemType
|
||||
{
|
||||
CallstackFrame,
|
||||
SymbolQuery,
|
||||
ExternalName,
|
||||
KernelCode,
|
||||
SourceCode
|
||||
};
|
||||
|
||||
struct SymbolQueueItem
|
||||
{
|
||||
SymbolQueueItemType type;
|
||||
uint64_t ptr;
|
||||
uint64_t extra;
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
public:
|
||||
Profiler();
|
||||
~Profiler();
|
||||
|
||||
void SpawnWorkerThreads();
|
||||
|
||||
static tracy_force_inline int64_t GetTime()
|
||||
{
|
||||
#ifdef TRACY_HW_TIMER
|
||||
# if defined TARGET_OS_IOS && TARGET_OS_IOS == 1
|
||||
if( HardwareSupportsInvariantTSC() ) return mach_absolute_time();
|
||||
# elif defined _WIN32
|
||||
# ifdef TRACY_TIMER_QPC
|
||||
return GetTimeQpc();
|
||||
# else
|
||||
if( HardwareSupportsInvariantTSC() ) return int64_t( __rdtsc() );
|
||||
# endif
|
||||
# elif defined __i386 || defined _M_IX86
|
||||
if( HardwareSupportsInvariantTSC() )
|
||||
{
|
||||
uint32_t eax, edx;
|
||||
asm volatile ( "rdtsc" : "=a" (eax), "=d" (edx) );
|
||||
return ( uint64_t( edx ) << 32 ) + uint64_t( eax );
|
||||
}
|
||||
# elif defined __x86_64__ || defined _M_X64
|
||||
if( HardwareSupportsInvariantTSC() )
|
||||
{
|
||||
uint64_t rax, rdx;
|
||||
asm volatile ( "rdtsc" : "=a" (rax), "=d" (rdx) );
|
||||
return (int64_t)(( rdx << 32 ) + rax);
|
||||
}
|
||||
# else
|
||||
# error "TRACY_HW_TIMER detection logic needs fixing"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined TRACY_HW_TIMER || defined TRACY_TIMER_FALLBACK
|
||||
# if defined __linux__ && defined CLOCK_MONOTONIC_RAW
|
||||
struct timespec ts;
|
||||
clock_gettime( CLOCK_MONOTONIC_RAW, &ts );
|
||||
return int64_t( ts.tv_sec ) * 1000000000ll + int64_t( ts.tv_nsec );
|
||||
# else
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined TRACY_TIMER_FALLBACK
|
||||
return 0; // unreachable branch
|
||||
#endif
|
||||
}
|
||||
|
||||
tracy_force_inline uint32_t GetNextZoneId()
|
||||
{
|
||||
return m_zoneId.fetch_add( 1, std::memory_order_relaxed );
|
||||
}
|
||||
|
||||
static tracy_force_inline QueueItem* QueueSerial()
|
||||
{
|
||||
auto& p = GetProfiler();
|
||||
p.m_serialLock.lock();
|
||||
return p.m_serialQueue.prepare_next();
|
||||
}
|
||||
|
||||
static tracy_force_inline QueueItem* QueueSerialCallstack( void* ptr )
|
||||
{
|
||||
auto& p = GetProfiler();
|
||||
p.m_serialLock.lock();
|
||||
p.SendCallstackSerial( ptr );
|
||||
return p.m_serialQueue.prepare_next();
|
||||
}
|
||||
|
||||
static tracy_force_inline void QueueSerialFinish()
|
||||
{
|
||||
auto& p = GetProfiler();
|
||||
p.m_serialQueue.commit_next();
|
||||
p.m_serialLock.unlock();
|
||||
}
|
||||
|
||||
static tracy_force_inline void SendFrameMark( const char* name )
|
||||
{
|
||||
if( !name ) GetProfiler().m_frameCount.fetch_add( 1, std::memory_order_relaxed );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
auto item = QueueSerial();
|
||||
MemWrite( &item->hdr.type, QueueType::FrameMarkMsg );
|
||||
MemWrite( &item->frameMark.time, GetTime() );
|
||||
MemWrite( &item->frameMark.name, uint64_t( name ) );
|
||||
QueueSerialFinish();
|
||||
}
|
||||
|
||||
static tracy_force_inline void SendFrameMark( const char* name, QueueType type )
|
||||
{
|
||||
assert( type == QueueType::FrameMarkMsgStart || type == QueueType::FrameMarkMsgEnd );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
auto item = QueueSerial();
|
||||
MemWrite( &item->hdr.type, type );
|
||||
MemWrite( &item->frameMark.time, GetTime() );
|
||||
MemWrite( &item->frameMark.name, uint64_t( name ) );
|
||||
QueueSerialFinish();
|
||||
}
|
||||
|
||||
static tracy_force_inline void SendFrameImage( const void* image, uint16_t w, uint16_t h, uint8_t offset, bool flip )
|
||||
{
|
||||
#ifndef TRACY_NO_FRAME_IMAGE
|
||||
auto& profiler = GetProfiler();
|
||||
assert( profiler.m_frameCount.load( std::memory_order_relaxed ) < std::numeric_limits<uint32_t>::max() );
|
||||
# ifdef TRACY_ON_DEMAND
|
||||
if( !profiler.IsConnected() ) return;
|
||||
# endif
|
||||
const auto sz = size_t( w ) * size_t( h ) * 4;
|
||||
auto ptr = (char*)tracy_malloc( sz );
|
||||
memcpy( ptr, image, sz );
|
||||
|
||||
profiler.m_fiLock.lock();
|
||||
auto fi = profiler.m_fiQueue.prepare_next();
|
||||
fi->image = ptr;
|
||||
fi->frame = uint32_t( profiler.m_frameCount.load( std::memory_order_relaxed ) - offset );
|
||||
fi->w = w;
|
||||
fi->h = h;
|
||||
fi->flip = flip;
|
||||
profiler.m_fiQueue.commit_next();
|
||||
profiler.m_fiLock.unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
static tracy_force_inline void PlotData( const char* name, int64_t val )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
TracyLfqPrepare( QueueType::PlotDataInt );
|
||||
MemWrite( &item->plotDataInt.name, (uint64_t)name );
|
||||
MemWrite( &item->plotDataInt.time, GetTime() );
|
||||
MemWrite( &item->plotDataInt.val, val );
|
||||
TracyLfqCommit;
|
||||
}
|
||||
|
||||
static tracy_force_inline void PlotData( const char* name, float val )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
TracyLfqPrepare( QueueType::PlotDataFloat );
|
||||
MemWrite( &item->plotDataFloat.name, (uint64_t)name );
|
||||
MemWrite( &item->plotDataFloat.time, GetTime() );
|
||||
MemWrite( &item->plotDataFloat.val, val );
|
||||
TracyLfqCommit;
|
||||
}
|
||||
|
||||
static tracy_force_inline void PlotData( const char* name, double val )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
TracyLfqPrepare( QueueType::PlotDataDouble );
|
||||
MemWrite( &item->plotDataDouble.name, (uint64_t)name );
|
||||
MemWrite( &item->plotDataDouble.time, GetTime() );
|
||||
MemWrite( &item->plotDataDouble.val, val );
|
||||
TracyLfqCommit;
|
||||
}
|
||||
|
||||
static tracy_force_inline void ConfigurePlot( const char* name, PlotFormatType type, bool step, bool fill, uint32_t color )
|
||||
{
|
||||
TracyLfqPrepare( QueueType::PlotConfig );
|
||||
MemWrite( &item->plotConfig.name, (uint64_t)name );
|
||||
MemWrite( &item->plotConfig.type, (uint8_t)type );
|
||||
MemWrite( &item->plotConfig.step, (uint8_t)step );
|
||||
MemWrite( &item->plotConfig.fill, (uint8_t)fill );
|
||||
MemWrite( &item->plotConfig.color, color );
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
|
||||
TracyLfqCommit;
|
||||
}
|
||||
|
||||
static tracy_force_inline void Message( const char* txt, size_t size, int callstack )
|
||||
{
|
||||
assert( size < std::numeric_limits<uint16_t>::max() );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
if( callstack != 0 )
|
||||
{
|
||||
tracy::GetProfiler().SendCallstack( callstack );
|
||||
}
|
||||
|
||||
auto ptr = (char*)tracy_malloc( size );
|
||||
memcpy( ptr, txt, size );
|
||||
|
||||
TracyQueuePrepare( callstack == 0 ? QueueType::Message : QueueType::MessageCallstack );
|
||||
MemWrite( &item->messageFat.time, GetTime() );
|
||||
MemWrite( &item->messageFat.text, (uint64_t)ptr );
|
||||
MemWrite( &item->messageFat.size, (uint16_t)size );
|
||||
TracyQueueCommit( messageFatThread );
|
||||
}
|
||||
|
||||
static tracy_force_inline void Message( const char* txt, int callstack )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
if( callstack != 0 )
|
||||
{
|
||||
tracy::GetProfiler().SendCallstack( callstack );
|
||||
}
|
||||
|
||||
TracyQueuePrepare( callstack == 0 ? QueueType::MessageLiteral : QueueType::MessageLiteralCallstack );
|
||||
MemWrite( &item->messageLiteral.time, GetTime() );
|
||||
MemWrite( &item->messageLiteral.text, (uint64_t)txt );
|
||||
TracyQueueCommit( messageLiteralThread );
|
||||
}
|
||||
|
||||
static tracy_force_inline void MessageColor( const char* txt, size_t size, uint32_t color, int callstack )
|
||||
{
|
||||
assert( size < std::numeric_limits<uint16_t>::max() );
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
if( callstack != 0 )
|
||||
{
|
||||
tracy::GetProfiler().SendCallstack( callstack );
|
||||
}
|
||||
|
||||
auto ptr = (char*)tracy_malloc( size );
|
||||
memcpy( ptr, txt, size );
|
||||
|
||||
TracyQueuePrepare( callstack == 0 ? QueueType::MessageColor : QueueType::MessageColorCallstack );
|
||||
MemWrite( &item->messageColorFat.time, GetTime() );
|
||||
MemWrite( &item->messageColorFat.text, (uint64_t)ptr );
|
||||
MemWrite( &item->messageColorFat.b, uint8_t( ( color ) & 0xFF ) );
|
||||
MemWrite( &item->messageColorFat.g, uint8_t( ( color >> 8 ) & 0xFF ) );
|
||||
MemWrite( &item->messageColorFat.r, uint8_t( ( color >> 16 ) & 0xFF ) );
|
||||
MemWrite( &item->messageColorFat.size, (uint16_t)size );
|
||||
TracyQueueCommit( messageColorFatThread );
|
||||
}
|
||||
|
||||
static tracy_force_inline void MessageColor( const char* txt, uint32_t color, int callstack )
|
||||
{
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
if( callstack != 0 )
|
||||
{
|
||||
tracy::GetProfiler().SendCallstack( callstack );
|
||||
}
|
||||
|
||||
TracyQueuePrepare( callstack == 0 ? QueueType::MessageLiteralColor : QueueType::MessageLiteralColorCallstack );
|
||||
MemWrite( &item->messageColorLiteral.time, GetTime() );
|
||||
MemWrite( &item->messageColorLiteral.text, (uint64_t)txt );
|
||||
MemWrite( &item->messageColorLiteral.b, uint8_t( ( color ) & 0xFF ) );
|
||||
MemWrite( &item->messageColorLiteral.g, uint8_t( ( color >> 8 ) & 0xFF ) );
|
||||
MemWrite( &item->messageColorLiteral.r, uint8_t( ( color >> 16 ) & 0xFF ) );
|
||||
TracyQueueCommit( messageColorLiteralThread );
|
||||
}
|
||||
|
||||
static tracy_force_inline void MessageAppInfo( const char* txt, size_t size )
|
||||
{
|
||||
assert( size < std::numeric_limits<uint16_t>::max() );
|
||||
auto ptr = (char*)tracy_malloc( size );
|
||||
memcpy( ptr, txt, size );
|
||||
TracyLfqPrepare( QueueType::MessageAppInfo );
|
||||
MemWrite( &item->messageFat.time, GetTime() );
|
||||
MemWrite( &item->messageFat.text, (uint64_t)ptr );
|
||||
MemWrite( &item->messageFat.size, (uint16_t)size );
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
|
||||
TracyLfqCommit;
|
||||
}
|
||||
|
||||
static tracy_force_inline void MemAlloc( const void* ptr, size_t size, bool secure )
|
||||
{
|
||||
if( secure && !ProfilerAvailable() ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
const auto thread = GetThreadHandle();
|
||||
|
||||
GetProfiler().m_serialLock.lock();
|
||||
SendMemAlloc( QueueType::MemAlloc, thread, ptr, size );
|
||||
GetProfiler().m_serialLock.unlock();
|
||||
}
|
||||
|
||||
static tracy_force_inline void MemFree( const void* ptr, bool secure )
|
||||
{
|
||||
if( secure && !ProfilerAvailable() ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
const auto thread = GetThreadHandle();
|
||||
|
||||
GetProfiler().m_serialLock.lock();
|
||||
SendMemFree( QueueType::MemFree, thread, ptr );
|
||||
GetProfiler().m_serialLock.unlock();
|
||||
}
|
||||
|
||||
static tracy_force_inline void MemAllocCallstack( const void* ptr, size_t size, int depth, bool secure )
|
||||
{
|
||||
if( secure && !ProfilerAvailable() ) return;
|
||||
#ifdef TRACY_HAS_CALLSTACK
|
||||
auto& profiler = GetProfiler();
|
||||
# ifdef TRACY_ON_DEMAND
|
||||
if( !profiler.IsConnected() ) return;
|
||||
# endif
|
||||
const auto thread = GetThreadHandle();
|
||||
|
||||
auto callstack = Callstack( depth );
|
||||
|
||||
profiler.m_serialLock.lock();
|
||||
SendCallstackSerial( callstack );
|
||||
SendMemAlloc( QueueType::MemAllocCallstack, thread, ptr, size );
|
||||
profiler.m_serialLock.unlock();
|
||||
#else
|
||||
static_cast<void>(depth); // unused
|
||||
MemAlloc( ptr, size, secure );
|
||||
#endif
|
||||
}
|
||||
|
||||
static tracy_force_inline void MemFreeCallstack( const void* ptr, int depth, bool secure )
|
||||
{
|
||||
if( secure && !ProfilerAvailable() ) return;
|
||||
if( !ProfilerAllocatorAvailable() )
|
||||
{
|
||||
MemFree( ptr, secure );
|
||||
return;
|
||||
}
|
||||
#ifdef TRACY_HAS_CALLSTACK
|
||||
auto& profiler = GetProfiler();
|
||||
# ifdef TRACY_ON_DEMAND
|
||||
if( !profiler.IsConnected() ) return;
|
||||
# endif
|
||||
const auto thread = GetThreadHandle();
|
||||
|
||||
auto callstack = Callstack( depth );
|
||||
|
||||
profiler.m_serialLock.lock();
|
||||
SendCallstackSerial( callstack );
|
||||
SendMemFree( QueueType::MemFreeCallstack, thread, ptr );
|
||||
profiler.m_serialLock.unlock();
|
||||
#else
|
||||
static_cast<void>(depth); // unused
|
||||
MemFree( ptr, secure );
|
||||
#endif
|
||||
}
|
||||
|
||||
static tracy_force_inline void MemAllocNamed( const void* ptr, size_t size, bool secure, const char* name )
|
||||
{
|
||||
if( secure && !ProfilerAvailable() ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
const auto thread = GetThreadHandle();
|
||||
|
||||
GetProfiler().m_serialLock.lock();
|
||||
SendMemName( name );
|
||||
SendMemAlloc( QueueType::MemAllocNamed, thread, ptr, size );
|
||||
GetProfiler().m_serialLock.unlock();
|
||||
}
|
||||
|
||||
static tracy_force_inline void MemFreeNamed( const void* ptr, bool secure, const char* name )
|
||||
{
|
||||
if( secure && !ProfilerAvailable() ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( !GetProfiler().IsConnected() ) return;
|
||||
#endif
|
||||
const auto thread = GetThreadHandle();
|
||||
|
||||
GetProfiler().m_serialLock.lock();
|
||||
SendMemName( name );
|
||||
SendMemFree( QueueType::MemFreeNamed, thread, ptr );
|
||||
GetProfiler().m_serialLock.unlock();
|
||||
}
|
||||
|
||||
static tracy_force_inline void MemAllocCallstackNamed( const void* ptr, size_t size, int depth, bool secure, const char* name )
|
||||
{
|
||||
if( secure && !ProfilerAvailable() ) return;
|
||||
#ifdef TRACY_HAS_CALLSTACK
|
||||
auto& profiler = GetProfiler();
|
||||
# ifdef TRACY_ON_DEMAND
|
||||
if( !profiler.IsConnected() ) return;
|
||||
# endif
|
||||
const auto thread = GetThreadHandle();
|
||||
|
||||
auto callstack = Callstack( depth );
|
||||
|
||||
profiler.m_serialLock.lock();
|
||||
SendCallstackSerial( callstack );
|
||||
SendMemName( name );
|
||||
SendMemAlloc( QueueType::MemAllocCallstackNamed, thread, ptr, size );
|
||||
profiler.m_serialLock.unlock();
|
||||
#else
|
||||
static_cast<void>(depth); // unused
|
||||
static_cast<void>(name); // unused
|
||||
MemAlloc( ptr, size, secure );
|
||||
#endif
|
||||
}
|
||||
|
||||
static tracy_force_inline void MemFreeCallstackNamed( const void* ptr, int depth, bool secure, const char* name )
|
||||
{
|
||||
if( secure && !ProfilerAvailable() ) return;
|
||||
#ifdef TRACY_HAS_CALLSTACK
|
||||
auto& profiler = GetProfiler();
|
||||
# ifdef TRACY_ON_DEMAND
|
||||
if( !profiler.IsConnected() ) return;
|
||||
# endif
|
||||
const auto thread = GetThreadHandle();
|
||||
|
||||
auto callstack = Callstack( depth );
|
||||
|
||||
profiler.m_serialLock.lock();
|
||||
SendCallstackSerial( callstack );
|
||||
SendMemName( name );
|
||||
SendMemFree( QueueType::MemFreeCallstackNamed, thread, ptr );
|
||||
profiler.m_serialLock.unlock();
|
||||
#else
|
||||
static_cast<void>(depth); // unused
|
||||
static_cast<void>(name); // unused
|
||||
MemFree( ptr, secure );
|
||||
#endif
|
||||
}
|
||||
|
||||
static tracy_force_inline void SendCallstack( int depth )
|
||||
{
|
||||
#ifdef TRACY_HAS_CALLSTACK
|
||||
auto ptr = Callstack( depth );
|
||||
TracyQueuePrepare( QueueType::Callstack );
|
||||
MemWrite( &item->callstackFat.ptr, (uint64_t)ptr );
|
||||
TracyQueueCommit( callstackFatThread );
|
||||
#else
|
||||
static_cast<void>(depth); // unused
|
||||
#endif
|
||||
}
|
||||
|
||||
static tracy_force_inline void ParameterRegister( ParameterCallback cb, void* data )
|
||||
{
|
||||
auto& profiler = GetProfiler();
|
||||
profiler.m_paramCallback = cb;
|
||||
profiler.m_paramCallbackData = data;
|
||||
}
|
||||
|
||||
static tracy_force_inline void ParameterSetup( uint32_t idx, const char* name, bool isBool, int32_t val )
|
||||
{
|
||||
TracyLfqPrepare( QueueType::ParamSetup );
|
||||
tracy::MemWrite( &item->paramSetup.idx, idx );
|
||||
tracy::MemWrite( &item->paramSetup.name, (uint64_t)name );
|
||||
tracy::MemWrite( &item->paramSetup.isBool, (uint8_t)isBool );
|
||||
tracy::MemWrite( &item->paramSetup.val, val );
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
GetProfiler().DeferItem( *item );
|
||||
#endif
|
||||
|
||||
TracyLfqCommit;
|
||||
}
|
||||
|
||||
static tracy_force_inline void SourceCallbackRegister( SourceContentsCallback cb, void* data )
|
||||
{
|
||||
auto& profiler = GetProfiler();
|
||||
profiler.m_sourceCallback = cb;
|
||||
profiler.m_sourceCallbackData = data;
|
||||
}
|
||||
|
||||
#ifdef TRACY_FIBERS
|
||||
static tracy_force_inline void EnterFiber( const char* fiber )
|
||||
{
|
||||
TracyQueuePrepare( QueueType::FiberEnter );
|
||||
MemWrite( &item->fiberEnter.time, GetTime() );
|
||||
MemWrite( &item->fiberEnter.fiber, (uint64_t)fiber );
|
||||
TracyQueueCommit( fiberEnter );
|
||||
}
|
||||
|
||||
static tracy_force_inline void LeaveFiber()
|
||||
{
|
||||
TracyQueuePrepare( QueueType::FiberLeave );
|
||||
MemWrite( &item->fiberLeave.time, GetTime() );
|
||||
TracyQueueCommit( fiberLeave );
|
||||
}
|
||||
#endif
|
||||
|
||||
void SendCallstack( int depth, const char* skipBefore );
|
||||
static void CutCallstack( void* callstack, const char* skipBefore );
|
||||
|
||||
static bool ShouldExit();
|
||||
|
||||
tracy_force_inline bool IsConnected() const
|
||||
{
|
||||
return m_isConnected.load( std::memory_order_acquire );
|
||||
}
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
tracy_force_inline uint64_t ConnectionId() const
|
||||
{
|
||||
return m_connectionId.load( std::memory_order_acquire );
|
||||
}
|
||||
|
||||
tracy_force_inline void DeferItem( const QueueItem& item )
|
||||
{
|
||||
m_deferredLock.lock();
|
||||
auto dst = m_deferredQueue.push_next();
|
||||
memcpy( dst, &item, sizeof( item ) );
|
||||
m_deferredLock.unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
void RequestShutdown() { m_shutdown.store( true, std::memory_order_relaxed ); m_shutdownManual.store( true, std::memory_order_relaxed ); }
|
||||
bool HasShutdownFinished() const { return m_shutdownFinished.load( std::memory_order_relaxed ); }
|
||||
|
||||
void SendString( uint64_t str, const char* ptr, QueueType type ) { SendString( str, ptr, strlen( ptr ), type ); }
|
||||
void SendString( uint64_t str, const char* ptr, size_t len, QueueType type );
|
||||
void SendSingleString( const char* ptr ) { SendSingleString( ptr, strlen( ptr ) ); }
|
||||
void SendSingleString( const char* ptr, size_t len );
|
||||
void SendSecondString( const char* ptr ) { SendSecondString( ptr, strlen( ptr ) ); }
|
||||
void SendSecondString( const char* ptr, size_t len );
|
||||
|
||||
|
||||
// Allocated source location data layout:
|
||||
// 2b payload size
|
||||
// 4b color
|
||||
// 4b source line
|
||||
// fsz function name
|
||||
// 1b null terminator
|
||||
// ssz source file name
|
||||
// 1b null terminator
|
||||
// nsz zone name (optional)
|
||||
|
||||
static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function )
|
||||
{
|
||||
return AllocSourceLocation( line, source, function, nullptr, 0 );
|
||||
}
|
||||
|
||||
static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function, const char* name, size_t nameSz )
|
||||
{
|
||||
return AllocSourceLocation( line, source, strlen(source), function, strlen(function), name, nameSz );
|
||||
}
|
||||
|
||||
static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz )
|
||||
{
|
||||
return AllocSourceLocation( line, source, sourceSz, function, functionSz, nullptr, 0 );
|
||||
}
|
||||
|
||||
static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz )
|
||||
{
|
||||
const auto sz32 = uint32_t( 2 + 4 + 4 + functionSz + 1 + sourceSz + 1 + nameSz );
|
||||
assert( sz32 <= std::numeric_limits<uint16_t>::max() );
|
||||
const auto sz = uint16_t( sz32 );
|
||||
auto ptr = (char*)tracy_malloc( sz );
|
||||
memcpy( ptr, &sz, 2 );
|
||||
memset( ptr + 2, 0, 4 );
|
||||
memcpy( ptr + 6, &line, 4 );
|
||||
memcpy( ptr + 10, function, functionSz );
|
||||
ptr[10 + functionSz] = '\0';
|
||||
memcpy( ptr + 10 + functionSz + 1, source, sourceSz );
|
||||
ptr[10 + functionSz + 1 + sourceSz] = '\0';
|
||||
if( nameSz != 0 )
|
||||
{
|
||||
memcpy( ptr + 10 + functionSz + 1 + sourceSz + 1, name, nameSz );
|
||||
}
|
||||
return uint64_t( ptr );
|
||||
}
|
||||
|
||||
private:
|
||||
enum class DequeueStatus { DataDequeued, ConnectionLost, QueueEmpty };
|
||||
enum class ThreadCtxStatus { Same, Changed, ConnectionLost };
|
||||
|
||||
static void LaunchWorker( void* ptr ) { ((Profiler*)ptr)->Worker(); }
|
||||
void Worker();
|
||||
|
||||
#ifndef TRACY_NO_FRAME_IMAGE
|
||||
static void LaunchCompressWorker( void* ptr ) { ((Profiler*)ptr)->CompressWorker(); }
|
||||
void CompressWorker();
|
||||
#endif
|
||||
|
||||
#ifdef TRACY_HAS_CALLSTACK
|
||||
static void LaunchSymbolWorker( void* ptr ) { ((Profiler*)ptr)->SymbolWorker(); }
|
||||
void SymbolWorker();
|
||||
void HandleSymbolQueueItem( const SymbolQueueItem& si );
|
||||
#endif
|
||||
|
||||
void ClearQueues( tracy::moodycamel::ConsumerToken& token );
|
||||
void ClearSerial();
|
||||
DequeueStatus Dequeue( tracy::moodycamel::ConsumerToken& token );
|
||||
DequeueStatus DequeueContextSwitches( tracy::moodycamel::ConsumerToken& token, int64_t& timeStop );
|
||||
DequeueStatus DequeueSerial();
|
||||
ThreadCtxStatus ThreadCtxCheck( uint32_t threadId );
|
||||
bool CommitData();
|
||||
|
||||
tracy_force_inline bool AppendData( const void* data, size_t len )
|
||||
{
|
||||
const auto ret = NeedDataSize( len );
|
||||
AppendDataUnsafe( data, len );
|
||||
return ret;
|
||||
}
|
||||
|
||||
tracy_force_inline bool NeedDataSize( size_t len )
|
||||
{
|
||||
assert( len <= TargetFrameSize );
|
||||
bool ret = true;
|
||||
if( m_bufferOffset - m_bufferStart + (int)len > TargetFrameSize )
|
||||
{
|
||||
ret = CommitData();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
tracy_force_inline void AppendDataUnsafe( const void* data, size_t len )
|
||||
{
|
||||
memcpy( m_buffer + m_bufferOffset, data, len );
|
||||
m_bufferOffset += int( len );
|
||||
}
|
||||
|
||||
bool SendData( const char* data, size_t len );
|
||||
void SendLongString( uint64_t ptr, const char* str, size_t len, QueueType type );
|
||||
void SendSourceLocation( uint64_t ptr );
|
||||
void SendSourceLocationPayload( uint64_t ptr );
|
||||
void SendCallstackPayload( uint64_t ptr );
|
||||
void SendCallstackPayload64( uint64_t ptr );
|
||||
void SendCallstackAlloc( uint64_t ptr );
|
||||
|
||||
void QueueCallstackFrame( uint64_t ptr );
|
||||
void QueueSymbolQuery( uint64_t symbol );
|
||||
void QueueExternalName( uint64_t ptr );
|
||||
void QueueKernelCode( uint64_t symbol, uint32_t size );
|
||||
void QueueSourceCodeQuery( uint32_t id );
|
||||
|
||||
bool HandleServerQuery();
|
||||
void HandleDisconnect();
|
||||
void HandleParameter( uint64_t payload );
|
||||
void HandleSymbolCodeQuery( uint64_t symbol, uint32_t size );
|
||||
void HandleSourceCodeQuery( char* data, char* image, uint32_t id );
|
||||
|
||||
void AckServerQuery();
|
||||
void AckSymbolCodeNotAvailable();
|
||||
|
||||
void CalibrateTimer();
|
||||
void CalibrateDelay();
|
||||
void ReportTopology();
|
||||
|
||||
static tracy_force_inline void SendCallstackSerial( void* ptr )
|
||||
{
|
||||
#ifdef TRACY_HAS_CALLSTACK
|
||||
auto item = GetProfiler().m_serialQueue.prepare_next();
|
||||
MemWrite( &item->hdr.type, QueueType::CallstackSerial );
|
||||
MemWrite( &item->callstackFat.ptr, (uint64_t)ptr );
|
||||
GetProfiler().m_serialQueue.commit_next();
|
||||
#else
|
||||
static_cast<void>(ptr); // unused
|
||||
#endif
|
||||
}
|
||||
|
||||
static tracy_force_inline void SendMemAlloc( QueueType type, const uint32_t thread, const void* ptr, size_t size )
|
||||
{
|
||||
assert( type == QueueType::MemAlloc || type == QueueType::MemAllocCallstack || type == QueueType::MemAllocNamed || type == QueueType::MemAllocCallstackNamed );
|
||||
|
||||
auto item = GetProfiler().m_serialQueue.prepare_next();
|
||||
MemWrite( &item->hdr.type, type );
|
||||
MemWrite( &item->memAlloc.time, GetTime() );
|
||||
MemWrite( &item->memAlloc.thread, thread );
|
||||
MemWrite( &item->memAlloc.ptr, (uint64_t)ptr );
|
||||
if( compile_time_condition<sizeof( size ) == 4>::value )
|
||||
{
|
||||
memcpy( &item->memAlloc.size, &size, 4 );
|
||||
memset( &item->memAlloc.size + 4, 0, 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( sizeof( size ) == 8 );
|
||||
memcpy( &item->memAlloc.size, &size, 4 );
|
||||
memcpy( ((char*)&item->memAlloc.size)+4, ((char*)&size)+4, 2 );
|
||||
}
|
||||
GetProfiler().m_serialQueue.commit_next();
|
||||
}
|
||||
|
||||
static tracy_force_inline void SendMemFree( QueueType type, const uint32_t thread, const void* ptr )
|
||||
{
|
||||
assert( type == QueueType::MemFree || type == QueueType::MemFreeCallstack || type == QueueType::MemFreeNamed || type == QueueType::MemFreeCallstackNamed );
|
||||
|
||||
auto item = GetProfiler().m_serialQueue.prepare_next();
|
||||
MemWrite( &item->hdr.type, type );
|
||||
MemWrite( &item->memFree.time, GetTime() );
|
||||
MemWrite( &item->memFree.thread, thread );
|
||||
MemWrite( &item->memFree.ptr, (uint64_t)ptr );
|
||||
GetProfiler().m_serialQueue.commit_next();
|
||||
}
|
||||
|
||||
static tracy_force_inline void SendMemName( const char* name )
|
||||
{
|
||||
assert( name );
|
||||
auto item = GetProfiler().m_serialQueue.prepare_next();
|
||||
MemWrite( &item->hdr.type, QueueType::MemNamePayload );
|
||||
MemWrite( &item->memName.name, (uint64_t)name );
|
||||
GetProfiler().m_serialQueue.commit_next();
|
||||
}
|
||||
|
||||
#if defined _WIN32 && defined TRACY_TIMER_QPC
|
||||
static int64_t GetTimeQpc();
|
||||
#endif
|
||||
|
||||
double m_timerMul;
|
||||
uint64_t m_resolution;
|
||||
uint64_t m_delay;
|
||||
std::atomic<int64_t> m_timeBegin;
|
||||
uint32_t m_mainThread;
|
||||
uint64_t m_epoch, m_exectime;
|
||||
std::atomic<bool> m_shutdown;
|
||||
std::atomic<bool> m_shutdownManual;
|
||||
std::atomic<bool> m_shutdownFinished;
|
||||
Socket* m_sock;
|
||||
UdpBroadcast* m_broadcast;
|
||||
bool m_noExit;
|
||||
uint32_t m_userPort;
|
||||
std::atomic<uint32_t> m_zoneId;
|
||||
int64_t m_samplingPeriod;
|
||||
|
||||
uint32_t m_threadCtx;
|
||||
int64_t m_refTimeThread;
|
||||
int64_t m_refTimeSerial;
|
||||
int64_t m_refTimeCtx;
|
||||
int64_t m_refTimeGpu;
|
||||
|
||||
void* m_stream; // LZ4_stream_t*
|
||||
char* m_buffer;
|
||||
int m_bufferOffset;
|
||||
int m_bufferStart;
|
||||
|
||||
char* m_lz4Buf;
|
||||
|
||||
FastVector<QueueItem> m_serialQueue, m_serialDequeue;
|
||||
TracyMutex m_serialLock;
|
||||
|
||||
#ifndef TRACY_NO_FRAME_IMAGE
|
||||
FastVector<FrameImageQueueItem> m_fiQueue, m_fiDequeue;
|
||||
TracyMutex m_fiLock;
|
||||
#endif
|
||||
|
||||
SPSCQueue<SymbolQueueItem> m_symbolQueue;
|
||||
|
||||
std::atomic<uint64_t> m_frameCount;
|
||||
std::atomic<bool> m_isConnected;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
std::atomic<uint64_t> m_connectionId;
|
||||
|
||||
TracyMutex m_deferredLock;
|
||||
FastVector<QueueItem> m_deferredQueue;
|
||||
#endif
|
||||
|
||||
#ifdef TRACY_HAS_SYSTIME
|
||||
void ProcessSysTime();
|
||||
|
||||
SysTime m_sysTime;
|
||||
uint64_t m_sysTimeLast = 0;
|
||||
#else
|
||||
void ProcessSysTime() {}
|
||||
#endif
|
||||
|
||||
ParameterCallback m_paramCallback;
|
||||
void* m_paramCallbackData;
|
||||
SourceContentsCallback m_sourceCallback;
|
||||
void* m_sourceCallbackData;
|
||||
|
||||
char* m_queryImage;
|
||||
char* m_queryData;
|
||||
char* m_queryDataPtr;
|
||||
|
||||
#if defined _WIN32
|
||||
void* m_exceptionHandler;
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
struct {
|
||||
struct sigaction pwr, ill, fpe, segv, pipe, bus, abrt;
|
||||
} m_prevSignal;
|
||||
#endif
|
||||
bool m_crashHandlerInstalled;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
141
oss/tracy/client/TracyRingBuffer.hpp
Normal file
141
oss/tracy/client/TracyRingBuffer.hpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#include <atomic>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "TracyDebug.hpp"
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
class RingBuffer
|
||||
{
|
||||
public:
|
||||
RingBuffer( unsigned int size, int fd, int id, int cpu = -1 )
|
||||
: m_size( size )
|
||||
, m_id( id )
|
||||
, m_cpu( cpu )
|
||||
, m_fd( fd )
|
||||
{
|
||||
const auto pageSize = uint32_t( getpagesize() );
|
||||
assert( size >= pageSize );
|
||||
assert( __builtin_popcount( size ) == 1 );
|
||||
m_mapSize = size + pageSize;
|
||||
auto mapAddr = mmap( nullptr, m_mapSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
|
||||
if( mapAddr == MAP_FAILED )
|
||||
{
|
||||
TracyDebug( "mmap failed: errno %i (%s)\n", errno, strerror( errno ) );
|
||||
m_fd = 0;
|
||||
m_metadata = nullptr;
|
||||
close( fd );
|
||||
return;
|
||||
}
|
||||
m_metadata = (perf_event_mmap_page*)mapAddr;
|
||||
assert( m_metadata->data_offset == pageSize );
|
||||
m_buffer = ((char*)mapAddr) + pageSize;
|
||||
m_tail = m_metadata->data_tail;
|
||||
}
|
||||
|
||||
~RingBuffer()
|
||||
{
|
||||
if( m_metadata ) munmap( m_metadata, m_mapSize );
|
||||
if( m_fd ) close( m_fd );
|
||||
}
|
||||
|
||||
RingBuffer( const RingBuffer& ) = delete;
|
||||
RingBuffer& operator=( const RingBuffer& ) = delete;
|
||||
|
||||
RingBuffer( RingBuffer&& other )
|
||||
{
|
||||
memcpy( (char*)&other, (char*)this, sizeof( RingBuffer ) );
|
||||
m_metadata = nullptr;
|
||||
m_fd = 0;
|
||||
}
|
||||
|
||||
RingBuffer& operator=( RingBuffer&& other )
|
||||
{
|
||||
memcpy( (char*)&other, (char*)this, sizeof( RingBuffer ) );
|
||||
m_metadata = nullptr;
|
||||
m_fd = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IsValid() const { return m_metadata != nullptr; }
|
||||
int GetId() const { return m_id; }
|
||||
int GetCpu() const { return m_cpu; }
|
||||
|
||||
void Enable()
|
||||
{
|
||||
ioctl( m_fd, PERF_EVENT_IOC_ENABLE, 0 );
|
||||
}
|
||||
|
||||
void Read( void* dst, uint64_t offset, uint64_t cnt )
|
||||
{
|
||||
const auto size = m_size;
|
||||
auto src = ( m_tail + offset ) % size;
|
||||
if( src + cnt <= size )
|
||||
{
|
||||
memcpy( dst, m_buffer + src, cnt );
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto s0 = size - src;
|
||||
const auto buf = m_buffer;
|
||||
memcpy( dst, buf + src, s0 );
|
||||
memcpy( (char*)dst + s0, buf, cnt - s0 );
|
||||
}
|
||||
}
|
||||
|
||||
void Advance( uint64_t cnt )
|
||||
{
|
||||
m_tail += cnt;
|
||||
StoreTail();
|
||||
}
|
||||
|
||||
bool CheckTscCaps() const
|
||||
{
|
||||
return m_metadata->cap_user_time_zero;
|
||||
}
|
||||
|
||||
int64_t ConvertTimeToTsc( int64_t timestamp ) const
|
||||
{
|
||||
if( !m_metadata->cap_user_time_zero ) return 0;
|
||||
const auto time = timestamp - m_metadata->time_zero;
|
||||
const auto quot = time / m_metadata->time_mult;
|
||||
const auto rem = time % m_metadata->time_mult;
|
||||
return ( quot << m_metadata->time_shift ) + ( rem << m_metadata->time_shift ) / m_metadata->time_mult;
|
||||
}
|
||||
|
||||
uint64_t LoadHead() const
|
||||
{
|
||||
return std::atomic_load_explicit( (const volatile std::atomic<uint64_t>*)&m_metadata->data_head, std::memory_order_acquire );
|
||||
}
|
||||
|
||||
uint64_t GetTail() const
|
||||
{
|
||||
return m_tail;
|
||||
}
|
||||
|
||||
private:
|
||||
void StoreTail()
|
||||
{
|
||||
std::atomic_store_explicit( (volatile std::atomic<uint64_t>*)&m_metadata->data_tail, m_tail, std::memory_order_release );
|
||||
}
|
||||
|
||||
unsigned int m_size;
|
||||
uint64_t m_tail;
|
||||
char* m_buffer;
|
||||
int m_id;
|
||||
int m_cpu;
|
||||
perf_event_mmap_page* m_metadata;
|
||||
|
||||
size_t m_mapSize;
|
||||
int m_fd;
|
||||
};
|
||||
|
||||
}
|
||||
175
oss/tracy/client/TracyScoped.hpp
Normal file
175
oss/tracy/client/TracyScoped.hpp
Normal file
@@ -0,0 +1,175 @@
|
||||
#ifndef __TRACYSCOPED_HPP__
|
||||
#define __TRACYSCOPED_HPP__
|
||||
|
||||
#include <limits>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../common/TracySystem.hpp"
|
||||
#include "../common/TracyAlign.hpp"
|
||||
#include "../common/TracyAlloc.hpp"
|
||||
#include "TracyProfiler.hpp"
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
class ScopedZone
|
||||
{
|
||||
public:
|
||||
ScopedZone( const ScopedZone& ) = delete;
|
||||
ScopedZone( ScopedZone&& ) = delete;
|
||||
ScopedZone& operator=( const ScopedZone& ) = delete;
|
||||
ScopedZone& operator=( ScopedZone&& ) = delete;
|
||||
|
||||
tracy_force_inline ScopedZone( const SourceLocationData* srcloc, bool is_active = true )
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
: m_active( is_active && GetProfiler().IsConnected() )
|
||||
#else
|
||||
: m_active( is_active )
|
||||
#endif
|
||||
{
|
||||
if( !m_active ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
m_connectionId = GetProfiler().ConnectionId();
|
||||
#endif
|
||||
TracyQueuePrepare( QueueType::ZoneBegin );
|
||||
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||
MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc );
|
||||
TracyQueueCommit( zoneBeginThread );
|
||||
}
|
||||
|
||||
tracy_force_inline ScopedZone( const SourceLocationData* srcloc, int depth, bool is_active = true )
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
: m_active( is_active && GetProfiler().IsConnected() )
|
||||
#else
|
||||
: m_active( is_active )
|
||||
#endif
|
||||
{
|
||||
if( !m_active ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
m_connectionId = GetProfiler().ConnectionId();
|
||||
#endif
|
||||
GetProfiler().SendCallstack( depth );
|
||||
|
||||
TracyQueuePrepare( QueueType::ZoneBeginCallstack );
|
||||
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||
MemWrite( &item->zoneBegin.srcloc, (uint64_t)srcloc );
|
||||
TracyQueueCommit( zoneBeginThread );
|
||||
}
|
||||
|
||||
tracy_force_inline ScopedZone( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, bool is_active = true )
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
: m_active( is_active && GetProfiler().IsConnected() )
|
||||
#else
|
||||
: m_active( is_active )
|
||||
#endif
|
||||
{
|
||||
if( !m_active ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
m_connectionId = GetProfiler().ConnectionId();
|
||||
#endif
|
||||
TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLoc );
|
||||
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||
MemWrite( &item->zoneBegin.srcloc, srcloc );
|
||||
TracyQueueCommit( zoneBeginThread );
|
||||
}
|
||||
|
||||
tracy_force_inline ScopedZone( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz, int depth, bool is_active = true )
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
: m_active( is_active && GetProfiler().IsConnected() )
|
||||
#else
|
||||
: m_active( is_active )
|
||||
#endif
|
||||
{
|
||||
if( !m_active ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
m_connectionId = GetProfiler().ConnectionId();
|
||||
#endif
|
||||
GetProfiler().SendCallstack( depth );
|
||||
|
||||
TracyQueuePrepare( QueueType::ZoneBeginAllocSrcLocCallstack );
|
||||
const auto srcloc = Profiler::AllocSourceLocation( line, source, sourceSz, function, functionSz, name, nameSz );
|
||||
MemWrite( &item->zoneBegin.time, Profiler::GetTime() );
|
||||
MemWrite( &item->zoneBegin.srcloc, srcloc );
|
||||
TracyQueueCommit( zoneBeginThread );
|
||||
}
|
||||
|
||||
tracy_force_inline ~ScopedZone()
|
||||
{
|
||||
if( !m_active ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( GetProfiler().ConnectionId() != m_connectionId ) return;
|
||||
#endif
|
||||
TracyQueuePrepare( QueueType::ZoneEnd );
|
||||
MemWrite( &item->zoneEnd.time, Profiler::GetTime() );
|
||||
TracyQueueCommit( zoneEndThread );
|
||||
}
|
||||
|
||||
tracy_force_inline void Text( const char* txt, size_t size )
|
||||
{
|
||||
assert( size < std::numeric_limits<uint16_t>::max() );
|
||||
if( !m_active ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( GetProfiler().ConnectionId() != m_connectionId ) return;
|
||||
#endif
|
||||
auto ptr = (char*)tracy_malloc( size );
|
||||
memcpy( ptr, txt, size );
|
||||
TracyQueuePrepare( QueueType::ZoneText );
|
||||
MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
|
||||
MemWrite( &item->zoneTextFat.size, (uint16_t)size );
|
||||
TracyQueueCommit( zoneTextFatThread );
|
||||
}
|
||||
|
||||
tracy_force_inline void Name( const char* txt, size_t size )
|
||||
{
|
||||
assert( size < std::numeric_limits<uint16_t>::max() );
|
||||
if( !m_active ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( GetProfiler().ConnectionId() != m_connectionId ) return;
|
||||
#endif
|
||||
auto ptr = (char*)tracy_malloc( size );
|
||||
memcpy( ptr, txt, size );
|
||||
TracyQueuePrepare( QueueType::ZoneName );
|
||||
MemWrite( &item->zoneTextFat.text, (uint64_t)ptr );
|
||||
MemWrite( &item->zoneTextFat.size, (uint16_t)size );
|
||||
TracyQueueCommit( zoneTextFatThread );
|
||||
}
|
||||
|
||||
tracy_force_inline void Color( uint32_t color )
|
||||
{
|
||||
if( !m_active ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( GetProfiler().ConnectionId() != m_connectionId ) return;
|
||||
#endif
|
||||
TracyQueuePrepare( QueueType::ZoneColor );
|
||||
MemWrite( &item->zoneColor.b, uint8_t( ( color ) & 0xFF ) );
|
||||
MemWrite( &item->zoneColor.g, uint8_t( ( color >> 8 ) & 0xFF ) );
|
||||
MemWrite( &item->zoneColor.r, uint8_t( ( color >> 16 ) & 0xFF ) );
|
||||
TracyQueueCommit( zoneColorThread );
|
||||
}
|
||||
|
||||
tracy_force_inline void Value( uint64_t value )
|
||||
{
|
||||
if( !m_active ) return;
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
if( GetProfiler().ConnectionId() != m_connectionId ) return;
|
||||
#endif
|
||||
TracyQueuePrepare( QueueType::ZoneValue );
|
||||
MemWrite( &item->zoneValue.value, value );
|
||||
TracyQueueCommit( zoneValueThread );
|
||||
}
|
||||
|
||||
tracy_force_inline bool IsActive() const { return m_active; }
|
||||
|
||||
private:
|
||||
const bool m_active;
|
||||
|
||||
#ifdef TRACY_ON_DEMAND
|
||||
uint64_t m_connectionId = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
41
oss/tracy/client/TracyStringHelpers.hpp
Normal file
41
oss/tracy/client/TracyStringHelpers.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef __TRACYSTRINGHELPERS_HPP__
|
||||
#define __TRACYSTRINGHELPERS_HPP__
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../common/TracyAlloc.hpp"
|
||||
#include "../common/TracyForceInline.hpp"
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
static tracy_force_inline char* CopyString( const char* src, size_t sz )
|
||||
{
|
||||
auto dst = (char*)tracy_malloc( sz + 1 );
|
||||
memcpy( dst, src, sz );
|
||||
dst[sz] = '\0';
|
||||
return dst;
|
||||
}
|
||||
|
||||
static tracy_force_inline char* CopyString( const char* src )
|
||||
{
|
||||
return CopyString( src, strlen( src ) );
|
||||
}
|
||||
|
||||
static tracy_force_inline char* CopyStringFast( const char* src, size_t sz )
|
||||
{
|
||||
auto dst = (char*)tracy_malloc_fast( sz + 1 );
|
||||
memcpy( dst, src, sz );
|
||||
dst[sz] = '\0';
|
||||
return dst;
|
||||
}
|
||||
|
||||
static tracy_force_inline char* CopyStringFast( const char* src )
|
||||
{
|
||||
return CopyStringFast( src, strlen( src ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
108
oss/tracy/client/TracySysTime.cpp
Normal file
108
oss/tracy/client/TracySysTime.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "TracySysTime.hpp"
|
||||
|
||||
#ifdef TRACY_HAS_SYSTIME
|
||||
|
||||
# if defined _WIN32
|
||||
# include <windows.h>
|
||||
# elif defined __linux__
|
||||
# include <stdio.h>
|
||||
# include <inttypes.h>
|
||||
# elif defined __APPLE__
|
||||
# include <mach/mach_host.h>
|
||||
# include <mach/host_info.h>
|
||||
# elif defined BSD
|
||||
# include <sys/types.h>
|
||||
# include <sys/sysctl.h>
|
||||
# endif
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
# if defined _WIN32
|
||||
|
||||
static inline uint64_t ConvertTime( const FILETIME& t )
|
||||
{
|
||||
return ( uint64_t( t.dwHighDateTime ) << 32 ) | uint64_t( t.dwLowDateTime );
|
||||
}
|
||||
|
||||
void SysTime::ReadTimes()
|
||||
{
|
||||
FILETIME idleTime;
|
||||
FILETIME kernelTime;
|
||||
FILETIME userTime;
|
||||
|
||||
GetSystemTimes( &idleTime, &kernelTime, &userTime );
|
||||
|
||||
idle = ConvertTime( idleTime );
|
||||
const auto kernel = ConvertTime( kernelTime );
|
||||
const auto user = ConvertTime( userTime );
|
||||
used = kernel + user;
|
||||
}
|
||||
|
||||
# elif defined __linux__
|
||||
|
||||
void SysTime::ReadTimes()
|
||||
{
|
||||
uint64_t user, nice, system;
|
||||
FILE* f = fopen( "/proc/stat", "r" );
|
||||
if( f )
|
||||
{
|
||||
int read = fscanf( f, "cpu %" PRIu64 " %" PRIu64 " %" PRIu64" %" PRIu64, &user, &nice, &system, &idle );
|
||||
fclose( f );
|
||||
if (read == 4)
|
||||
{
|
||||
used = user + nice + system;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# elif defined __APPLE__
|
||||
|
||||
void SysTime::ReadTimes()
|
||||
{
|
||||
host_cpu_load_info_data_t info;
|
||||
mach_msg_type_number_t cnt = HOST_CPU_LOAD_INFO_COUNT;
|
||||
host_statistics( mach_host_self(), HOST_CPU_LOAD_INFO, reinterpret_cast<host_info_t>( &info ), &cnt );
|
||||
used = info.cpu_ticks[CPU_STATE_USER] + info.cpu_ticks[CPU_STATE_NICE] + info.cpu_ticks[CPU_STATE_SYSTEM];
|
||||
idle = info.cpu_ticks[CPU_STATE_IDLE];
|
||||
}
|
||||
|
||||
# elif defined BSD
|
||||
|
||||
void SysTime::ReadTimes()
|
||||
{
|
||||
u_long data[5];
|
||||
size_t sz = sizeof( data );
|
||||
sysctlbyname( "kern.cp_time", &data, &sz, nullptr, 0 );
|
||||
used = data[0] + data[1] + data[2] + data[3];
|
||||
idle = data[4];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SysTime::SysTime()
|
||||
{
|
||||
ReadTimes();
|
||||
}
|
||||
|
||||
float SysTime::Get()
|
||||
{
|
||||
const auto oldUsed = used;
|
||||
const auto oldIdle = idle;
|
||||
|
||||
ReadTimes();
|
||||
|
||||
const auto diffIdle = idle - oldIdle;
|
||||
const auto diffUsed = used - oldUsed;
|
||||
|
||||
#if defined _WIN32
|
||||
return diffUsed == 0 ? -1 : ( diffUsed - diffIdle ) * 100.f / diffUsed;
|
||||
#elif defined __linux__ || defined __APPLE__ || defined BSD
|
||||
const auto total = diffUsed + diffIdle;
|
||||
return total == 0 ? -1 : diffUsed * 100.f / total;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
36
oss/tracy/client/TracySysTime.hpp
Normal file
36
oss/tracy/client/TracySysTime.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef __TRACYSYSTIME_HPP__
|
||||
#define __TRACYSYSTIME_HPP__
|
||||
|
||||
#if defined _WIN32 || defined __linux__ || defined __APPLE__
|
||||
# define TRACY_HAS_SYSTIME
|
||||
#else
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifdef BSD
|
||||
# define TRACY_HAS_SYSTIME
|
||||
#endif
|
||||
|
||||
#ifdef TRACY_HAS_SYSTIME
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
class SysTime
|
||||
{
|
||||
public:
|
||||
SysTime();
|
||||
float Get();
|
||||
|
||||
void ReadTimes();
|
||||
|
||||
private:
|
||||
uint64_t idle, used;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1592
oss/tracy/client/TracySysTrace.cpp
Normal file
1592
oss/tracy/client/TracySysTrace.cpp
Normal file
File diff suppressed because it is too large
Load Diff
28
oss/tracy/client/TracySysTrace.hpp
Normal file
28
oss/tracy/client/TracySysTrace.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef __TRACYSYSTRACE_HPP__
|
||||
#define __TRACYSYSTRACE_HPP__
|
||||
|
||||
#if !defined TRACY_NO_SYSTEM_TRACING && ( defined _WIN32 || defined __linux__ )
|
||||
# include "../common/TracyUwp.hpp"
|
||||
# ifndef TRACY_UWP
|
||||
# define TRACY_HAS_SYSTEM_TRACING
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef TRACY_HAS_SYSTEM_TRACING
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
bool SysTraceStart( int64_t& samplingPeriod );
|
||||
void SysTraceStop();
|
||||
void SysTraceWorker( void* ptr );
|
||||
|
||||
void SysTraceGetExternalName( uint64_t thread, const char*& threadName, const char*& name );
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user