182 lines
8.0 KiB
PowerShell
182 lines
8.0 KiB
PowerShell
|
|
param(
|
||
|
|
[ValidateRange(1, 32)]
|
||
|
|
[int]$Jobs = 4,
|
||
|
|
[switch]$Fresh
|
||
|
|
)
|
||
|
|
|
||
|
|
$ErrorActionPreference = "Stop"
|
||
|
|
. (Join-Path $PSScriptRoot "native_dep_versions.ps1")
|
||
|
|
|
||
|
|
$Cmake = Join-Path $CmakeRoot "bin\cmake.exe"
|
||
|
|
foreach ($required in @($Cmake, $Make, (Join-Path $MingwBin "gcc.exe"),
|
||
|
|
(Join-Path $MingwBin "g++.exe"), $GrpcSource)) {
|
||
|
|
if (-not (Test-Path -LiteralPath $required)) { throw "Required path not found: $required" }
|
||
|
|
}
|
||
|
|
|
||
|
|
function Enable-OldMingwProtobufCompatibility {
|
||
|
|
$protobufRoot = Join-Path $GrpcSource "third_party\protobuf\src\google\protobuf"
|
||
|
|
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
|
||
|
|
|
||
|
|
function Set-TextFile([string]$path, [string]$content) {
|
||
|
|
$current = [System.IO.File]::ReadAllText($path)
|
||
|
|
if ($current -ne $content) {
|
||
|
|
[System.IO.File]::WriteAllText($path, $content, $utf8NoBom)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$portDef = Join-Path $protobufRoot "port_def.inc"
|
||
|
|
$content = [System.IO.File]::ReadAllText($portDef)
|
||
|
|
$newline = if ($content.Contains("`r`n")) { "`r`n" } else { "`n" }
|
||
|
|
if (-not $content.Contains("PROTOBUF_MINGW_CONSTEXPR")) {
|
||
|
|
$anchor = "#define PROTOBUF_CONSTINIT${newline}#endif${newline}"
|
||
|
|
$macro = @(
|
||
|
|
"#define PROTOBUF_CONSTINIT",
|
||
|
|
"#endif",
|
||
|
|
"",
|
||
|
|
"#ifdef PROTOBUF_MINGW_CONSTEXPR",
|
||
|
|
"#error PROTOBUF_MINGW_CONSTEXPR was previously defined",
|
||
|
|
"#endif",
|
||
|
|
"#if defined(__MINGW32__) && __GNUC__ < 8",
|
||
|
|
"#define PROTOBUF_MINGW_CONSTEXPR",
|
||
|
|
"#else",
|
||
|
|
"#define PROTOBUF_MINGW_CONSTEXPR constexpr",
|
||
|
|
"#endif",
|
||
|
|
""
|
||
|
|
) -join $newline
|
||
|
|
if (-not $content.Contains($anchor)) { throw "Cannot patch Protobuf port_def.inc" }
|
||
|
|
Set-TextFile $portDef $content.Replace($anchor, $macro)
|
||
|
|
}
|
||
|
|
|
||
|
|
$portUndef = Join-Path $protobufRoot "port_undef.inc"
|
||
|
|
$content = [System.IO.File]::ReadAllText($portUndef)
|
||
|
|
$newline = if ($content.Contains("`r`n")) { "`r`n" } else { "`n" }
|
||
|
|
if (-not $content.Contains("#undef PROTOBUF_MINGW_CONSTEXPR")) {
|
||
|
|
$anchor = "#undef PROTOBUF_CONSTINIT${newline}"
|
||
|
|
if (-not $content.Contains($anchor)) { throw "Cannot patch Protobuf port_undef.inc" }
|
||
|
|
Set-TextFile $portUndef $content.Replace(
|
||
|
|
$anchor, "$anchor#undef PROTOBUF_MINGW_CONSTEXPR${newline}")
|
||
|
|
}
|
||
|
|
|
||
|
|
$mutexHeader = Join-Path $protobufRoot "stubs\mutex.h"
|
||
|
|
$content = [System.IO.File]::ReadAllText($mutexHeader)
|
||
|
|
$pattern = '(?s)(class GOOGLE_PROTOBUF_CAPABILITY\("mutex"\) PROTOBUF_EXPORT WrappedMutex \{\r?\n public:\r?\n).*?( void Lock)'
|
||
|
|
$content = [regex]::Replace(
|
||
|
|
$content, $pattern, '${1} PROTOBUF_MINGW_CONSTEXPR WrappedMutex() {}' + $newline + '${2}', 1)
|
||
|
|
if (-not $content.Contains("PROTOBUF_MINGW_CONSTEXPR WrappedMutex")) {
|
||
|
|
throw "Cannot patch Protobuf mutex.h"
|
||
|
|
}
|
||
|
|
Set-TextFile $mutexHeader $content
|
||
|
|
|
||
|
|
$mapFieldHeader = Join-Path $protobufRoot "map_field.h"
|
||
|
|
$content = [System.IO.File]::ReadAllText($mapFieldHeader)
|
||
|
|
$content = [regex]::Replace(
|
||
|
|
$content,
|
||
|
|
'(?s)#if defined\(__MINGW32__\) && __GNUC__ < 8\r?\n#define PROTOBUF_MAP_FIELD_CONSTEXPR.*?#endif\r?\n\r?\n(?=class PROTOBUF_EXPORT MapFieldBase)',
|
||
|
|
'')
|
||
|
|
$content = $content.Replace("PROTOBUF_MAP_FIELD_CONSTEXPR", "PROTOBUF_MINGW_CONSTEXPR")
|
||
|
|
$content = [regex]::Replace($content, '(?m)^#undef PROTOBUF_MINGW_CONSTEXPR\r?\n', '')
|
||
|
|
$content = [regex]::Replace(
|
||
|
|
$content,
|
||
|
|
'explicit constexpr (MapFieldBase|TypeDefinedMapFieldBase|MapField)\(ConstantInitialized',
|
||
|
|
'explicit PROTOBUF_MINGW_CONSTEXPR $1(ConstantInitialized')
|
||
|
|
if (([regex]::Matches($content, "PROTOBUF_MINGW_CONSTEXPR (MapFieldBase|TypeDefinedMapFieldBase|MapField)\(")).Count -ne 3) {
|
||
|
|
throw "Cannot patch Protobuf map_field.h"
|
||
|
|
}
|
||
|
|
Set-TextFile $mapFieldHeader $content
|
||
|
|
|
||
|
|
$cppMessage = Join-Path $protobufRoot "compiler\cpp\cpp_message.cc"
|
||
|
|
$content = [System.IO.File]::ReadAllText($cppMessage)
|
||
|
|
$content = $content.Replace('explicit constexpr $classname$(', 'explicit PROTOBUF_MINGW_CONSTEXPR $classname$(')
|
||
|
|
$content = $content.Replace('"explicit constexpr "', '"explicit PROTOBUF_MINGW_CONSTEXPR "')
|
||
|
|
$content = $content.Replace('"constexpr $classname$::$classname$(', '"PROTOBUF_MINGW_CONSTEXPR $classname$::$classname$(')
|
||
|
|
Set-TextFile $cppMessage $content
|
||
|
|
|
||
|
|
$cppFile = Join-Path $protobufRoot "compiler\cpp\cpp_file.cc"
|
||
|
|
$content = [System.IO.File]::ReadAllText($cppFile)
|
||
|
|
$content = $content.Replace('" constexpr $1$()\n"', '" PROTOBUF_MINGW_CONSTEXPR $1$()\n"')
|
||
|
|
Set-TextFile $cppFile $content
|
||
|
|
|
||
|
|
foreach ($generatedRoot in @($GrpcSource, (Join-Path $GrpcBuild "gens"))) {
|
||
|
|
if (-not (Test-Path -LiteralPath $generatedRoot)) { continue }
|
||
|
|
foreach ($header in Get-ChildItem -LiteralPath $generatedRoot -Recurse -Filter "*.pb.h") {
|
||
|
|
$content = [System.IO.File]::ReadAllText($header.FullName)
|
||
|
|
$content = $content.Replace("explicit constexpr ", "explicit PROTOBUF_MINGW_CONSTEXPR ")
|
||
|
|
Set-TextFile $header.FullName $content
|
||
|
|
}
|
||
|
|
foreach ($source in Get-ChildItem -LiteralPath $generatedRoot -Recurse -Filter "*.pb.cc") {
|
||
|
|
$content = [System.IO.File]::ReadAllText($source.FullName)
|
||
|
|
$content = [regex]::Replace(
|
||
|
|
$content,
|
||
|
|
'(?m)^constexpr (?=[A-Za-z_][A-Za-z0-9_]*::[A-Za-z_][A-Za-z0-9_]*\()',
|
||
|
|
'PROTOBUF_MINGW_CONSTEXPR ')
|
||
|
|
$content = [regex]::Replace(
|
||
|
|
$content,
|
||
|
|
'(?m)^ constexpr (?=[A-Za-z_][A-Za-z0-9_]*DefaultTypeInternal\(\))',
|
||
|
|
' PROTOBUF_MINGW_CONSTEXPR ')
|
||
|
|
Set-TextFile $source.FullName $content
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Write-Host "Applied Protobuf default-instance compatibility patch for MinGW GCC 7"
|
||
|
|
}
|
||
|
|
|
||
|
|
Enable-OldMingwProtobufCompatibility
|
||
|
|
|
||
|
|
New-Item -ItemType Directory -Force $GrpcBuild, $GrpcInstall | Out-Null
|
||
|
|
$env:PATH = "$MingwBin;$(Join-Path $CmakeRoot 'bin');$env:PATH"
|
||
|
|
$GrpcSourceCmake = $GrpcSource.Replace("\", "/")
|
||
|
|
$GrpcBuildCmake = $GrpcBuild.Replace("\", "/")
|
||
|
|
$GrpcInstallCmake = $GrpcInstall.Replace("\", "/")
|
||
|
|
$MingwBinCmake = $MingwBin.Replace("\", "/")
|
||
|
|
$MakeCmake = $Make.Replace("\", "/")
|
||
|
|
|
||
|
|
$configurePrefix = @()
|
||
|
|
if ($Fresh -or -not (Test-Path -LiteralPath (Join-Path $GrpcBuild "CMakeCache.txt"))) {
|
||
|
|
$configurePrefix += "--fresh"
|
||
|
|
}
|
||
|
|
|
||
|
|
& $Cmake @configurePrefix -S $GrpcSourceCmake -B $GrpcBuildCmake -G "MinGW Makefiles" `
|
||
|
|
"-DCMAKE_BUILD_TYPE=Release" `
|
||
|
|
"-DCMAKE_INSTALL_PREFIX=$GrpcInstallCmake" `
|
||
|
|
"-DCMAKE_C_COMPILER=$MingwBinCmake/gcc.exe" `
|
||
|
|
"-DCMAKE_CXX_COMPILER=$MingwBinCmake/g++.exe" `
|
||
|
|
"-DCMAKE_MAKE_PROGRAM=$MakeCmake" `
|
||
|
|
"-DCMAKE_POSITION_INDEPENDENT_CODE=ON" `
|
||
|
|
"-DBUILD_SHARED_LIBS=OFF" `
|
||
|
|
"-DBUILD_TESTING=OFF" `
|
||
|
|
"-DgRPC_INSTALL=ON" `
|
||
|
|
"-DgRPC_BUILD_TESTS=OFF" `
|
||
|
|
"-DgRPC_BUILD_CODEGEN=ON" `
|
||
|
|
"-DgRPC_BUILD_GRPC_CPP_PLUGIN=ON" `
|
||
|
|
"-DgRPC_BUILD_GRPC_CSHARP_PLUGIN=OFF" `
|
||
|
|
"-DgRPC_BUILD_GRPC_NODE_PLUGIN=OFF" `
|
||
|
|
"-DgRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN=OFF" `
|
||
|
|
"-DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF" `
|
||
|
|
"-DgRPC_BUILD_GRPC_PYTHON_PLUGIN=OFF" `
|
||
|
|
"-DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF" `
|
||
|
|
"-DgRPC_ABSL_PROVIDER=module" `
|
||
|
|
"-DgRPC_CARES_PROVIDER=module" `
|
||
|
|
"-DgRPC_PROTOBUF_PROVIDER=module" `
|
||
|
|
"-DgRPC_RE2_PROVIDER=module" `
|
||
|
|
"-DgRPC_SSL_PROVIDER=module" `
|
||
|
|
"-DgRPC_ZLIB_PROVIDER=module" `
|
||
|
|
"-DRE2_BUILD_TESTING=OFF" `
|
||
|
|
"-Dprotobuf_BUILD_TESTS=OFF" `
|
||
|
|
"-Dprotobuf_BUILD_SHARED_LIBS=OFF" `
|
||
|
|
"-DABSL_ENABLE_INSTALL=ON" `
|
||
|
|
"-DCARES_STATIC=ON" `
|
||
|
|
"-DCARES_SHARED=OFF" `
|
||
|
|
"-DCARES_BUILD_TOOLS=OFF" `
|
||
|
|
"-DOPENSSL_NO_ASM=ON"
|
||
|
|
if ($LASTEXITCODE -ne 0) { throw "gRPC configure failed" }
|
||
|
|
|
||
|
|
& $Cmake --build $GrpcBuild --target install --parallel $Jobs
|
||
|
|
if ($LASTEXITCODE -ne 0) { throw "gRPC build failed" }
|
||
|
|
|
||
|
|
$Protoc = Join-Path $GrpcInstall "bin\protoc.exe"
|
||
|
|
$GrpcPlugin = Join-Path $GrpcInstall "bin\grpc_cpp_plugin.exe"
|
||
|
|
if (-not (Test-Path -LiteralPath $Protoc) -or -not (Test-Path -LiteralPath $GrpcPlugin)) {
|
||
|
|
throw "gRPC build finished but protoc or grpc_cpp_plugin is missing"
|
||
|
|
}
|
||
|
|
Write-Host "gRPC and Protobuf installed to $GrpcInstall"
|