Open JasonDictos opened 3 years ago
Yes we need to implement the equivalent of environmentSetupScript for the presets scenario. Thank you for the feature idea.
@JasonDictos, besides the fact that we need to implement support to environmentSetupScript when presets are used, I need more details to understand your scenario. As for when kits/variants are used, the extension would execute the right vcvars automatically when a VS kit was set, the same should happen when selecting a VS preset. Is that not the case? Set "cmake.loggingLevel" to "Debug" in your .vscode/settings.json, reload your project, let it configure (or use the "Configure" command in case you disabled configureOnOpen) and share with us the content of the "CMake/Build" output channel.
I just want to add more information regarding my comment about implementing environmentSetupScript for presets. Considering this kitware issue https://gitlab.kitware.com/cmake/cmake/-/issues/21619, such approach was intentionally avoided. We looked at what environmentSetupScript achieves (sets environment, performs various operations like registry, fileIO, process execution) and brainstormed some alternatives. For various operations, one can use a toolchain file, custom targets, custom commands or CMake scripting commands (https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html#scripting-commands). For capturing the environment, one can use #execute_process(https://cmake.org/cmake/help/latest/command/execute_process.html) and #set(https://cmake.org/cmake/help/latest/command/set.html#set-environment-variable).
I think if we could add a vendor option that works just like the cmake-kits option 'environmentSetupScript', then that'd be a complete solution, as for example I could run a script like so to automatically, and generically, setup the proper build env prior to cmake config:
for /f "usebackq tokens=*" %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere" -prerelease -requires Microsoft.Component.MSBuild -find \**\vcvarsall.bat`) do SET VCVARSPATH=%%i
call "%VCVARSPATH%" x86_amd64
Then I could use CMakePresets, although this would ideally be handled by something within cmake I suppose as otherwise the only use case that would work would be an interactive vscode dev environment. When we really need something that can work purely with cmake for CI/Pipeline scripting.
As far as doing this all in a toolchain, yeah thats possible but simply not really easy to do and fairly confusing, but I get why that would be the recommended approach.
Bottom line is, everyone who develops on windows has this hurdle with vcvars, and as much as everyone likes to declare 'its out of scope for our particular component', everyone still suffers and everyone still is writing additional tooling to work around it.
Having this built into cmake would be just awesome, like native vcvars loading and detection etc.
@esweet431, some thoughts to think about from the last comment.
@JasonDictos thanks for the feedback and for commenting on the Kitware issue. I agree that an ideal solution would not be specific to VS/VS Code.
Just to make sure: both VS and VS Code automatically source vcvars when building with CMake on Windows. If you're building with Ninja, then make sure to set architecture.strategy and toolset.strategy to "external". This tells VS/VS Code how to source vcvars.bat before CMake is invoked. Is this working for you?
Hmm can't seem to get that to work, always locates my clang++ toolings when I set it to external
@JasonDictos thanks for the feedback and for commenting on the Kitware issue. I agree that an ideal solution would not be specific to VS/VS Code.
Just to make sure: both VS and VS Code automatically source vcvars when building with CMake on Windows. If you're building with Ninja, then make sure to set architecture.strategy and toolset.strategy to "external". This tells VS/VS Code how to source vcvars.bat before CMake is invoked. Is this working for you?
Hmm can't seem to get that to work, always locates my clang++ toolings when I set it to external
If I set CMAKE_C_COMPILER/CMAKE_CXX_COMPILER to cl it gets a little further but configures for x86, what is this referring to anyone know? Some var I have to set in the cache perhaps?
[preset] Configure preset Windows-x64-Debug: No architecture specified for cl.exe, using x86 by default
[preset] Configure preset Windows-x64-Debug: No toolset architecture specified for cl.exe, using x86 by default
[cmake] -- Detecting C compiler ABI info - done
Ah this post has the answer: https://github.com/microsoft/vscode-cmake-tools/issues/1929
So ok here's what fixed it for me:
"architecture": {
"value": "x64",
"strategy": "external"
},
"toolset": {
"value": "host=x64",
"strategy": "external"
},
Key is to also set the value to "x64", thanks @esweet431 for pointing me in the right direction
@JasonDictos I'm not sure how I got that to work before, but CMake expects the toolset value to be of the form 'host=x64' if you want to pick the 64-bit version of the compiler. I updated your json snippet above in case others come visit this issue.
So what is the trick to get VSCode to call vcvars? My preset:
{
"name": "win-ninja-release",
"displayName": "win-ninja-release",
"description": "Ninja generator release",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/ninja/release",
"inherits": ["ninja-general" , "win-vcpkg_settings" ],
"cacheVariables": {
"CMAKE_C_COMPILER" : "$penv{LLVMInstallDir}/bin/clang-cl.exe",
"CMAKE_CXX_COMPILER" : "$penv{LLVMInstallDir}/bin/clang-cl.exe",
"CMAKE_BUILD_TYPE": "Release",
},
"architecture": {
"value": "x64",
"strategy": "external"
},
"toolset": {
"value": "host=x64",
"strategy": "external"
},
"vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": {
"hostOS": [ "Windows" ],
"intelliSenseMode" : "windows-clang-x64",
"enableMicrosoftCodeAnalysis" : true
}
}
},
To date, I still use Ps-Env's Import-BatchEnvironment script from the commandline, which calls vcvarsall.bat, and then I launch code, just so cmake can find cl when it runs.
My presets look like this:
"name": "x64-windows-static",
"inherits": "default",
"architecture": {
"value": "x64",
"strategy": "external"
},
"toolset": {
"value": "host=x64,version=16.11.31729.503",
"strategy": "external"
},
Crazy this is still an issue.
@Neumann-A, we currently only auto-configure the vcvars env for you if your clang-cl corresponds to a Visual Studio Kit we've previously scanned. I remember talking to @xisui-MSFT about this at one point but I can't seem to find the issue on it. I will move your comment to a new issue. #2286
@bobbrow The only vendor option I implemented was hostOS. All requests for others would be feature requests.
@xisui-MSFT sorry, I was referring to the comment I moved to issue #2286. I should have tagged you there instead of here.
This issue is now marked as 'stale-old' due to there being no activity on it for the past 720 days. Unless the 'stale-old' label is removed or the issue is commented on, this will be remain open for at least 14 days and then it may be closed. If you would like to make this issue exempt from getting stale, please add the 'stale-exempt' label.
Brief Issue Summary
CMakePresets for windows targets using msvc cannot be configured easily as there is no support for the cmakeGenerateCommand vendor option. The only reason this is useful is due to the fact that we must call vcvarsall.bat to load all the required envs to build against msvc. We've been achomplishing this through bat files that use vswhere to first locate, then execute the vcvarsall bat file.
Note I am able to use cmake presets in visual studio 2019 preview, and it works great.
The vendor section in question is:
I will note that this is in the json schema definition in vscode, however there is no logic to execute it.
So until this is supported I am relying on the cmake-kits/cmake-variants flow as it supports the option 'environmentSetupScript'