mirror of
https://github.com/ClusterM/open-bamboo-networking.git
synced 2026-10-19 01:29:46 -05:00
378 lines
15 KiB
PowerShell
378 lines
15 KiB
PowerShell
# PowerShell wrapper around CMake for the Windows build, mirroring what
|
|
# ./configure does on Linux. Drops a ready-to-build tree under -BuildDir
|
|
# (default ./build) and writes a tiny config.ps1 that records the build
|
|
# directory for downstream helpers.
|
|
#
|
|
# Every parameter below maps 1:1 to a CMake cache variable; run cmake
|
|
# directly if you want something this script does not expose.
|
|
#
|
|
# Typical use:
|
|
# .\configure.ps1 # bambu_studio, x64-windows-static
|
|
# .\configure.ps1 -ClientType orca_slicer
|
|
# .\configure.ps1 -BuildType Debug -EnableTests:$false
|
|
# .\configure.ps1 -VcpkgRoot C:\vcpkg -VcpkgTriplet x64-windows
|
|
# .\configure.ps1 -Architecture ARM64 -VcpkgTriplet arm64-windows-static-md
|
|
# .\configure.ps1 -Generator "Visual Studio 17 2022" # pin a VS version
|
|
#
|
|
# If -Generator is omitted, it is not passed to CMake and CMake picks its
|
|
# platform default (on Windows with VS installed, typically the newest
|
|
# Visual Studio). VCPKG_ROOT does not imply a compiler/VS version; use
|
|
# -Generator when you must match a specific toolset (e.g. VS 2019 / v142).
|
|
#
|
|
# Requirements:
|
|
# - Visual Studio 2019 (toolset v142) -- matches the MSVC ABI Bambu Studio
|
|
# itself ships with. Newer toolsets *may* work but the std::string layout
|
|
# across the DLL boundary is not guaranteed. For Windows ARM64 use a VS
|
|
# install that includes the ARM64 C++ toolset (CI uses windows-11-arm).
|
|
# - vcpkg (manifest mode picks up vcpkg.json automatically).
|
|
# - cmake on PATH (3.16+).
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[string] $Prefix = "",
|
|
[string] $BuildDir = "build",
|
|
[ValidateSet("Release","Debug","RelWithDebInfo","MinSizeRel")]
|
|
[string] $BuildType = "Release",
|
|
[string] $WithVersion = "",
|
|
[ValidateSet("bambu_studio","orca_slicer")]
|
|
[string] $ClientType = "bambu_studio",
|
|
[bool] $EnableTests = $false,
|
|
[bool] $PatchConf = $true,
|
|
# On Windows install the DirectShow source filter (HKCU CLSID +
|
|
# bambu: URL handler) so wxMediaCtrl2 can stream live camera. The
|
|
# CMake side runs `regsvr32 /s BambuSource.dll`. Set $false to
|
|
# skip if the user prefers to register manually.
|
|
[bool] $RegisterDShowFilter = $true,
|
|
[string] $VcpkgRoot = "",
|
|
# Default triplet: x64-windows-static-md = static deps + dynamic CRT (/MD).
|
|
# Bambu Studio is /MD (dynamic CRT), and a /MT-built DLL would emit a
|
|
# LIBCMT-vs-MSVCRT mismatch warning (LNK4098) and -- worse -- run two
|
|
# copies of the C runtime side by side with diverging stdio and heap
|
|
# state. -static (without -md) is left as an option for users who want
|
|
# the older default. Use arm64-windows-static-md for native Windows ARM64.
|
|
[ValidateSet("x64-windows","x64-windows-static","x64-windows-static-md","x86-windows","x86-windows-static","arm64-windows","arm64-windows-static-md")]
|
|
[string] $VcpkgTriplet = "x64-windows-static-md",
|
|
# Empty = let CMake choose (-G omitted). Pass an explicit name to pin
|
|
# a Visual Studio version (e.g. "Visual Studio 16 2019").
|
|
[string] $Generator = "",
|
|
# CMake -A platform: "x64", "Win32", or "ARM64". When an arm64-* / x86-*
|
|
# triplet is selected and this is still the default "x64", configure.ps1
|
|
# rewrites it automatically below.
|
|
[string] $Architecture = "x64",
|
|
[string[]] $CMakeArg = @()
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
function Write-Note {
|
|
param([string]$msg)
|
|
Write-Host "configure: $msg"
|
|
}
|
|
|
|
function Write-Err {
|
|
param([string]$msg)
|
|
Write-Host "configure: $msg" -ForegroundColor Red
|
|
}
|
|
|
|
# ----- prerequisites -----------------------------------------------------
|
|
|
|
if (-not (Get-Command cmake -ErrorAction SilentlyContinue)) {
|
|
Write-Err "cmake is required but was not found on PATH"
|
|
exit 1
|
|
}
|
|
|
|
# Resolve vcpkg root, in this order: -VcpkgRoot, $env:VCPKG_ROOT, vcpkg.exe
|
|
# on PATH (its parent directory). If none are usable we error out -- vcpkg
|
|
# is mandatory for the Windows build because dependency resolution in
|
|
# CMakeLists relies on the vcpkg.cmake toolchain.
|
|
if ([string]::IsNullOrEmpty($VcpkgRoot) -and $env:VCPKG_ROOT) {
|
|
$VcpkgRoot = $env:VCPKG_ROOT
|
|
}
|
|
if ([string]::IsNullOrEmpty($VcpkgRoot)) {
|
|
$vcpkgExe = Get-Command vcpkg.exe -ErrorAction SilentlyContinue
|
|
if ($vcpkgExe) {
|
|
$VcpkgRoot = Split-Path -Parent $vcpkgExe.Source
|
|
}
|
|
}
|
|
if ([string]::IsNullOrEmpty($VcpkgRoot) -or
|
|
-not (Test-Path (Join-Path $VcpkgRoot "scripts\buildsystems\vcpkg.cmake"))) {
|
|
Write-Err "vcpkg is required for the Windows build."
|
|
Write-Err " Install it from https://github.com/microsoft/vcpkg, set"
|
|
Write-Err " `$env:VCPKG_ROOT (or pass -VcpkgRoot), and re-run."
|
|
exit 1
|
|
}
|
|
$ToolchainFile = Join-Path $VcpkgRoot "scripts\buildsystems\vcpkg.cmake"
|
|
|
|
# ----- per-client defaults ----------------------------------------------
|
|
|
|
# AppData\Roaming -- matches wxStandardPaths::Get().GetUserDataDir() in
|
|
# Bambu Studio's Windows build. CMakeLists / Clients.cmake compute the same
|
|
# default; we recompute it here so we can also surface the version detected
|
|
# from the slicer's existing .conf file before we even invoke cmake.
|
|
$Appdata = $env:APPDATA
|
|
$ClientLabel = ""
|
|
$ClientDir = ""
|
|
$ConfName = ""
|
|
$JsonKey = ""
|
|
switch ($ClientType) {
|
|
"bambu_studio" {
|
|
$ClientLabel = "Bambu Studio"
|
|
$ClientDir = Join-Path $Appdata "BambuStudio"
|
|
$ConfName = "BambuStudio.conf"
|
|
$JsonKey = "version"
|
|
}
|
|
"orca_slicer" {
|
|
$ClientLabel = "Orca Slicer"
|
|
$ClientDir = Join-Path $Appdata "OrcaSlicer"
|
|
$ConfName = "OrcaSlicer.conf"
|
|
$JsonKey = "network_plugin_version"
|
|
}
|
|
}
|
|
|
|
if ([string]::IsNullOrEmpty($Prefix)) {
|
|
$Prefix = $ClientDir
|
|
}
|
|
|
|
# ----- version auto-detection -------------------------------------------
|
|
|
|
# Mirrors the Linux ./configure logic: read "app.<json_key>" from the
|
|
# slicer's conf file, bump the last component to .99 so our plugin always
|
|
# wins the slicer's compatibility gate (Studio compares the first 8 chars
|
|
# == "MAJOR.MINOR.PATCH"; .99 keeps us ahead).
|
|
function Detect-VersionFromConf {
|
|
param([string]$ConfPath, [string]$Key)
|
|
if (-not (Test-Path $ConfPath)) { return "" }
|
|
$line = Select-String -Path $ConfPath -Pattern "`"$Key`"\s*:\s*`"([0-9][0-9.]*)`"" -ErrorAction SilentlyContinue |
|
|
Select-Object -First 1
|
|
if (-not $line) { return "" }
|
|
if ($line.Matches.Count -gt 0 -and $line.Matches[0].Groups.Count -ge 2) {
|
|
return $line.Matches[0].Groups[1].Value
|
|
}
|
|
return ""
|
|
}
|
|
|
|
# Resolve <ExeName>.exe to a four-component FileVersion via the
|
|
# Windows registry's Uninstall keys. The registry's DisplayVersion can
|
|
# lag behind the actual binary (it is set at install time and not
|
|
# refreshed on minor patches), so we read the running binary's
|
|
# FileVersion resource directly. That is the same string Studio reports
|
|
# in the About dialog and uses internally as SLIC3R_VERSION on Windows.
|
|
function Detect-VersionFromExe {
|
|
param([string]$DisplayName)
|
|
$regPaths = @(
|
|
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
|
|
'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*',
|
|
'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*'
|
|
)
|
|
$entries = Get-ItemProperty -Path $regPaths -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.DisplayName -eq $DisplayName }
|
|
foreach ($e in $entries) {
|
|
# DisplayIcon usually points at the launcher exe, even when
|
|
# InstallLocation is empty (and many installers leave it empty).
|
|
$exe = $null
|
|
if ($e.DisplayIcon) {
|
|
$candidate = ($e.DisplayIcon -split ',')[0].Trim('"')
|
|
if (Test-Path $candidate) { $exe = $candidate }
|
|
}
|
|
if (-not $exe -and $e.InstallLocation) {
|
|
$base = ([System.IO.Path]::GetFileNameWithoutExtension($DisplayName).ToLower() -replace ' ','-')
|
|
$candidate = Join-Path $e.InstallLocation ($base + '.exe')
|
|
if (Test-Path $candidate) { $exe = $candidate }
|
|
}
|
|
if ($exe) {
|
|
$fv = (Get-Item $exe).VersionInfo.FileVersion
|
|
if ($fv -match '^\d+(\.\d+){2,3}$') {
|
|
return [PSCustomObject]@{ Version = $fv; Path = $exe }
|
|
}
|
|
}
|
|
}
|
|
return $null
|
|
}
|
|
|
|
if ([string]::IsNullOrEmpty($WithVersion)) {
|
|
$confPath = Join-Path $Prefix $ConfName
|
|
$confVersion = Detect-VersionFromConf -ConfPath $confPath -Key $JsonKey
|
|
|
|
$exeVersion = ""
|
|
$exePath = ""
|
|
$exeInfo = $null
|
|
if ($ClientType -eq "bambu_studio") {
|
|
$exeInfo = Detect-VersionFromExe -DisplayName "Bambu Studio"
|
|
} else {
|
|
# Orca's Add/Remove name has historically been just "OrcaSlicer".
|
|
$exeInfo = Detect-VersionFromExe -DisplayName "OrcaSlicer"
|
|
}
|
|
if ($exeInfo) {
|
|
$exeVersion = $exeInfo.Version
|
|
$exePath = $exeInfo.Path
|
|
}
|
|
|
|
# Prefer the binary's FileVersion over the conf -- Windows Studio
|
|
# ships .exe v02.06.01.55 against a conf still saying 02.06.00.51
|
|
# right after a minor patch, and Studio compares the first 8 chars
|
|
# of OUR plugin version against its own SLIC3R_VERSION. Picking the
|
|
# conf there would silently fail the gate and Studio would fall back
|
|
# to the stock backup at every launch.
|
|
$detected = ""
|
|
$source = ""
|
|
if (-not [string]::IsNullOrEmpty($exeVersion)) {
|
|
$detected = $exeVersion
|
|
$source = "exe FileVersion of $exePath"
|
|
} elseif (-not [string]::IsNullOrEmpty($confVersion)) {
|
|
$detected = $confVersion
|
|
$source = "conf $confPath"
|
|
} elseif ($ClientType -eq "orca_slicer") {
|
|
# Orca only writes network_plugin_version after it has installed a
|
|
# plugin at least once. A pristine Orca install has no key at all,
|
|
# so fall back to the latest version Orca knows about. See
|
|
# AVAILABLE_NETWORK_VERSIONS in
|
|
# 3rd_party/OrcaSlicer/src/slic3r/Utils/bambu_networking.hpp.
|
|
$detected = "02.03.00"
|
|
$source = "(default for orca_slicer; no $JsonKey in $confPath)"
|
|
}
|
|
|
|
if ([string]::IsNullOrEmpty($detected)) {
|
|
Write-Err "cannot determine the plugin version automatically."
|
|
Write-Err " Tried to read `"$JsonKey`" from: $confPath"
|
|
Write-Err " Tried to read FileVersion via the Add/Remove Programs registry."
|
|
if (-not (Test-Path $confPath)) {
|
|
Write-Err " (conf file does not exist)"
|
|
}
|
|
Write-Err " Launch $ClientLabel at least once so it writes its config,"
|
|
Write-Err " or pass the version explicitly:"
|
|
Write-Err " .\configure.ps1 -WithVersion 02.06.01.99"
|
|
exit 1
|
|
}
|
|
|
|
# Helpful sanity warning when the two sources disagree -- keeps the
|
|
# user from being surprised when their conf-driven build gets
|
|
# silently swapped out by Studio for a /lower/ stock version.
|
|
if (-not [string]::IsNullOrEmpty($exeVersion) -and
|
|
-not [string]::IsNullOrEmpty($confVersion) -and
|
|
$exeVersion -ne $confVersion) {
|
|
Write-Note "note: $ClientLabel binary FileVersion is $exeVersion but conf reports $confVersion"
|
|
Write-Note " using the binary version (Studio uses it for plugin compatibility check)"
|
|
}
|
|
|
|
# CMake's OBN_VERSION regex requires exactly four dotted components.
|
|
if ($detected -match '^\d+(\.\d+){3}$') {
|
|
$WithVersion = ($detected -replace '\.\d+$', '.99')
|
|
} elseif ($detected -match '^\d+(\.\d+){2}$') {
|
|
$WithVersion = "$detected.99"
|
|
} else {
|
|
Write-Err "cannot bump version `"$detected`": expected 3 or 4 dotted components."
|
|
exit 1
|
|
}
|
|
Write-Note "detected $ClientLabel baseline $detected (source: $source)"
|
|
Write-Note "plugin version set to $WithVersion (override with -WithVersion ...)"
|
|
}
|
|
|
|
# ----- assemble cmake command line --------------------------------------
|
|
|
|
# Keep -A in sync with the vcpkg triplet when the user only flipped the
|
|
# triplet (or left -Architecture at its default "x64"):
|
|
# x86-* → Win32
|
|
# arm64-* → ARM64
|
|
# x64-* → x64 (default)
|
|
if ($VcpkgTriplet -like "x86-*" -and $Architecture -eq "x64") {
|
|
Write-Note "x86 triplet selected; switching architecture to Win32"
|
|
$Architecture = "Win32"
|
|
}
|
|
if ($VcpkgTriplet -like "arm64-*" -and $Architecture -eq "x64") {
|
|
Write-Note "arm64 triplet selected; switching architecture to ARM64"
|
|
$Architecture = "ARM64"
|
|
}
|
|
|
|
# Convert booleans to ON/OFF first; if we inline the ternary into the
|
|
# array literal, PowerShell's comma-vs-plus operator precedence ends up
|
|
# splitting "-DFOO=" and "ON" into two adjacent elements.
|
|
$enableTestsVal = if ($EnableTests) { "ON" } else { "OFF" }
|
|
$patchConfVal = if ($PatchConf) { "ON" } else { "OFF" }
|
|
$registerDshowVal = if ($RegisterDShowFilter){ "ON" } else { "OFF" }
|
|
|
|
$cmakeArgs = @(
|
|
"-S", ".",
|
|
"-B", $BuildDir
|
|
)
|
|
if (-not [string]::IsNullOrWhiteSpace($Generator)) {
|
|
$cmakeArgs += "-G", $Generator
|
|
}
|
|
$cmakeArgs += @(
|
|
"-A", $Architecture,
|
|
"-DCMAKE_TOOLCHAIN_FILE=$ToolchainFile",
|
|
"-DVCPKG_TARGET_TRIPLET=$VcpkgTriplet",
|
|
"-DCMAKE_BUILD_TYPE=$BuildType",
|
|
"-DCMAKE_INSTALL_PREFIX=$Prefix",
|
|
"-DOBN_VERSION=$WithVersion",
|
|
"-DOBN_CLIENT_TYPE=$ClientType",
|
|
"-DOBN_BUILD_TESTS=$enableTestsVal",
|
|
"-DOBN_PATCH_CLIENT_CONF=$patchConfVal",
|
|
"-DOBN_REGISTER_DSHOW_FILTER=$registerDshowVal"
|
|
)
|
|
if ($CMakeArg.Count -gt 0) { $cmakeArgs += $CMakeArg }
|
|
|
|
Write-Note ("cmake " + ($cmakeArgs -join " "))
|
|
& cmake @cmakeArgs
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Err "cmake exited with $LASTEXITCODE"
|
|
exit $LASTEXITCODE
|
|
}
|
|
|
|
# When -Generator was omitted, report the generator CMake actually selected.
|
|
$resolvedGenerator = $Generator
|
|
if ([string]::IsNullOrWhiteSpace($resolvedGenerator)) {
|
|
$cacheFile = Join-Path $BuildDir "CMakeCache.txt"
|
|
if (Test-Path $cacheFile) {
|
|
$gLine = Select-String -LiteralPath $cacheFile -Pattern '^CMAKE_GENERATOR:INTERNAL=' -ErrorAction SilentlyContinue |
|
|
Select-Object -First 1
|
|
if ($gLine) {
|
|
$resolvedGenerator = ($gLine.Line -replace '^CMAKE_GENERATOR:INTERNAL=', '')
|
|
}
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($resolvedGenerator)) {
|
|
$resolvedGenerator = "(CMake default; see CMakeCache.txt)"
|
|
}
|
|
}
|
|
|
|
# Persist the build dir so a future helper script (or the user) can reuse it
|
|
# without retyping it. POSIX side does the same with config.mk; ours is just
|
|
# a one-liner ps1 sourced via dot-source.
|
|
@(
|
|
"# Generated by configure.ps1. Re-run it to refresh.",
|
|
"`$BuildDir = '$BuildDir'"
|
|
) | Set-Content -Path "config.ps1" -Encoding ASCII
|
|
|
|
$patchTargetConf = Join-Path $ClientDir $ConfName
|
|
|
|
@"
|
|
configure: done.
|
|
|
|
Selected client: $ClientType
|
|
Install prefix : $Prefix
|
|
Plugin version : $WithVersion
|
|
Build dir : $BuildDir
|
|
Generator : $resolvedGenerator $Architecture
|
|
vcpkg toolchain: $ToolchainFile ($VcpkgTriplet)
|
|
|
|
Next steps:
|
|
cmake --build $BuildDir --config $BuildType
|
|
cmake --install $BuildDir --config $BuildType
|
|
|
|
The install step copies bambu_networking.dll, BambuSource.dll and
|
|
live555.dll into:
|
|
$Prefix\plugins\
|
|
|
|
and (when -PatchConf is on, the default) sets installed_networking,
|
|
update_network_plugin and ignore_module_cert under "app" in:
|
|
$patchTargetConf
|
|
|
|
so Bambu Studio loads our DLL on next launch.
|
|
|
|
When -RegisterDShowFilter is on (the default) the install step also
|
|
runs:
|
|
regsvr32 /s "$Prefix\plugins\BambuSource.dll"
|
|
to register the DirectShow Source Filter (HKCU only, no admin needed)
|
|
that Studio's wxMediaCtrl2 needs for live camera view. To uninstall:
|
|
regsvr32 /u "$Prefix\plugins\BambuSource.dll"
|
|
"@
|