mirror of
https://github.com/koloideal/SortLab.git
synced 2026-06-10 02:15:31 +03:00
277 lines
9.6 KiB
PowerShell
277 lines
9.6 KiB
PowerShell
$ErrorActionPreference = "Stop"
|
|
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
|
|
$MINGW_FILE = "winlibs-x86_64-posix-seh-gcc-13.1.0-mingw-w64msvcrt-11.0.0-r5.zip"
|
|
$MINGW_URL = "https://github.com/brechtsanders/winlibs_mingw/releases/download/13.1.0-16.0.5-11.0.0-msvcrt-r5/$MINGW_FILE"
|
|
$SFML_FILE = "SFML-2.6.1-windows-gcc-13.1.0-mingw-64-bit.zip"
|
|
$SFML_URL = "https://github.com/SFML/SFML/releases/download/2.6.1/$SFML_FILE"
|
|
$CMAKE_FILE = "cmake-3.28.3-windows-x86_64.zip"
|
|
$CMAKE_URL = "https://github.com/Kitware/CMake/releases/download/v3.28.3/$CMAKE_FILE"
|
|
|
|
$ROOT = $PSScriptRoot
|
|
$TOOLS = Join-Path $ROOT ".tools"
|
|
$MINGW = Join-Path $TOOLS "mingw64"
|
|
$SFML = Join-Path $TOOLS "SFML-2.6.1"
|
|
$CMAKE = Join-Path $TOOLS "cmake"
|
|
$BUILD = Join-Path $ROOT "build"
|
|
|
|
function Get-File($url, $dest) {
|
|
if (Test-Path $dest) { return }
|
|
Write-Host "Downloading $(Split-Path $url -Leaf)..."
|
|
$tmp = "$dest.tmp"
|
|
try {
|
|
$wc = New-Object System.Net.WebClient
|
|
$wc.DownloadFile($url, $tmp)
|
|
Move-Item $tmp $dest
|
|
} catch {
|
|
if (Test-Path $tmp) { Remove-Item $tmp }
|
|
throw "Failed to download $url : $_"
|
|
}
|
|
}
|
|
|
|
function Unzip($zip, $dest) {
|
|
Write-Host "Extracting $(Split-Path $zip -Leaf)..."
|
|
[System.IO.Compression.ZipFile]::ExtractToDirectory($zip, $dest)
|
|
}
|
|
|
|
function Find-InPath($cmd) {
|
|
return Get-Command $cmd -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
function Find-Make($gppPath) {
|
|
$binDir = Split-Path $gppPath
|
|
$candidates = @(
|
|
(Join-Path $binDir "mingw32-make.exe"),
|
|
(Join-Path $binDir "make.exe")
|
|
)
|
|
foreach ($c in $candidates) {
|
|
if (Test-Path $c) { return $c }
|
|
}
|
|
$sys = Find-InPath "mingw32-make.exe"
|
|
if ($sys) { return $sys.Source }
|
|
$sys = Find-InPath "make.exe"
|
|
if ($sys) { return $sys.Source }
|
|
return $null
|
|
}
|
|
|
|
function Get-MsysRoot($gppPath) {
|
|
if ($gppPath -match "msys64") {
|
|
$parts = $gppPath -split "msys64"
|
|
return $parts[0] + "msys64"
|
|
}
|
|
return $null
|
|
}
|
|
|
|
function Get-MsysArch($gppPath) {
|
|
if ($gppPath -like "*ucrt64*") { return "ucrt64" }
|
|
if ($gppPath -like "*mingw64*") { return "mingw64" }
|
|
if ($gppPath -like "*mingw32*") { return "mingw32" }
|
|
if ($gppPath -like "*clang64*") { return "clang64" }
|
|
return $null
|
|
}
|
|
|
|
New-Item -ItemType Directory -Force -Path $TOOLS | Out-Null
|
|
|
|
$cmakeExe = $null
|
|
$systemCmake = Find-InPath "cmake.exe"
|
|
if ($systemCmake) {
|
|
$ver = (& $systemCmake.Source --version 2>$null | Select-Object -First 1) -replace "cmake version ", ""
|
|
Write-Host "Found system cmake $ver at $($systemCmake.Source)"
|
|
$cmakeExe = $systemCmake.Source
|
|
} elseif (Test-Path (Join-Path $CMAKE "bin\\cmake.exe")) {
|
|
Write-Host "Found local cmake in .tools"
|
|
$cmakeExe = Join-Path $CMAKE "bin\\cmake.exe"
|
|
} else {
|
|
$zip = Join-Path $TOOLS $CMAKE_FILE
|
|
Get-File $CMAKE_URL $zip
|
|
Unzip $zip $TOOLS
|
|
$extracted = Get-ChildItem $TOOLS -Directory | Where-Object { $_.Name -like "cmake-3.28*" } | Select-Object -First 1
|
|
Rename-Item $extracted.FullName $CMAKE
|
|
$cmakeExe = Join-Path $CMAKE "bin\\cmake.exe"
|
|
}
|
|
|
|
$gppExe = $null
|
|
$gccExe = $null
|
|
$makeExe = $null
|
|
$generator = $null
|
|
$sfmlCmakeDir = $null
|
|
$extraCmakeArgs = @()
|
|
$isMsys2 = $false
|
|
|
|
$hasMSVC = Find-InPath "cl.exe"
|
|
$systemGpp = Find-InPath "g++.exe"
|
|
|
|
if ($hasMSVC) {
|
|
Write-Host "Found MSVC cl.exe"
|
|
$vsWhere = Join-Path ${env:ProgramFiles(x86)} "Microsoft Visual Studio\\Installer\\vswhere.exe"
|
|
$vsVer = $null
|
|
if (Test-Path $vsWhere) {
|
|
$vsVer = & $vsWhere -latest -property catalog_productLineVersion 2>$null
|
|
}
|
|
if ($vsVer -eq "2022") { $generator = "Visual Studio 17 2022" }
|
|
elseif ($vsVer -eq "2019") { $generator = "Visual Studio 16 2019" }
|
|
else { $generator = "Visual Studio 17 2022" }
|
|
$extraCmakeArgs = @("-A", "x64")
|
|
} elseif ($systemGpp) {
|
|
$ver = (& $systemGpp.Source --version 2>$null | Select-Object -First 1) -replace ".*?(\\d+\\.\\d+\\.\\d+).*", '$1'
|
|
Write-Host "Found system g++ $ver at $($systemGpp.Source)"
|
|
$gppExe = $systemGpp.Source
|
|
$gccExe = (Find-InPath "gcc.exe").Source
|
|
$makeExe = Find-Make $gppExe
|
|
if (-not $makeExe) {
|
|
throw "make.exe / mingw32-make.exe not found near $gppExe"
|
|
}
|
|
Write-Host "Found make at $makeExe"
|
|
$generator = "MinGW Makefiles"
|
|
|
|
$msysRoot = Get-MsysRoot $gppExe
|
|
$msysArch = Get-MsysArch $gppExe
|
|
if ($msysRoot -and $msysArch) {
|
|
$isMsys2 = $true
|
|
$msysSfmlDir = Join-Path $msysRoot "$msysArch\\lib\\cmake\\SFML"
|
|
if (-not (Test-Path (Join-Path $msysSfmlDir "SFMLConfig.cmake"))) {
|
|
$pkg = if ($msysArch -eq "ucrt64") { "mingw-w64-ucrt-x86_64-sfml" } elseif ($msysArch -eq "mingw64") { "mingw-w64-x86_64-sfml" } else { "mingw-w64-$msysArch-sfml" }
|
|
Write-Host "SFML not found in MSYS2, installing $pkg via pacman..."
|
|
$pacman = Join-Path $msysRoot ("usr\\bin\\pacman.exe")
|
|
if (-not (Test-Path $pacman)) {
|
|
throw "pacman.exe not found in MSYS2 root $msysRoot"
|
|
}
|
|
& $pacman -S --needed --noconfirm $pkg
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "pacman failed to install $pkg"
|
|
}
|
|
}
|
|
if (Test-Path (Join-Path $msysSfmlDir "SFMLConfig.cmake")) {
|
|
Write-Host "Using MSYS2 SFML at $msysSfmlDir"
|
|
$sfmlCmakeDir = $msysSfmlDir
|
|
} else {
|
|
throw "SFMLConfig.cmake still not found in $msysSfmlDir after pacman install"
|
|
}
|
|
}
|
|
|
|
$extraCmakeArgs = @(
|
|
"-DCMAKE_CXX_COMPILER=$($gppExe -replace '\\', '/')",
|
|
"-DCMAKE_MAKE_PROGRAM=$($makeExe -replace '\\', '/')"
|
|
)
|
|
} elseif (Test-Path (Join-Path $MINGW "bin\\g++.exe")) {
|
|
Write-Host "Found local MinGW in .tools"
|
|
$gppExe = Join-Path $MINGW "bin\\g++.exe"
|
|
$gccExe = Join-Path $MINGW "bin\\gcc.exe"
|
|
$makeExe = Join-Path $MINGW "bin\\mingw32-make.exe"
|
|
$env:PATH = (Join-Path $MINGW "bin") + ";" + $env:PATH
|
|
$generator = "MinGW Makefiles"
|
|
|
|
$extraCmakeArgs = @(
|
|
"-DCMAKE_C_COMPILER=$($gccExe -replace '\\', '/')",
|
|
"-DCMAKE_CXX_COMPILER=$($gppExe -replace '\\', '/')",
|
|
"-DCMAKE_MAKE_PROGRAM=$($makeExe -replace '\\', '/')"
|
|
)
|
|
} else {
|
|
$zip = Join-Path $TOOLS $MINGW_FILE
|
|
Get-File $MINGW_URL $zip
|
|
Unzip $zip $TOOLS
|
|
$extracted = Get-ChildItem $TOOLS -Directory | Where-Object { $_.Name -like "mingw64*" } | Select-Object -First 1
|
|
if ($extracted -and $extracted.FullName -ne $MINGW) {
|
|
Rename-Item $extracted.FullName $MINGW
|
|
}
|
|
$gppExe = Join-Path $MINGW "bin\\g++.exe"
|
|
$gccExe = Join-Path $MINGW "bin\\gcc.exe"
|
|
$makeExe = Join-Path $MINGW "bin\\mingw32-make.exe"
|
|
$env:PATH = (Join-Path $MINGW "bin") + ";" + $env:PATH
|
|
$generator = "MinGW Makefiles"
|
|
|
|
$extraCmakeArgs = @(
|
|
"-DCMAKE_C_COMPILER=$($gccExe -replace '\\', '/')",
|
|
"-DCMAKE_CXX_COMPILER=$($gppExe -replace '\\', '/')",
|
|
"-DCMAKE_MAKE_PROGRAM=$($makeExe -replace '\\', '/')"
|
|
)
|
|
}
|
|
|
|
if (-not $sfmlCmakeDir) {
|
|
$sfmlInclude = Join-Path $SFML "include\\SFML"
|
|
if (!(Test-Path $sfmlInclude)) {
|
|
$zip = Join-Path $TOOLS $SFML_FILE
|
|
Get-File $SFML_URL $zip
|
|
Unzip $zip $TOOLS
|
|
} else {
|
|
Write-Host "Found local SFML 2.6.1 in .tools"
|
|
}
|
|
$sfmlCmakeDir = Join-Path $SFML "lib\\cmake\\SFML"
|
|
}
|
|
|
|
$cacheFile = Join-Path $BUILD "CMakeCache.txt"
|
|
|
|
if (Test-Path $cacheFile) {
|
|
$cachedGenerator = Get-Content $cacheFile |
|
|
Where-Object { $_ -match "^CMAKE_GENERATOR:INTERNAL=" } |
|
|
ForEach-Object { ($_ -split "=", 2)[1] }
|
|
if ($cachedGenerator -and $cachedGenerator.Trim() -ne $generator) {
|
|
Write-Host "Generator changed ('$($cachedGenerator.Trim())' -> '$generator'), clearing build cache..."
|
|
Remove-Item -Recurse -Force $BUILD
|
|
}
|
|
}
|
|
|
|
if (!(Test-Path $cacheFile)) {
|
|
Write-Host "Configuring with generator: $generator"
|
|
|
|
$sfmlCmakeDirFixed = $sfmlCmakeDir -replace '\\', '/'
|
|
|
|
$configArgs = @(
|
|
"-S", $ROOT,
|
|
"-B", $BUILD,
|
|
"-G", $generator,
|
|
"-DSFML_DIR=$sfmlCmakeDirFixed",
|
|
"-DCMAKE_BUILD_TYPE=Release"
|
|
) + $extraCmakeArgs
|
|
& $cmakeExe @configArgs
|
|
if ($LASTEXITCODE -ne 0) { throw "CMake configure failed" }
|
|
}
|
|
|
|
Write-Host "Building..."
|
|
& $cmakeExe --build $BUILD --config Release -j 4
|
|
if ($LASTEXITCODE -ne 0) { throw "CMake build failed" }
|
|
|
|
if (-not $isMsys2) {
|
|
$dllDirs = @(
|
|
(Join-Path $SFML "bin"),
|
|
(Join-Path $BUILD "bin"),
|
|
(Join-Path $BUILD "Release"),
|
|
(Join-Path $BUILD "_deps\sfml-build\lib\Release"),
|
|
(Join-Path $BUILD "_deps\sfml-build\lib\Debug")
|
|
)
|
|
$copied = $false
|
|
foreach ($dir in $dllDirs) {
|
|
if (Test-Path (Join-Path $dir "sfml-graphics*.dll")) {
|
|
Copy-Item (Join-Path $dir "*.dll") $BUILD -Force
|
|
Write-Host "Copied SFML DLLs from $dir"
|
|
$copied = $true
|
|
break
|
|
}
|
|
}
|
|
if (-not $copied) {
|
|
Write-Host "Warning: SFML DLLs not found, you may need to copy them manually"
|
|
}
|
|
|
|
$mingwBin = Split-Path $gppExe
|
|
if (Test-Path $mingwBin) {
|
|
$mingwDlls = @(
|
|
"libstdc++-6.dll",
|
|
"libgcc_s_seh-1.dll",
|
|
"libwinpthread-1.dll"
|
|
)
|
|
foreach ($dll in $mingwDlls) {
|
|
$src = Join-Path $mingwBin $dll
|
|
if (Test-Path $src) {
|
|
Copy-Item $src $BUILD -Force
|
|
Write-Host "Copied MinGW DLL: $dll"
|
|
} else {
|
|
Write-Host "Warning: Could not find $dll in $mingwBin"
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
Write-Host "MSYS2 build: DLLs are handled by CMake TARGET_RUNTIME_DLLS"
|
|
}
|
|
|
|
Write-Host "Done! Run: $(Join-Path $BUILD 'SortLab.exe')"
|