forked from Mirrors/openclonk
CI: Use AppVeyor to build MSVC binaries
parent
0d7738dce5
commit
354b6be1c6
|
@ -0,0 +1,25 @@
|
||||||
|
version: "{build}"
|
||||||
|
pull_requests:
|
||||||
|
do_not_increment_build_number: true
|
||||||
|
shallow_clone: true
|
||||||
|
|
||||||
|
cache: ..\openclonk-cache
|
||||||
|
|
||||||
|
configuration: RelWithDebInfo
|
||||||
|
platform:
|
||||||
|
- Win32
|
||||||
|
- x64
|
||||||
|
|
||||||
|
install:
|
||||||
|
- ps: "& $env:APPVEYOR_BUILD_FOLDER\\tools\\ci\\appv-Install.ps1"
|
||||||
|
before_build:
|
||||||
|
- ps: "& $env:APPVEYOR_BUILD_FOLDER\\tools\\ci\\appv-BeforeBuild.ps1"
|
||||||
|
build:
|
||||||
|
project: ../openclonk-build/openclonk.sln
|
||||||
|
verbosity: minimal
|
||||||
|
after_build:
|
||||||
|
- ps: "& $env:APPVEYOR_BUILD_FOLDER\\tools\\ci\\appv-AfterBuild.ps1"
|
||||||
|
test_script:
|
||||||
|
- ps: "& $env:APPVEYOR_BUILD_FOLDER\\tools\\ci\\appv-Test.ps1"
|
||||||
|
|
||||||
|
deploy: off
|
|
@ -0,0 +1,118 @@
|
||||||
|
pushd $env:BUILD_TARGET_FOLDER
|
||||||
|
trap {popd}
|
||||||
|
|
||||||
|
[void]([System.Reflection.Assembly]::LoadWithPartialName('Microsoft.Build'))
|
||||||
|
$projects = New-Object Microsoft.Build.Evaluation.ProjectCollection
|
||||||
|
$projects.SetGlobalProperty('Configuration', $env:CONFIGURATION)
|
||||||
|
|
||||||
|
function Resolve-CanonicalPath {
|
||||||
|
param([string]$Path)
|
||||||
|
Add-Type -TypeDefinition @'
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
|
||||||
|
public static class ResolveCanonicalPath {
|
||||||
|
[DllImport("kernel32.dll", EntryPoint="CreateFileW", CharSet=CharSet.Unicode, SetLastError=true)]
|
||||||
|
public static extern SafeFileHandle CreateFile(
|
||||||
|
string lpFileName,
|
||||||
|
int dwDesiredAccess,
|
||||||
|
int dwShareMode,
|
||||||
|
IntPtr securityAttributes,
|
||||||
|
int dwCreationDisposition,
|
||||||
|
int dwFlagsAndAttributes,
|
||||||
|
IntPtr hTemplateFile);
|
||||||
|
[DllImport("kernel32.dll", EntryPoint="GetFinalPathNameByHandleW", CharSet=CharSet.Unicode, SetLastError=true)]
|
||||||
|
public static extern int GetFinalPathNameByHandle(
|
||||||
|
IntPtr hFile,
|
||||||
|
[In, Out] System.Text.StringBuilder lpszFilePath,
|
||||||
|
int cchFilePath,
|
||||||
|
int dwFlags);
|
||||||
|
}
|
||||||
|
'@
|
||||||
|
# Ask the file system to provide us with the canonical path, which includes
|
||||||
|
# proper capitalization
|
||||||
|
$fh = [ResolveCanonicalPath]::CreateFile($Path, 0, 2, [System.IntPtr]::Zero, 3, 0x2000000, [System.IntPtr]::Zero)
|
||||||
|
try {
|
||||||
|
$real_path = New-Object System.Text.StringBuilder 512
|
||||||
|
$rp_len = [ResolveCanonicalPath]::GetFinalPathNameByHandle($fh.DangerousGetHandle(), $real_path, $real_path.Capacity, 0)
|
||||||
|
if ($rp_len -lt 0) {
|
||||||
|
throw [System.ComponentModel.Win32Exception]::new([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())
|
||||||
|
}
|
||||||
|
$real_path = $real_path.ToString()
|
||||||
|
if ($real_path.StartsWith('\\?\')) {
|
||||||
|
return $real_path.Substring(4)
|
||||||
|
}
|
||||||
|
return $real_path
|
||||||
|
} finally {
|
||||||
|
$fh.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Add-SourceServerData {
|
||||||
|
param([string]$pdb)
|
||||||
|
|
||||||
|
$srctool = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\srcsrv\srctool.exe"
|
||||||
|
$pdbstr = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\srcsrv\pdbstr.exe"
|
||||||
|
|
||||||
|
$temp_name = New-TemporaryFile
|
||||||
|
try {
|
||||||
|
$temp = New-Object System.IO.StreamWriter $temp_name.OpenWrite()
|
||||||
|
$temp.WriteLine(@"
|
||||||
|
SRCSRV: ini ------------------------------------------------
|
||||||
|
VERSION=2
|
||||||
|
VERCTRL=http
|
||||||
|
SRCSRV: variables ------------------------------------------
|
||||||
|
DEPOT=https://raw.githubusercontent.com/$env:APPVEYOR_REPO_NAME/%COMMIT%/
|
||||||
|
COMMIT=$env:APPVEYOR_REPO_COMMIT
|
||||||
|
SRCSRVTRG=%DEPOT%%var2%
|
||||||
|
SRCSRV: source files ---------------------------------------
|
||||||
|
"@)
|
||||||
|
& $srctool -r $pdb | %{
|
||||||
|
Resolve-CanonicalPath $_
|
||||||
|
} | ?{
|
||||||
|
# Filter everything outside of the source path
|
||||||
|
$_.StartsWith($env:APPVEYOR_BUILD_FOLDER, [System.StringComparison]::OrdinalIgnoreCase)
|
||||||
|
} | ?{
|
||||||
|
# Filter everything that doesn't exist
|
||||||
|
Test-Path $_
|
||||||
|
} | %{
|
||||||
|
# Strip source folder prefix for building an URL
|
||||||
|
$path = $_.Substring($env:APPVEYOR_BUILD_FOLDER.Length)
|
||||||
|
$path = $path.TrimStart(@([System.IO.Path]::DirectorySeparatorChar, [System.IO.Path]::AltDirectorySeparatorChar))
|
||||||
|
$path = $path.Replace('\','/')
|
||||||
|
$temp.WriteLine("$_*$path")
|
||||||
|
}
|
||||||
|
$temp.WriteLine('SRCSRV: end ------------------------------------------------')
|
||||||
|
$temp.Close()
|
||||||
|
# Write source info to PDB
|
||||||
|
& $pdbstr -w -p:$pdb -i:$($temp_name.FullName) -s:srcsrv
|
||||||
|
} finally {
|
||||||
|
$temp_name.Delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $env:APPVEYOR) {
|
||||||
|
function Push-AppveyorArtifact {
|
||||||
|
param([string]$Path)
|
||||||
|
"Uploading $Path.... (dry run)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Get-Item *.vcxproj | %{
|
||||||
|
$p = $projects.LoadProject($_.FullName)
|
||||||
|
if ($p.GetPropertyValue('ConfigurationType') -eq 'Application') {
|
||||||
|
# For all executable files
|
||||||
|
$binary = $p.GetPropertyValue('TargetPath')
|
||||||
|
if (Test-Path $binary) {
|
||||||
|
# Upload the executable itself as an artifact
|
||||||
|
Push-AppveyorArtifact $binary
|
||||||
|
$pdb = $p.ItemDefinitions['Link'].GetMetadataValue('ProgramDataBaseFile')
|
||||||
|
if (Test-Path $pdb) {
|
||||||
|
# If we generated a .pdb file, add source server information
|
||||||
|
Add-SourceServerData $pdb
|
||||||
|
Push-AppveyorArtifact $pdb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
$ErrorActionPreference='Stop'
|
||||||
|
|
||||||
|
switch ($env:PLATFORM) {
|
||||||
|
'Win32' {
|
||||||
|
$cmake_generator = 'Visual Studio 14 2015'
|
||||||
|
$qt = 'C:\Qt\5.7\msvc2015'
|
||||||
|
}
|
||||||
|
'x64' {
|
||||||
|
$cmake_generator = 'Visual Studio 14 2015 Win64'
|
||||||
|
$qt = 'C:\Qt\5.7\msvc2015_64'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pushd $env:BUILD_TARGET_FOLDER
|
||||||
|
try {
|
||||||
|
$(cmake --version)[0]
|
||||||
|
$ErrorActionPreference='SilentlyContinue'
|
||||||
|
cmake -G $cmake_generator -DCMAKE_PREFIX_PATH:PATH="$env:BUILD_DEPS_FOLDER\$env:PLATFORM;$qt_path" $env:APPVEYOR_BUILD_FOLDER 2>&1
|
||||||
|
$ErrorActionPreference='Stop'
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
if (Test-Path CMakeFiles\CMakeOutput.log) {
|
||||||
|
Push-AppveyorArtifact CMakeFiles\CMakeOutput.log
|
||||||
|
}
|
||||||
|
if (Test-Path CMakeFiles\CMakeError.log) {
|
||||||
|
Push-AppveyorArtifact CMakeFiles\CMakeError.log
|
||||||
|
}
|
||||||
|
throw "CMake invocation failed with code $LASTEXITCODE"
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
popd
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
$ErrorActionPreference='Stop'
|
||||||
|
|
||||||
|
if (-not $env:APPVEYOR) {
|
||||||
|
function Set-AppveyorBuildVariable {
|
||||||
|
param([string]$Name, [string]$Value)
|
||||||
|
Set-Content -Path "env:$Name" -Value $Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Calculate build paths.
|
||||||
|
$source_path = $env:APPVEYOR_BUILD_FOLDER
|
||||||
|
if ($source_path -eq $null) {
|
||||||
|
$source_path = $PWD.Path
|
||||||
|
}
|
||||||
|
$build_path = $env:BUILD_TARGET_FOLDER
|
||||||
|
$slug = [System.IO.Path]::GetFileName($source_path)
|
||||||
|
$prefix = [System.IO.Path]::GetDirectoryName($source_path)
|
||||||
|
if ($build_path -eq $null) {
|
||||||
|
$build_path = [System.IO.Path]::Combine($prefix, "${slug}-build")
|
||||||
|
Set-AppveyorBuildVariable -Name BUILD_TARGET_FOLDER -Value $build_path
|
||||||
|
}
|
||||||
|
$deps_path = $env:BUILD_DEPS_FOLDER
|
||||||
|
if ($deps_path -eq $null) {
|
||||||
|
$deps_path = [System.IO.Path]::Combine($prefix, "${slug}-deps")
|
||||||
|
Set-AppveyorBuildVariable -Name BUILD_DEPS_FOLDER -Value $deps_path
|
||||||
|
}
|
||||||
|
$cache_path = $env:BUILD_CACHE_FOLDER
|
||||||
|
if ($cache_path -eq $null) {
|
||||||
|
$cache_path = [System.IO.Path]::Combine($prefix, "${slug}-cache")
|
||||||
|
Set-AppveyorBuildVariable -Name BUILD_CACHE_FOLDER -Value $cache_path
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create folders we'll use
|
||||||
|
if (-not (Test-Path $build_path)) {
|
||||||
|
[void](mkdir $build_path)
|
||||||
|
}
|
||||||
|
if (-not (Test-Path $deps_path)) {
|
||||||
|
[void](mkdir $deps_path)
|
||||||
|
}
|
||||||
|
if (-not (Test-Path $cache_path)) {
|
||||||
|
[void](mkdir $cache_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Source path: $source_path"
|
||||||
|
Write-Host "Building in: $build_path"
|
||||||
|
if ($build_path -eq $source_path) {
|
||||||
|
Write-Host 'Build type: in-tree (deprecated)'
|
||||||
|
} else {
|
||||||
|
Write-Host 'Build type: out-of-tree (recommended)'
|
||||||
|
}
|
||||||
|
|
||||||
|
function Update-BuildCache {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[Uri]
|
||||||
|
$Url,
|
||||||
|
[string]
|
||||||
|
$File = $Url.Segments[-1],
|
||||||
|
[bool]
|
||||||
|
$Force = $false
|
||||||
|
)
|
||||||
|
$local_file = $File
|
||||||
|
if (-not [System.IO.Path]::IsPathRooted($local_file)) {
|
||||||
|
$local_file = [System.IO.Path]::Combine($cache_path, $local_file)
|
||||||
|
}
|
||||||
|
Write-Host -NoNewline "Updating $([System.IO.Path]::GetFileName($local_file))... "
|
||||||
|
$fi = New-Object System.IO.FileInfo $local_file
|
||||||
|
[System.Net.HttpWebRequest]$req = [System.Net.WebRequest]::CreateHttp($Url)
|
||||||
|
$req.Method = 'GET'
|
||||||
|
# No need to do error handling because System.IO.FileInfo will return a
|
||||||
|
# date in the past if the file does not exist
|
||||||
|
$req.IfModifiedSince = $fi.LastWriteTime
|
||||||
|
try {
|
||||||
|
[System.Net.HttpWebResponse]$resp = $req.GetResponse()
|
||||||
|
$target_stream = $fi.Create()
|
||||||
|
$resp.GetResponseStream().CopyTo($target_stream)
|
||||||
|
$target_stream.Dispose()
|
||||||
|
$fi.LastWriteTime = $resp.LastModified
|
||||||
|
Write-Host 'done'
|
||||||
|
} catch [System.Net.WebException] {
|
||||||
|
if ($_.Exception.Response.StatusCode -eq [System.Net.HttpStatusCode]::NotModified) {
|
||||||
|
Write-Host 'unchanged'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Write-Host 'failed!'
|
||||||
|
throw $_.Exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update dependencies
|
||||||
|
pushd $deps_path
|
||||||
|
try {
|
||||||
|
# If you want to use the build dependencies for yourself, please note that
|
||||||
|
# this archive is a tarbomb, i.e. it doesn't contain a single root directory
|
||||||
|
Update-BuildCache 'https://autobuild.openclonk.org/static/binaries/appveyor-deps.tar.xz'
|
||||||
|
cmake -E tar xJ $cache_path\appveyor-deps.tar.xz
|
||||||
|
} finally {
|
||||||
|
popd
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
pushd $env:BUILD_TARGET_FOLDER
|
||||||
|
trap {popd}
|
||||||
|
|
||||||
|
[void]([System.Reflection.Assembly]::LoadWithPartialName('Microsoft.Build'))
|
||||||
|
$projects = New-Object Microsoft.Build.Evaluation.ProjectCollection
|
||||||
|
$projects.SetGlobalProperty('Configuration', $env:CONFIGURATION)
|
||||||
|
|
||||||
|
Get-Item tests\*.vcxproj | %{
|
||||||
|
$p = $projects.LoadProject($_.FullName)
|
||||||
|
if ($p.GetPropertyValue('ConfigurationType') -eq 'Application') {
|
||||||
|
$binary = $p.GetPropertyValue('TargetPath')
|
||||||
|
if (Test-Path $binary) {
|
||||||
|
& $binary "--gtest_output=xml:$binary.xml"
|
||||||
|
$client = New-Object System.Net.WebClient
|
||||||
|
$client.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", "$binary.xml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue