Skip to content

Fix building with Visual Studio 2026 (while keeping support for VS 2022)#10878

Open
jschmidt-icinga wants to merge 3 commits into
masterfrom
fix-windows-vs-path
Open

Fix building with Visual Studio 2026 (while keeping support for VS 2022)#10878
jschmidt-icinga wants to merge 3 commits into
masterfrom
fix-windows-vs-path

Conversation

@jschmidt-icinga

@jschmidt-icinga jschmidt-icinga commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Due to changes to the Github Windows Runner images that went live today (2026-06-15), we suddenly need to build and run our Windows checks with VS 2026. This PR changes our Windows build/configure scripts to detect the Visual studio paths the canonical way via the vswhere command instead of hard-coding versions.

Description

This contains four individual fixes:

Getting the path for the Visual Studio install using vswhere

This is straight forward: vswhere has a installationPath property that does exactly this. The override variable VS_INSTALL_PATH is kept and optionally fed to vswhere via the -path flag, ensuring that the other properties (like the next one) also take it into account.

Determining the matching CMake generator from the detected installation

CMake supports each Visual Studio version via its own generator, for example previously this was Visual Studio 17 2022. The major version can easily be retrieved via the installationVersion property from vswhere, but there is no good way to get that year number. But since these always match up and there is only a single generator for each major version, I added a function that checks if CMake has a generator for this major version with a regex pattern and then select that one.

I've tried to do this in a future-proof way so no additional manual edits need to be made as long as the installed CMake version supports the generator.

Since this functionality is needed by both this fix and the previous one, I've put all vswhere-related code into the new file find-vs.ps1. The other scripts can then source this file and call the functions in it without code duplication.

Explicitly setting the toolset version when configuring CMake

Visual Studio 2022 defaults to toolset 14.3, while Visual Studio 2026 defaults to 14.5. Since our Gitlab Pipelines are (for now) still on Visual Studio 2022 it is better to stick to 14.3 for now. Luckily VS 2026 (or rather the Github images) still has this toolset installed, so all it takes is explicitly configuring it in CMake with the CMAKE_GENERATOR_TOOLSET variable (which can still be used to override the default). This should be a noop on VS 2022 and should produce the same output on VS 2026.

At some point in the future maybe this can be abstracted out so it can easily be defined in a single place.

Bump the .NET version in the project file

This is somewhat unrelated, but it causes an error because VS 2026 doesn't support the .NET version we set in the installer project file anymore. And since there is no auto setting or simply leaving out the node from the XML, updating it to 4.8 seems to be the best option. Common "wisdom" seems to be that this version should be (and remain) supported on all newer VS versions.

Testing

This seems to pass both the Github CI as well as work with the Pipelines on Gitlab.

fixes #10885

@cla-bot cla-bot Bot added the cla/signed label Jun 15, 2026
@jschmidt-icinga jschmidt-icinga force-pushed the fix-windows-vs-path branch 2 times, most recently from c41f828 to a403f16 Compare June 15, 2026 12:02
This makes use of VS's `vcwhere` command to detect the VS installation.

Since the previously hardcoded VS version was also used to select the
CMake generator, this has also been switched to use the version
properties from `vcwhere`.
We don't use C# or .NET, but Visual Studio seems to crap itself
if this non-optional setting is set to the wrong number.
@jschmidt-icinga jschmidt-icinga changed the title Fix Visual Studio path detection in Windows build-scripts Fix building with Visual Studio 2026 (while keeping support for VS 2022) Jun 15, 2026
@jschmidt-icinga jschmidt-icinga marked this pull request as ready for review June 15, 2026 14:21
@Al2Klimov

Copy link
Copy Markdown
Member

You could btw also just revert #9172 instead, I guess.

@jschmidt-icinga

Copy link
Copy Markdown
Contributor Author

You could btw also just revert #9172 instead, I guess.

As far as I can tell the main benefit of that PR was improving build times (which I am hugely in favor of). Why would we want to throw that away?

@Al2Klimov Al2Klimov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Admittedly, this PR passes https://git.icinga.com/packages/special/windows-icinga2/-/pipelines/40554 and works on Server 2012R2. Even the IfW-supported Server 2008R2 should have .NET 4.8.

But, and that is very important, this is a change to GHA. The only purpose of GHA is to verify whether packages will build. In contrast to our VS2022 build server, this PR now tests with VS2026 only.

Please do one of the following:

  • Revert instead #9172
  • Suggest a transition strategy at the end of which GHA and our build server will be in sync

@jschmidt-icinga

jschmidt-icinga commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

The only purpose of GHA #10581 (comment) to verify whether packages will build.

I thought that was the purpose of the Gitlab runners (since we're not building any actual packages in the GHA) and the purpose of the GHAs is mainly to aid development (and they're currently doing the opposite).

That said, I get the point that preferably the GHA and Gitlab Pipelines should be in sync. Someone else would need to upgrade that VS installation though, because I'm getting a headache even thinking about it. Writing a bit of powershell is one thing, but actually having to interact with Windows is a nightmare I'm not keen to get involved in.

@Al2Klimov

Copy link
Copy Markdown
Member

Someone else would need to upgrade that VS installation

I'm on (testing) it.

Meanwhile, please could you make a separate(!) branch with a stripped down version of this PR to the minimum needed to only support VS2026 (but with toolset 14.3)?

@jschmidt-icinga

Copy link
Copy Markdown
Contributor Author

a stripped down version of this PR to the minimum needed to only support VS2026 (but with toolset 14.3)?

You mean just s/2022/2026/g so it can break again in the future as soon as MS/Github wants to change something around again? Personally I'd prefer these actions to be as robust as possible to interrupt development as little as possible.

However, I've made the requested branch anyway: https://github.com/Icinga/icinga2/tree/brittle-replace-vs-2026

No PR for now, I'd rather merge it into this one if that's what we want.

@julianbrost

Copy link
Copy Markdown
Member

(Maybe) stupid question: what would CMake do if we just pass nothing about Visual Studio and let it auto-detect things? Call me naive, but using CMake to build C++ on Windows really shouldn't be that esoteric that you have to jump through such hoops.

@jschmidt-icinga

jschmidt-icinga commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

(Maybe) stupid question: what would CMake do if we just pass nothing about Visual Studio and let it auto-detect things?

If no generator is explicitly specified CMake should be able to autodetect the latest VS version if it is properly installed. But this still leaves the path detection we need to do outside CMake, with potentially different results if our VS_INSTALL_PATH override variable is set (or maybe even without that variable, who knows) to the one detected by CMake.

The problem is that Windows doesn't have a $PATH which makes using system programs a nightmare. The crutch here is the vswhere helper, which might be what CMake uses. If that assumption is correct, dropping the VS_INSTALL_PATH support (which we don't use anywhere in our own scripts I think) would allow us to let CMake autodetect and only use vswhere to get the VS path, not for determining the CMake generator, which would simplify things considerably.

@Al2Klimov Al2Klimov mentioned this pull request Jun 17, 2026
2 tasks
@julianbrost

julianbrost commented Jun 17, 2026

Copy link
Copy Markdown
Member

But this still leaves the path detection we need to do outside CMake

Where else do we need the VS installation path? From a quick git grep -e VS_INSTALL_PATH -e VSBASE this seems to be here, which has a smell. If CMake is indeed able to detect VS, it might as well be able to set up things properly to run it.

# Execute vcvars in cmd and store env
$vcvars_locations = @(
"${VSBASE}\BuildTools\VC\Auxiliary\Build\vcvars${bits}.bat"
"${VSBASE}\Community\VC\Auxiliary\Build\vcvars${bits}.bat"
"${VSBASE}\Enterprise\VC\Auxiliary\Build\vcvars${bits}.bat"
)
$vcvars = $null
foreach ($file in $vcvars_locations) {
if (Test-Path $file) {
$vcvars = $file
break
}
}
if ($vcvars -eq $null) {
throw "Could not get Build environment script at locations: ${vcvars_locations}"
}
cmd.exe /c "call `"${vcvars}`" && set > `"${BUILD}\vcvars.txt`""
if ($LastExitCode -ne 0) {
throw "Could not load Build environment from: ${vcvars}"
}
# Load environment for PowerShell
Get-Content "${BUILD}\vcvars.txt" | Foreach-Object {
if ($_ -match "^(VSCMD.*?)=(.*)$") {
Set-Content ("env:" + $matches[1]) $matches[2]
}
}

The problem is that Windows doesn't have a $PATH which makes using system programs a nightmare.

It does, Visual Studio probably just thinks it isn't a good idea to put itself there (maybe because you can have multiple versions installed in parallel and that might lead to a mess).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Visual Studio 2026

3 participants