Clang : Add power shell scripts

This commit is contained in:
Magne Sjaastad 2018-02-24 09:15:31 +01:00
parent 7ce6177bc5
commit bba69e7b98
4 changed files with 3019 additions and 0 deletions

View File

@ -0,0 +1,231 @@
<#
.SYNOPSIS
Compiles or tidies up code from Visual Studio .vcxproj project files.
It sets up the scene required for clang-build.ps1 to do its job, and makes
command-line usage for projects and files quicker.
Before calling sample-clang-build.ps1 you need to set the current directory
to the root source directory.
.PARAMETER aVcxprojToCompile
Alias 'proj'. Array of project(s) to compile. If empty, all projects are compiled.
If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used,
e.g. "msicomp" compiles all msicomp projects.
Can be passed as comma separated values.
.PARAMETER aVcxprojToIgnore
Alias 'proj-ignore'. Array of project(s) to ignore, from the matched ones.
If empty, all already matched projects are compiled.
If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used,
e.g. "msicomp" compiles all msicomp projects.
Can be passed as comma separated values.
.PARAMETER aVcxprojConfigPlatform
Alias 'active-config'. The configuration-platform pair, separated by |,
to be used when processing project files.
E.g. 'Debug|Win32'.
If not specified, the first configuration-plaform found in the current project is used.
.PARAMETER aCppToCompile
Alias 'file'. What cpp(s) to compile from the found project(s). If empty, all CPPs are compiled.
If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used,
e.g. "table" compiles all CPPs containing 'table'.
.PARAMETER aCppToIgnore
Alias 'file-ignore'. Array of file(s) to ignore, from the matched ones.
If empty, all already matched files are compiled.
If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used,
e.g. "table" ignores all CPPs containing 'table'.
Can be passed as comma separated values.
.PARAMETER aContinueOnError
Alias 'continue'. Switch to continue project compilation even when errors occur.
.PARAMETER aClangCompileFlags
Alias 'clang-flags'. Flags given to clang++ when compiling project,
alongside project-specific defines.
.PARAMETER aDisableNameRegexMatching
Alias 'literal'. Switch to take project and cpp name filters literally, not by regex matching.
.PARAMETER aTidyFlags
Alias 'tidy'. If not empty clang-tidy will be called with given flags, instead of clang++.
The tidy operation is applied to whole translation units, meaning all directory headers
included in the CPP will be tidied up too. Changes will not be applied, only simulated.
If aTidyFixFlags is present, it takes precedence over this parameter.
.PARAMETER aTidyFixFlags
Alias 'tidy-fix'. If not empty clang-tidy will be called with given flags, instead of clang++.
The tidy operation is applied to whole translation units, meaning all directory headers
included in the CPP will be tidied up too. Changes will be applied to the file(s).
If present, this parameter takes precedence over aTidyFlags.
.PARAMETER aAfterTidyFixFormatStyle
Alias 'format-style'. Used in combination with 'tidy-fix'. If present, clang-tidy will
also format the fixed file(s), using the specified style.
Possible values: - not present, no formatting will be done
- 'file'
Literally 'file', not a placeholder.
Uses .clang-format file in the closest parent directory.
- 'llvm'
- 'google'
- 'webkit'
- 'mozilla'
.EXAMPLE
PS .\sample-clang-build.ps1 -dir -proj foo,bar -file meow -tidy "-*,modernize-*"
<Description of example>
Runs clang-tidy, using "-*,modernize-*", on all CPPs containing 'meow' in their name from
the projects containing 'foo' or 'bar' in their names.
Doesn't actually apply the clang-tidy module changes to CPPs.
It will only print the tidy module output.
.EXAMPLE
PS .\sample-clang-build.ps1 -dir -proj foo,bar -file meow -tidy-fix "-*,modernize-*"
<Description of example>
Runs clang-tidy, using "-*,modernize-*", on all CPPs containing 'meow' in their name from
the projects containing 'foo' or 'bar' in their names.
It will apply all tidy module changes to CPPs.
.EXAMPLE
PS .\sample-clang-build.ps1 -dir -proj foo -proj-ignore foobar
<Description of example>
Runs clang++ on all CPPs in foo... projects, except foobar
.OUTPUTS
Will output Clang warnings and errors to screen. The return code will be 0 for success, >0 for failure.
.NOTES
Author: Gabriel Diaconita
#>
param( [alias("proj")] [Parameter(Mandatory=$false)][string[]] $aVcxprojToCompile
, [alias("proj-ignore")] [Parameter(Mandatory=$false)][string[]] $aVcxprojToIgnore
, [alias("active-config")][Parameter(Mandatory=$false)][string] $aVcxprojConfigPlatform
, [alias("file")] [Parameter(Mandatory=$false)][string] $aCppToCompile
, [alias("file-ignore")] [Parameter(Mandatory=$false)][string[]] $aCppToIgnore
, [alias("continue")] [Parameter(Mandatory=$false)][switch] $aContinueOnError
, [alias("literal")] [Parameter(Mandatory=$false)][switch] $aDisableNameRegexMatching
, [alias("tidy")] [Parameter(Mandatory=$false)][string] $aTidyFlags
, [alias("tidy-fix")] [Parameter(Mandatory=$false)][string] $aTidyFixFlags
, [alias("format-style")] [Parameter(Mandatory=$false)][string] $aAfterTidyFixFormatStyle
)
# ------------------------------------------------------------------------------------------------
Set-Variable -name kClangCompileFlags -Option Constant `
-value @( "-Wall"
, "-fms-compatibility-version=19.10"
, "-Wmicrosoft"
, "-Wno-invalid-token-paste"
, "-Wno-unknown-pragmas"
, "-Wno-unused-variable"
, "-Wno-unused-value"
, "-Wno-undefined-var-template"
, "-Wno-microsoft-enum-value"
, "-Wno-inconsistent-missing-override"
, "-Wno-extra-tokens"
, "-Wno-c99-extensions"
, "-Wno-logical-op-parentheses"
, "-Wno-invalid-source-encoding"
)
Set-Variable -name kVisualStudioVersion -value "2017" -Option Constant
Set-Variable -name kVisualStudioSku -value "Professional" -Option Constant
Set-Variable -name localVarUseParallelCompile -value $True -Option Constant
Set-Variable -name localVarCppToIgnore -Option Constant `
-value @( "gtest"
, "moc_"
)
# ------------------------------------------------------------------------------------------------
Function Merge-Array([string[]] $aArray)
{
# we need to individually wrap items into quotes as values
# can contain PS control characters (e.g. - in -std=c++14)
$quotedArray = ($aArray | ForEach-Object { """$_"""})
return ($quotedArray -join ",")
}
[string] $scriptDirectory = (Split-Path -parent $PSCommandPath)
[string] $clangScript = "$scriptDirectory\clang-build.ps1"
[string[]] $scriptParams = @("-aSolutionsPath", "'$(Get-Location)'")
if (![string]::IsNullOrEmpty($aVcxprojToCompile))
{
$scriptParams += ("-aVcxprojToCompile", (Merge-Array $aVcxprojToCompile))
}
if (![string]::IsNullOrEmpty($aVcxprojToIgnore))
{
$scriptParams += ("-aVcxprojToIgnore", (Merge-Array $aVcxprojToIgnore))
}
if (![string]::IsNullOrEmpty($aVcxprojConfigPlatform))
{
$scriptParams += ("-aVcxprojConfigPlatform", (Merge-Array $aVcxprojConfigPlatform))
}
if (![string]::IsNullOrEmpty($aCppToCompile))
{
$scriptParams += ("-aCppToCompile", (Merge-Array $aCppToCompile))
}
if (![string]::IsNullOrEmpty($localVarCppToIgnore))
{
$scriptParams += ("-aCppToIgnore", (Merge-Array $localVarCppToIgnore))
}
$scriptParams += ("-aClangCompileFlags", (Merge-Array $kClangCompileFlags))
if (![string]::IsNullOrEmpty($aTidyFlags))
{
$scriptParams += ("-aTidyFlags", (Merge-Array (@($aTidyFlags))))
}
if (![string]::IsNullOrEmpty($aTidyFixFlags))
{
$scriptParams += ("-aTidyFixFlags", (Merge-Array (@($aTidyFixFlags))))
}
if (![string]::IsNullOrEmpty($aAfterTidyFixFormatStyle))
{
$scriptParams += ("-aAfterTidyFixFormatStyle", $aAfterTidyFixFormatStyle)
}
if ($localVarUseParallelCompile)
{
$scriptParams += ("-aUseParallelCompile")
}
if ($aContinueOnError)
{
$scriptParams += ("-aContinueOnError")
}
if ($True)
{
$scriptParams += ("-aTreatAdditionalIncludesAsSystemIncludes")
}
if ($aDisableNameRegexMatching)
{
$scriptParams += ("-aDisableNameRegexMatching")
}
$scriptParams += ("-aVisualStudioVersion", $kVisualStudioVersion)
$scriptParams += ("-aVisualStudioSku", $kVisualStudioSku)
$scriptParams += ("-aTidyHeaderFilter", ".*")
Invoke-Expression "&'$clangScript' $scriptParams"

2229
scripts/clang-build.ps1 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,334 @@
# Tests for ClangPowerTools MSBUILD Expression/Condition translation
$Configuration = "Release2"
$Platform = "Win32"
$UserRootDir = "c:\test"
$SolutionDir = "C:\AI Trunk\ClangPowerToolsProblem"
$ProjectDir = "C:\AI Trunk\win"
$TargetName = "YOLOTest"
$varB = 1
# -------------------------------------------------------------------------------------------------------------------
Set-Variable -name "kMsbuildExpressionToPsRules" -option Constant `
-value @(<# backticks are control characters in PS, replace them #>
('`' , '''' )`
<# Temporarily replace $( #> `
, ('\$\s*\(' , '!@#' )`
<# Escape $ #> `
, ('\$' , '`$' )`
<# Put back $( #> `
, ('!@#' , '$(' )`
<# Various operators #> `
, ("([\s\)\'""])!=" , '$1 -ne ' )`
, ("([\s\)\'""])<=" , '$1 -le ' )`
, ("([\s\)\'""])>=" , '$1 -ge ' )`
, ("([\s\)\'""])==" , '$1 -eq ' )`
, ("([\s\)\'""])<" , '$1 -lt ' )`
, ("([\s\)\'""])>" , '$1 -gt ' )`
, ("([\s\)\'""])or" , '$1 -or ' )`
, ("([\s\)\'""])and" , '$1 -and ' )`
<# Use only double quotes #> `
, ("\'" , '"' )`
, ("Exists\((.*?)\)(\s|$)" , '(Exists($1))$2' )`
, ("HasTrailingSlash\((.*?)\)(\s|$)" , '(HasTrailingSlash($1))$2' )`
, ("(\`$\()(Registry:)(.*?)(\))" , '$$(GetRegValue("$3"))' )`
)
Set-Variable -name "kMsbuildConditionToPsRules" -option Constant `
-value @(<# Use only double quotes #> `
("\'" , '"' )`
<# We need to escape double quotes since we will eval() the condition #> `
, ('"' , '""' )`
)
function GetRegValue([Parameter(Mandatory=$true)][string] $regPath)
{
[int] $separatorIndex = $regPath.IndexOf('@')
[string] $valueName = ""
if ($separatorIndex -gt 0)
{
[string] $valueName = $regPath.Substring($separatorIndex + 1)
$regPath = $regPath.Substring(0, $separatorIndex)
}
if ([string]::IsNullOrEmpty($valueName))
{
throw "Cannot retrieve an empty registry value"
}
$regPath = $regPath -replace "HKEY_LOCAL_MACHINE\\", "HKLM:\"
if (Test-Path $regPath)
{
return (Get-Item $regPath).GetValue($valueName)
}
else
{
return ""
}
}
function HasTrailingSlash([Parameter(Mandatory=$true)][string] $str)
{
return $str.EndsWith('\') -or $str.EndsWith('/')
}
function Exists([Parameter(Mandatory=$false)][string] $path)
{
if ([string]::IsNullOrEmpty($path))
{
return $false
}
return Test-Path $path
}
function Evaluate-MSBuildExpression([string] $expression, [switch] $isCondition)
{
Write-Debug "Start evaluate MSBuild expression $expression"
foreach ($rule in $kMsbuildExpressionToPsRules)
{
$expression = $expression -replace $rule[0], $rule[1]
}
if ( !$isCondition -and ($expression.IndexOf('$') -lt 0))
{
# we can stop here, further processing is not required
return $expression
}
[int] $expressionStartIndex = -1
[int] $openParantheses = 0
for ([int] $i = 0; $i -lt $expression.Length; $i += 1)
{
if ($expression.Substring($i, 1) -eq '(')
{
if ($i -gt 0 -and $expressionStartIndex -lt 0 -and $expression.Substring($i - 1, 1) -eq '$')
{
$expressionStartIndex = $i - 1
}
if ($expressionStartIndex -ge 0)
{
$openParantheses += 1
}
}
if ($expression.Substring($i, 1) -eq ')' -and $expressionStartIndex -ge 0)
{
$openParantheses -= 1
if ($openParantheses -lt 0)
{
throw "Parse error"
}
if ($openParantheses -eq 0)
{
[string] $content = $expression.Substring($expressionStartIndex + 2,
$i - $expressionStartIndex - 2)
[int] $initialLength = $content.Length
if ([regex]::Match($content, "[a-zA-Z_][a-zA-Z0-9_\-]+").Value -eq $content)
{
# we have a plain property retrieval
$content = "`${$content}"
}
else
{
# dealing with a more complex expression
$content = $content -replace '(^|\s+|\$\()([a-zA-Z_][a-zA-Z0-9_]+)(\.|\)|$)', '$1$$$2$3'
}
$newCond = $expression.Substring(0, $expressionStartIndex + 2) +
$content + $expression.Substring($i)
$expression = $newCond
$i += ($content.Length - $initialLength)
$expressionStartIndex = -1
}
}
}
Write-Debug "Intermediate PS expression: $expression"
try
{
[string] $toInvoke = "(`$s = ""$expression"")"
if ($isCondition)
{
$toInvoke = "(`$s = ""`$($expression)"")"
}
$res = Invoke-Expression $toInvoke
}
catch
{
write-debug $_.Exception.Message
}
Write-Debug "Evaluated expression to: $res"
return $res
}
function Evaluate-MSBuildCondition([Parameter(Mandatory=$true)][string] $condition)
{
Write-Debug "Evaluating condition $condition"
foreach ($rule in $kMsbuildConditionToPsRules)
{
$condition = $condition -replace $rule[0], $rule[1]
}
$expression = Evaluate-MSBuildExpression -expression $condition -isCondition
if ($expression -ieq "true")
{
return $true
}
if ($expression -ieq "false")
{
return $false
}
[bool] $res = $false
try
{
$res = (Invoke-Expression $expression) -eq $true
}
catch
{
Write-Debug $_.Exception.Message
}
Write-Debug "Evaluated condition to $res"
return $res
}
Clear-Host
function Test-Condition([string] $condition, [bool]$expectation, [switch] $expectFailure)
{
[boolean] $condValue
try
{
$condValue = Evaluate-MSBuildCondition $condition
}
catch
{
if ($expectFailure)
{
Write-Output "TEST OK"
return
}
else
{
Write-Output $_.Exception.Message
throw "Test failed"
}
}
if ($condValue -ne $expectation)
{
Write-Output "Expected $expectation | Got $condValue"
throw "Test failed"
}
Write-Output "TEST OK"
}
function Test-Expression($expresion)
{
$res = Evaluate-MSBuildExpression $expresion
Write-output $res
}
# ----------------------------------------------------------------------------
Test-Condition "'`$(ImportDirectoryBuildProps)' == 'true' and exists('`$(DirectoryBuildPropsPath)')" -expectation $false
Test-Expression '$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\15.0\AD7Metrics\ExpressionEvaluator\{3A12D0B7-C26C-11D0-B442-00A0244A1DD2}\{994B45C4-E6E9-11D2-903F-00C04FA302A1}@LoadInShimManagedEE)'
Test-Expression '$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@InstallationFolder)'
Test-Expression '$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@InstallationFolder)'
Test-Expression '$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A@InstallationFolder)'
Test-Expression '$(GetRegValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@InstallationFolder"))'
Test-Condition "'`$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A@InstallationFolder)' != ''" `
-expectation $true
Test-Condition "'`$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DevDiv\vs\Servicing\11.0\professional@Version)' == ''" `
-expectation $true
Test-Condition -condition "'`$(Configuration)|`$(Platform)'=='Debug|Win32' or '`$(Configuration)' == 'Release2'" `
-expectation $true
Test-Condition -condition "'`$(Platform)'=='x64' or '`$(Platform)'=='Win32' or '`$(Platform)'=='Durango' or exists('`$(UserRootDir)\Microsoft.Cpp.`$(Platform).user.props2')"`
-expectation $true
Test-Condition -condition "exists('c:\ai trunk')"`
-expectation $true
Test-Condition -condition "'`$(Configuration)|`$(Platform)'=='Release|Win32'"`
-expectation $false
Test-Condition -condition '$(Platform.Replace(" ", "")) and $(testB)'`
-expectation $false
Test-Condition -condition '$(Platform) and $(varB)'`
-expectation $true
Test-Condition -condition "exists('`$(UserRootDir)\Microsoft.Cpp.`$(Platform).user.props')"`
-expectation $true
Test-Expression -expression "`$(SolutionDir)\Tools\PropertySheets\Evolution.Module.props"
Test-Expression -expresion "WIN32_LEAN_AND_MEAN and `$(Configuration)"
Test-Condition -condition "exists('`$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(``WindowsMobile, Version=10.0.10240.0``, `$(TargetPlatformIdentifier), `$(TargetPlatformVersion), `$(SDKReferenceDirectoryRoot), `$(SDKExtensionDirectoryRoot), `$(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\WindowsMobile.props')"`
-expectFailure
Test-Expression -expression "`$Foo;`$(ProjectDir);..\..;..\..\third-party"
Test-Condition -condition "`$(TargetName.EndsWith('Test'))"`
-expectation $true
Test-Condition -condition "`$(TargetName.EndsWith('Test2'))"`
-expectation $false
$var = 4
Test-Condition -condition '$(var) == 2 and 4 == 4'`
-expectation $false
Test-Expression -expression "%(ASDASD);`$(TargetName)"
$PkgMicrosoft_Gsl = "..\.."
Test-Condition -condition "Exists('`$(PkgMicrosoft_Gsl)\build\native\Microsoft.Gsl.targets') OR ! Exists('`$(PkgMicrosoft_Gsl)\build\native\Microsoft.Gsl.targets')"`
-expectation $true
$myVar = 'TwoThree'
$MySelector = "One;Two;Three"
Test-Condition -condition "`$(MySelector.Contains(`$(myVar.Substring(3, 3))))"`
-expectation $true
$MySelector = "One;Two;Three"
$myVar = "Two"
Test-Condition -condition "`$(MySelector.Contains(`$(myVar)))"`
-expectation $true
$MySelector = "One;Two;Three"
Test-Condition -condition "`$(MySelector.Contains(Three))"`
-expectFailure
$MySelector = "One;Two;Three"
Test-Condition -condition "`$(MySelector.Contains('Three'))"`
-expectation $true
Test-Condition -condition "`$([System.DateTime]::Now.Year) == 2018"`
-expectation $true
Test-Condition -condition "HasTrailingSlash('c:\windows\')"`
-expectation $true
Test-Condition -condition "HasTrailingSlash('c:\windows\') and hasTrailingSlash('c:\temp/')"`
-expectation $true
$prop = "c:\windows\"
Test-Condition -condition "hasTrailingSlash(`$(prop))"`
-expectation $true

View File

@ -0,0 +1,225 @@
<#
.SYNOPSIS
Compiles or tidies up code from Visual Studio .vcxproj project files.
It sets up the scene required for clang-build.ps1 to do its job, and makes
command-line usage for projects and files quicker.
Before calling sample-clang-build.ps1 you need to set the current directory
to the root source directory.
.PARAMETER aVcxprojToCompile
Alias 'proj'. Array of project(s) to compile. If empty, all projects are compiled.
If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used,
e.g. "msicomp" compiles all msicomp projects.
Can be passed as comma separated values.
.PARAMETER aVcxprojToIgnore
Alias 'proj-ignore'. Array of project(s) to ignore, from the matched ones.
If empty, all already matched projects are compiled.
If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used,
e.g. "msicomp" compiles all msicomp projects.
Can be passed as comma separated values.
.PARAMETER aVcxprojConfigPlatform
Alias 'active-config'. The configuration-platform pair, separated by |,
to be used when processing project files.
E.g. 'Debug|Win32'.
If not specified, the first configuration-plaform found in the current project is used.
.PARAMETER aCppToCompile
Alias 'file'. What cpp(s) to compile from the found project(s). If empty, all CPPs are compiled.
If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used,
e.g. "table" compiles all CPPs containing 'table'.
.PARAMETER aCppToIgnore
Alias 'file-ignore'. Array of file(s) to ignore, from the matched ones.
If empty, all already matched files are compiled.
If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used,
e.g. "table" ignores all CPPs containing 'table'.
Can be passed as comma separated values.
.PARAMETER aUseParallelCompile
Alias 'parallel'. Switch to run in parallel mode, on all logical CPU cores.
.PARAMETER aContinueOnError
Alias 'continue'. Switch to continue project compilation even when errors occur.
.PARAMETER aTreatAdditionalIncludesAsSystemIncludes
Alias 'treat-sai'. Switch to treat project additional include directories as system includes.
.PARAMETER aClangCompileFlags
Alias 'clang-flags'. Flags given to clang++ when compiling project,
alongside project-specific defines.
.PARAMETER aDisableNameRegexMatching
Alias 'literal'. Switch to take project and cpp name filters literally, not by regex matching.
.PARAMETER aTidyFlags
Alias 'tidy'. If not empty clang-tidy will be called with given flags, instead of clang++.
The tidy operation is applied to whole translation units, meaning all directory headers
included in the CPP will be tidied up too. Changes will not be applied, only simulated.
If aTidyFixFlags is present, it takes precedence over this parameter.
.PARAMETER aTidyFixFlags
Alias 'tidy-fix'. If not empty clang-tidy will be called with given flags, instead of clang++.
The tidy operation is applied to whole translation units, meaning all directory headers
included in the CPP will be tidied up too. Changes will be applied to the file(s).
If present, this parameter takes precedence over aTidyFlags.
.PARAMETER aAfterTidyFixFormatStyle
Alias 'format-style'. Used in combination with 'tidy-fix'. If present, clang-tidy will
also format the fixed file(s), using the specified style.
Possible values: - not present, no formatting will be done
- 'file'
Literally 'file', not a placeholder.
Uses .clang-format file in the closest parent directory.
- 'llvm'
- 'google'
- 'webkit'
- 'mozilla'
.EXAMPLE
PS .\sample-clang-build.ps1 -dir -proj foo,bar -file meow -tidy "-*,modernize-*"
<Description of example>
Runs clang-tidy, using "-*,modernize-*", on all CPPs containing 'meow' in their name from
the projects containing 'foo' or 'bar' in their names.
Doesn't actually apply the clang-tidy module changes to CPPs.
It will only print the tidy module output.
.EXAMPLE
PS .\sample-clang-build.ps1 -dir -proj foo,bar -file meow -tidy-fix "-*,modernize-*"
<Description of example>
Runs clang-tidy, using "-*,modernize-*", on all CPPs containing 'meow' in their name from
the projects containing 'foo' or 'bar' in their names.
It will apply all tidy module changes to CPPs.
.EXAMPLE
PS .\sample-clang-build.ps1 -dir -proj foo -proj-ignore foobar
<Description of example>
Runs clang++ on all CPPs in foo... projects, except foobar
.OUTPUTS
Will output Clang warnings and errors to screen. The return code will be 0 for success, >0 for failure.
.NOTES
Author: Gabriel Diaconita
#>
param( [alias("proj")] [Parameter(Mandatory=$false)][string[]] $aVcxprojToCompile
, [alias("proj-ignore")] [Parameter(Mandatory=$false)][string[]] $aVcxprojToIgnore
, [alias("active-config")][Parameter(Mandatory=$false)][string] $aVcxprojConfigPlatform
, [alias("file")] [Parameter(Mandatory=$false)][string] $aCppToCompile
, [alias("file-ignore")] [Parameter(Mandatory=$false)][string[]] $aCppToIgnore
, [alias("parallel")] [Parameter(Mandatory=$false)][switch] $aUseParallelCompile
, [alias("continue")] [Parameter(Mandatory=$false)][switch] $aContinueOnError
, [alias("treat-sai")] [Parameter(Mandatory=$false)][switch] $aTreatAdditionalIncludesAsSystemIncludes
, [alias("literal")] [Parameter(Mandatory=$false)][switch] $aDisableNameRegexMatching
, [alias("tidy")] [Parameter(Mandatory=$false)][string] $aTidyFlags
, [alias("tidy-fix")] [Parameter(Mandatory=$false)][string] $aTidyFixFlags
, [alias("format-style")] [Parameter(Mandatory=$false)][string] $aAfterTidyFixFormatStyle
)
# ------------------------------------------------------------------------------------------------
Set-Variable -name kClangCompileFlags -Option Constant `
-value @( "-Werror"
, "-Wall"
, "-fms-compatibility-version=19.10"
, "-Wmicrosoft"
, "-Wno-invalid-token-paste"
, "-Wno-unknown-pragmas"
, "-Wno-unused-value"
)
Set-Variable -name kVisualStudioVersion -value "2017" -Option Constant
Set-Variable -name kVisualStudioSku -value "Professional" -Option Constant
# ------------------------------------------------------------------------------------------------
Function Merge-Array([string[]] $aArray)
{
# we need to individually wrap items into quotes as values
# can contain PS control characters (e.g. - in -std=c++14)
$quotedArray = ($aArray | ForEach-Object { """$_"""})
return ($quotedArray -join ",")
}
[string] $scriptDirectory = (Split-Path -parent $PSCommandPath)
[string] $clangScript = "$scriptDirectory\clang-build.ps1"
[string[]] $scriptParams = @("-aSolutionsPath", "'$(Get-Location)'")
if (![string]::IsNullOrEmpty($aVcxprojToCompile))
{
$scriptParams += ("-aVcxprojToCompile", (Merge-Array $aVcxprojToCompile))
}
if (![string]::IsNullOrEmpty($aVcxprojToIgnore))
{
$scriptParams += ("-aVcxprojToIgnore", (Merge-Array $aVcxprojToIgnore))
}
if (![string]::IsNullOrEmpty($aVcxprojConfigPlatform))
{
$scriptParams += ("-aVcxprojConfigPlatform", (Merge-Array $aVcxprojConfigPlatform))
}
if (![string]::IsNullOrEmpty($aCppToCompile))
{
$scriptParams += ("-aCppToCompile", (Merge-Array $aCppToCompile))
}
if (![string]::IsNullOrEmpty($aCppToIgnore))
{
$scriptParams += ("-aCppToIgnore", (Merge-Array $aCppToIgnore))
}
$scriptParams += ("-aClangCompileFlags", (Merge-Array $kClangCompileFlags))
if (![string]::IsNullOrEmpty($aTidyFlags))
{
$scriptParams += ("-aTidyFlags", (Merge-Array (@($aTidyFlags))))
}
if (![string]::IsNullOrEmpty($aTidyFixFlags))
{
$scriptParams += ("-aTidyFixFlags", (Merge-Array (@($aTidyFixFlags))))
}
if (![string]::IsNullOrEmpty($aAfterTidyFixFormatStyle))
{
$scriptParams += ("-aAfterTidyFixFormatStyle", $aAfterTidyFixFormatStyle)
}
if ($aUseParallelCompile)
{
$scriptParams += ("-aUseParallelCompile")
}
if ($aContinueOnError)
{
$scriptParams += ("-aContinueOnError")
}
if ($aTreatAdditionalIncludesAsSystemIncludes)
{
$scriptParams += ("-aTreatAdditionalIncludesAsSystemIncludes")
}
if ($aDisableNameRegexMatching)
{
$scriptParams += ("-aDisableNameRegexMatching")
}
$scriptParams += ("-aVisualStudioVersion", $kVisualStudioVersion)
$scriptParams += ("-aVisualStudioSku", $kVisualStudioSku)
$scriptParams += ("-aTidyHeaderFilter", ".*")
Invoke-Expression "&'$clangScript' $scriptParams"