Constrain VS2017 MSBuild detection to VS2017 in vswhere query - #1
Constrain VS2017 MSBuild detection to VS2017 in vswhere query#1BIMvoice wants to merge 2 commits into
Conversation
msbuild.bat locates MSBuild via `vswhere -latest ... -property installationPath` with no version constraint. When more than one Visual Studio version is installed (e.g. 2017 plus a newer 2019, 2022 or 2026), `-latest` picks the newest install instead of VS2017. The subsequent `MSBuild\15.0\Bin\MSBuild.exe` existence check then silently fails against that wrong path, msbdir is left unset, and the later `!msbdir!\msbuild.exe` call fails with a bare "msbuild.exe is not recognized" error that gives no indication of the real cause. Add `-version "[15.0,16.0)"`, vswhere's documented range syntax for the VS2017 product line, so the query only ever matches a VS2017 install regardless of what else is present. Also fail loudly with a clear message if vswhere itself, a matching VS2017 install, or its MSBuild.exe can't be found, instead of falling through to the generic error further down. Traced from IfcOpenShell/IfcOpenShell#8631 and the workaround in IfcOpenShell/IfcOpenShell#8685 (which pre-detects msbdir this same way from the caller side, since it could not fix this script directly). This is a root-cause fix of the detection logic itself so callers no longer need that workaround. Traced from the script logic and vswhere's documented version-range syntax; not run on a real Windows VS2017 installation, since none is available in this environment. Generated with the assistance of an AI coding tool.
Andrej730/mpir-vs2026's unconstrained "vswhere -latest" detection picks a newer Visual Studio when multiple are installed, breaking the VS2017 MSBuild path (IfcOpenShell#8631). A logic fix for this has been proposed directly in IfcOpenShell's own fork of that dependency (IfcOpenShell/mpir-vs2026#1), so point the clone at that fork instead of upstream. Kept the local msbdir pre-detection workaround alongside this redirect: the fork-side fix is unverified on real Windows and not yet merged, and the workaround costs nothing once it lands, since msbuild.bat already skips its own detection when msbdir is pre-set. Generated with the assistance of an AI coding tool.
|
I used the following but got this result C:\Users\chris\work\cad\ifcopenshellbuildissue\IfcOpenShell-fix>cd win C:\Users\chris\work\cad\ifcopenshellbuildissue\IfcOpenShell-fix\win>build-deps.cmd This script fetches and builds all IfcOpenShell dependencies Generator not passed, but VisualStudioVersion=15.0 environment variable detected: C:\Users\chris\work\cad\ifcopenshellbuildissue\IfcOpenShell-fix\win> |
|
Thanks for testing this @ccic-techni, and sorry for the regression. Found it: the VS2017 detection block references paths under The fix switches those references to delayed expansion ( Could you pull the updated This comment was written with AI assistance. |
|
It is getting further. HEAD is now at 365957b vs26 - update toolsets MSBUILD : error MSB1008: Only one project can be specified. For switch syntax, type "MSBuild /help" An error occurred Last logged action: Build ended at 18:44:22.80. Time elapsed 0:02:57.30. |
…ucceeds ccic-techni reported (IfcOpenShell#1, comment 5032275723) that once msbdir is actually found, the build still fails: MSBUILD : error MSB1008: Only one project can be specified. Switch: (x86)\Microsoft Two independent defects in the invocation lines, both pre-existing (present on master before this branch, since this branch's earlier commits only touch the detection block): 1. msbdir is assigned with the quote characters embedded in its value, e.g. set msbdir="!InstallDir!\MSBuild\15.0\Bin", then used as !msbdir!\msbuild.exe. The closing quote lands right after "Bin", with \msbuild.exe glued on unquoted immediately after with no separating space. That hybrid quoted/unquoted token is what MSBuild's own argument parser was choking on: a path like C:\Program Files (x86)\... that is not cleanly one quoted argument gets split into extra tokens, one of which ((x86)\Microsoft) is reported as a second, illegal "project". Fixed by storing msbdir without embedded quotes and quoting the whole exe path at the point of use ("!msbdir!\msbuild.exe"), matching the convention already used correctly in msvc/vs19/msbuild.bat, msvc/vs22/msbuild.bat and msvc/vs26/msbuild.bat (msb_exe="%msb_dir%\MSBuild.exe"). The msbdir="C:\...\Bin" literals for the unreachable (vs_version is hardcoded to 2017) VS2013/2015 branches are switched to set "msbdir=...", which protects the literal parentheses in "(x86)" from being misread as closing the enclosing if-block, without embedding quote characters into the value. 2. The Windows SDK version override property is written as /p:"Windows%20SDK%20Version=%win_sdk%". In batch, %20 is not a URL-encoded space, it is the substitution %2 (this script's own library-type argument, LIB or DLL) followed by a literal "0". With library type LIB this expands to /p:"WindowsLIB0SDKLIB0Version=", exactly matching the mangled property name ccic-techni saw. There is no property by that name anywhere, so the %5 "Windows SDK version" argument documented in this script's own header has never actually overridden anything. The vcxproj files declare <WindowsTargetPlatformVersion>, so that is the correct property name; fixed to /p:"WindowsTargetPlatformVersion=%win_sdk%". The same %20 property-name bug also exists in msvc/vs19, msvc/vs22 and msvc/vs26's msbuild.bat (all currently share the literal /p:"Windows%20SDK%20Version=%win_sdk%" text), but those scripts already quote msb_exe correctly at the point of use, so they are not affected by defect 1. Left untouched here since this PR's scope is the VS2017 script. Generated with the assistance of an AI coding tool.
|
Thanks for testing, and for the detailed log, that helped a lot. Two separate bugs, both further down the script than the detection fix in this PR:
Both are pushed to this branch now. One thing I noticed in your log: it shows Would appreciate another test run when you get a chance. |
|
I have tried again. Note that in the mean time I used the original workaround and have started to compile the code. I needed to use boost_1_74_0 as it won't easily compile with Visual Studio 2017. There are a number of issues with lambda functions and the use of auto that Visual Studio 2017 won't compile. I am required to use Visual Studio 2017 on this project, so I am stuck, but right now the issue below is the least of my problems. I appreciate your help, but the work around is all I need for now. I used I see this Cloning into 'C:\Users\chris\work\cad\ifcopenshellbuildissue\IfcOpenShell-fix_deps\mpir'... MSBUILD : error MSB1008: Only one project can be specified. For switch syntax, type "MSBuild /help" An error occurred Last logged action: Build ended at 11:28:45.50. Time elapsed 0:02:46.95. |
|
Thanks for the follow-up, and that log explains it: So no action needed on your side, your workaround is the right call for now; once this PR is merged, the standard build path picks the fix up automatically. On the VS2017 C++ compile errors you are now hitting in IfcOpenShell itself (lambdas/auto): current IfcOpenShell targets C++17, and VS2017's support for it is incomplete, so building the current codebase with VS2017 is likely to keep fighting you. If the 2017 toolset is a hard project constraint, an older IfcOpenShell release from the VS2017 era (or the prebuilt wheels/binaries if usable in your setup) may be the pragmatic route. Good luck with the project. |
msbuild.bat locates MSBuild via
vswhere -latest ... -property installationPathwith no version constraint. When more than one Visual Studio version is installed (e.g. 2017 plus a newer 2019, 2022 or 2026),-latestpicks the newest install instead of VS2017. The subsequentMSBuild\15.0\Bin\MSBuild.exeexistence check then silently fails against that wrong path, msbdir is left unset, and the later!msbdir!\msbuild.execall fails with a bare "msbuild.exe is not recognized" error that gives no indication of the real cause.Adds
-version "[15.0,16.0)", vswhere's documented range syntax for the VS2017 product line, so the query only ever matches a VS2017 install regardless of what else is present. Also fails loudly with a clear message if vswhere itself, a matching VS2017 install, or its MSBuild.exe can't be found, instead of falling through to the generic error further down.Traced from IfcOpenShell/IfcOpenShell#8631 and the workaround in IfcOpenShell/IfcOpenShell#8685 (which pre-detects msbdir this same way from the caller side, since it could not fix this script directly). This is a root-cause fix of the detection logic itself so callers no longer need that workaround.
This was traced from the script logic and vswhere's documented version-range syntax, not run on a real Windows VS2017 installation, since none was available in the environment this was developed in. Would appreciate a test from anyone with a real VS2017 + newer-VS setup before merging.
Generated with the assistance of an AI coding tool.