aboutsummaryrefslogtreecommitdiffstats
path: root/coin/provisioning/common/windows/protobuf.ps1
blob: 306d33979cc275284d77fb8c4c2d180be98d9a0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

. "$PSScriptRoot\helpers.ps1"

# Here we build protobuf libraries for MinGW and MSVC.
# Since it's a c++ library we need both msvc and mingw because they mangle symbols differently.
# For MSVC it builds with both debug and release configurations because of the visual c++ runtime.
# For MinGW we only need one, so we only build with release.
# The function below takes care of the common part of building - invoking cmake,
# calling ninja and installing it to a directory which we set an environment variable to.
# Because we have two compilers we also have two env. vars. and then each
# config in CI has the Protobuf_ROOT set to the appropriate one.
function build-install-protobuf {
    param(
        [string]$CC,
        [string]$CXX,
        [string]$BuildType,
        [string]$Postfix, # Used for install-path and the environment variable name
        [string[]]$ExtraArguments = @()
    )
    $installPrefix = "C:\Utils\protobuf"
    $installPath = "${installPrefix}-$Postfix"
    Write-Output "Configuring and building protobuf for $CXX"
    $oldCC = $env:CC
    $oldCXX = $env:CXX
    $env:CC = $CC
    $env:CXX = $CXX
    mkdir build
    Push-Location build
    cmake .. -G"Ninja Multi-Config" -DCMAKE_CONFIGURATION_TYPES="$BuildType" -DCMAKE_INSTALL_PREFIX="$installPath" -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_WITH_ZLIB=OFF $ExtraArguments
    # ninja install:all # This is broken and does not work
    foreach ($config in $BuildType.split(";")) {
        ninja -f "build-$config.ninja" install
    }
    $env:CC = $oldCC
    $env:CXX = $oldCXX
    Set-EnvironmentVariable "Protobuf_ROOT_$Postfix" "$InstallPath"
    Pop-Location
    Remove build
}

function Find-Tool {
    param(
        [string]$Name,
        [string]$Path
    )
    # Is tool missing from path?
    if (!(Get-Command $Name -ErrorAction SilentlyContinue)) {
        # Is tool in the $Path directory?
        if (Test-Path "$Path\$Name") {
            $env:Path += ";$Path"
        }
        else {
            throw "Cannot find $Name in path or $Name in $Name, something is configured wrong"
        }
    }
}
# This script is fairly late in provisioning so both of these should be present!
Find-Tool -Name "cmake.exe" -Path "C:\CMake\bin"
Find-Tool -Name "ninja.exe" -Path "C:\Utils\Ninja"

$version = "21.9"
$sha1 = "3226a0e49d048759b702ae524da79387c59f05cc"
$internalUrl = "http://ci-files01-hki.intra.qt.io/input/protobuf/protobuf-all-$version.zip"
$externalUrl = "https://github.com/protocolbuffers/protobuf/releases/download/v$version/protobuf-all-$version.zip"

$targetDir = "$env:HOMEDRIVE\$env:HOMEPATH\protobuf-$version"
$targetFile = "$targetDir.zip"
Download  $externalUrl $internalUrl $targetFile
Verify-Checksum $targetFile $sha1
Extract-7Zip $targetFile (Join-Path $env:HOMEDRIVE $env:HOMEPATH)
Remove $targetFile


# cd into the cmake directory where the CMakeLists.txt file is located
# then we build in a build\ subfolder there for simplicity's sake
Push-Location $targetDir

### MinGW

# Check if mingw is where we expect it to be and add it to path:
$mingwPath = "C:\MINGW1120\mingw64\bin"
if (!(Test-Path $mingwPath)) {
    throw "Cannot find mingw in $mingwPath, something is configured wrong"
}

$oldPath = $env:Path
$env:Path = "$mingwPath;$env:Path"
build-install-protobuf -CC "gcc" -CXX "g++" -BuildType "Release" -Postfix "mingw"
$env:Path = $oldPath

### LLVM MinGW

$llvmMingwPath = "C:\llvm-mingw"
if (!(Test-Path $llvmMingwPath)) {
    throw "Cannot find llvm-mingw in $llvmMingwPath, something is configured wrong"
}

$oldPath = $env:Path
$env:Path = "$llvmMingwPath\bin;$env:Path"
build-install-protobuf -CC "clang" -CXX "clang++" -BuildType "Release" -Postfix "llvm_mingw"
$env:Path = $oldPath

### MSVC

# Add cl to path if it is not already there
if (!(Get-Command cl.exe -ErrorAction SilentlyContinue)) {
    $vswhere = "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"
    $vc_component = "Microsoft.VisualStudio.Component.VC.CoreIde"
    # We pick the oldest build tools we can find and use that to be compatible with it and any newer version:
    # If MSVC has an ABI break this will stop working, and yet another build must be added.
    $vs_location = (& $vswhere -nologo -products * -requires $vc_component -sort -format value -property installationPath | Select-Object -Last 1)
    $vcvars_location = Join-Path $vs_location "VC\Auxiliary\Build\"

    Push-Location $vcvars_location

    # This snippet was stolen from https://stackoverflow.com/a/2124759
    # Grabs all the environment variables that the script has set and assigns it
    # to environment variables in PowerShell (calling batch files creates a
    # cmd.exe instance which does not propagate environment variables)
    cmd /c "vcvarsall.bat $env:PROCESSOR_ARCHITECTURE & set" |
    ForEach-Object {
        if ($_ -match "=") {
            $v = $_.Split("=");
            Set-Item -Force -Path "ENV:\$($v[0])" -Value "$($v[1])"
        }
    }

    Pop-Location
}

# We pass along an extra argument to stop protobuf linking with the static runtime
build-install-protobuf -CC "cl" -CXX "cl" -BuildType "Release" -Postfix "msvc" -ExtraArguments @("-Dprotobuf_MSVC_STATIC_RUNTIME=OFF")

$env:Path = $oldPath
Pop-Location
Remove $targetDir

Write-Output "Protobuf = $version" >> ~/versions.txt