Compile.ps1 (210 lines of code) (raw):

<# .SYNOPSIS Compile a project on various platforms. .DESCRIPTION Compile the given project file with the given configuration, on the given platform, using the given compiler .PARAMETER workingDirectory specify the working folder where compilation will talke place. This is the folder where the project file is found. .PARAMETER slnOrPrjFile the project fileName whatever it is (sln, make, xcworkspace). Only provide the project filename here, path to this file must be set as the working folder. .PARAMETER configuration the configuration used to compile your project. Default to 'debug'. .PARAMETER platform the platform used to compile your project (Any CPU, x64, win32,...) .PARAMETER vsVersion The version of visual studio toolchain you want to use for your build. Can be : - a visual studio number, like "2019" or "2022" - a windows name (with syntax 'windows-xxxx'), like "windows-2019" or "windows-2022" - the value "latest", to use latest available visual studio version available on the running machine - omit, if you have already setup everything for visual build toolchain to run. The purpose of this parameter is to search for the requested visual studio toolchain, and run appropriate visual studio batch to setup that toolchain. .PARAMETER compiler The compiler you want to use for your build. available values are "dotnet", "xcode", "make", "msbuild" .PARAMETER scheme The 'scheme' parameter required when the xcodebuild compiler is selected. Ignored for all other compilers. #> param ([string] $slnOrPrjFile, [string] $configuration='debug', [string] $platform, [string] $vsVersion, [string] $compiler, [string] $workingDirectory, [string] $scheme) function Get-MsBuildCmd { param ([int]$VsVersion) #find 'where' tool $VsWhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio' 'Installer' 'vswhere.exe' if (-not(Test-Path -Path $VsWhere -PathType Leaf)) { throw "could not find '$VsWhere' file on local machine" } if ($vsVersion -eq 0) { # latest available visual version requested $vsVersions = &"$VsWhere" -latest -products * -property installationPath $vsMsBuildCmd = Join-Path $vsVersions 'Common7' 'Tools' if (Test-Path -Path $vsMsBuildCmd -PathType Container) { #found ! Write-Host "msbuild batch path : $vsMsBuildCmd" return $vsMsBuildCmd } } else { # specific visual version required $vsVersions = &"$VsWhere" -products * -property installationPath # scan all available versions, find the first one with visual version number in the path foreach ($vsVersionsItem in $vsVersions) { $vsMsBuildCmd = Join-Path $vsVersionsItem 'Common7' 'Tools' if (Test-Path -Path $vsMsBuildCmd -PathType Container ) { if ($vsMsBuildCmd -like "*$VsVersion*") { # found ! Write-Host "msbuild batch path : $vsMsBuildCmd" return $vsMsBuildCmd } } } } } try { $runProcessPath = Join-Path "$(Get-Location)" "RunProcess.ps1" Write-Host "--- Compile $slnOrPrjFile, $configuration|$platform with $vsVersion $compiler" # change working folder if one was given if($workingDirectory -ne "") { Push-Location -Path $workingDirectory if (-not $?) { throw "error when changing working dir : $LASTEXITCODE" } } Write-Host "working folder : $(Get-Location)" # if a VsVersion was requested, find and run matching VsMsBuildCommand, else just run the build that is supposed to be in the path already if($vsVersion -ne "") { # by default, get latest available vs version [int]$vsVersionNumber = 0 if ($vsVersion -ne "latest") { # a specific version is required # remove potential "windows-" prefix on given vsVersion $vsVersion = $vsVersion -replace "windows-" $vsVersionNumber = [int]$vsVersion } # setup Build toolchain for given visual studio version Write-Host "setup toolchain" # find requested visual studio version $msBuildCommand = Get-MsBuildCmd -VsVersion $vsVersionNumber if ($msBuildCommand -eq "") { # not found throw "could not find visual build toolchain $vsVersion" } # set msbuild batch path as current working folder Push-Location $msBuildCommand if (-not $?) { throw "error when changing working dir : $LASTEXITCODE" } # run visual studio setup batch and gather all changed environment variables. this is required because batch is run in another process, # so we must gather result environment variable to update the ones in powershell process $modifiedEnvVars = cmd /c "VsMSBuildCmd.bat &set" # set powershell process env vars from the one returned by visual studio setup batch foreach ($line in $modifiedEnvVars) { If ($line -match "=") { $v = $line.split("=") Set-Item -Force -Path "ENV:\$($v[0])" -Value "$($v[1])" } } # back to previous working folder Pop-Location } Write-Host "working folder : $(Get-Location)" $binLogName = "msbuild_$configuration.binlog" if ($compiler -eq "dotnet") { if ($IsWindows) { Write-Host "dotnet compile on Windows" #dotnet compile $msBuildLog = Join-Path 'tmp' 'msbuild' 'windows' $binLogName dotnet build `"$slnOrPrjFile`" -nologo -v m -c `"$configuration`" -bl:`"$msBuildLog`" if($LASTEXITCODE -ne 0) { throw "error $LASTEXITCODE during dotnet compile" } Write-Host "compile success" } else { Write-Host "dotnet compile on Linux" #dotnet compile $osPath = $ImageOS + $platform $msBuildLog = Join-Path 'tmp' 'msbuild' $osPath $binLogName dotnet build -nologo -v m -bl:`"$msBuildLog`" -p:UseAppHost=true /p:_EnableMacOSCodeSign=false `"$slnOrPrjFile`" --configuration `"$configuration`" if($LASTEXITCODE -ne 0) { throw "error $LASTEXITCODE during dotnet compile" } Write-Host "compile success" } } elseif ($compiler -eq "xcode") { #xcode compile Write-Host "xcode compile" Write-Host $scheme # directly call xcodebuild, don't use start-process xcodebuild -workspace "$slnOrPrjFile" -configuration "$configuration" -scheme "$scheme" if($LASTEXITCODE -ne 0) { throw "error $LASTEXITCODE during xcode compile" } Write-Host "compile success" } elseif ($compiler -eq "make") { #make compile Write-Host "make compile" make -f "$slnOrPrjFile" config="$configuration" Write-Host "exit code : $LASTEXITCODE" if($LASTEXITCODE -and $LASTEXITCODE -ne 0) { Write-Error "error $LASTEXITCODE during make execution" exit $LASTEXITCODE } Write-Host "compile success" } else { #msbuild compile Write-Host "msbuild compile" $msBuildLog = Join-Path 'tmp' 'msbuild' 'windows' $binLogName msbuild $slnOrPrjFile -bl:"$msBuildLog" -clp:Summary -t:rebuild -restore /nologo /verbosity:m /p:Configuration="$configuration" /p:Platform="$platform" /maxcpucount /p:CL_MPCount=$env:NUMBER_OF_PROCESSORS Write-Host "exit code : $LASTEXITCODE" if($LASTEXITCODE -and $LASTEXITCODE -ne 0) { Write-Error "error $LASTEXITCODE during msbuild compile" exit $LASTEXITCODE } Write-Host "compile success" } } catch { Write-Error $PSItem.Exception exit 1 } finally { # back to previous working folder, if one was pushed if($workingDirectory -ne "") { Pop-Location Write-Host "working folder : $(Get-Location)" } }