conan
conan copied to clipboard
[feature] CMakePresets support for msvc toolset version
What is your suggestion?
Suggestion
Would it be possible for the Conan generated CMakePresets.json to include msvc.toolset version details (i.e. v143, v142, etc.) when populating the toolset.value field?
This would allow IDEs to know which vcvarsall.bat environment to use when building the project.
Expected Behavior
For example, when cross-compiling with VS2022 x64 to x86, I'd expect to see the conan generated CMakePresets.json look something like:
"generator": "Ninja",
"cacheVariables": {
"CMAKE_POLICY_DEFAULT_CMP0091": "NEW",
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
},
"architecture": {
"value": "x86",
"strategy": "external"
},
+"toolset": {
+ "value": "v143,host=x64",
+ "strategy": "external"
+},
"toolchainFile": "C:\\projects\\build\\foo\\RelWithDebInfo\\generators\\conan_toolchain.cmake",
"binaryDir": "C:\\projects\\build\\foo\\RelWithDebInfo
I can use tools.cmake.cmaketoolchain:toolset_arch=x64 to add the "host=x64" portion, but I don't have anyway to get v143 added.
VSCode recognizes this toolset / architecture combination and correctly chooses VS2022 and calls vcvarsall.bat amd64_x86 prior to calling CMake.
Current Behavior
Conan doesn't include toolset details in the generated CMakePresets.json file, so in order to get IDEs like VSCode to find the right environment, we need to adjust CMakePresets.json (as described above) or worse adjust the CMakeUserPresets.json file as follows:
{
"version": 4,
"vendor": {
"conan": {}
},
"include": [
"C:\\path\\to\\conan\\CMakePresets.json"
- ]
+ ],
+ "configurePresets": [
+ {
+ "name": "RelWithDebInfo",
+ "displayName": "RelWithDebInfo",
+ "inherits": "relwithdebinfo",
+ "toolset": {
+ "value": "v143,host=x64",
+ "strategy": "external"
+ }
+ ],
+ "buildPresets": [
+ {
+ "name": "RelWithDebInfo",
+ "displayName": "RelWithDebInfo",
+ "configurePreset": "RelWithDebInfo",
+ "configuration": "RelWithDebInfo"
+ }
+ ]
}
Conan already knows which vcvarsall to call, and and ensures the correct one gets called in the generated conanvcvars.bat.
Conan also appears to know about msvc.toolset version information:
https://github.com/conan-io/conan/blob/e33b55a486fd208223524dda49cce02dbe70c214/conans/client/conf/init.py#L117
At least for the legacy toolsets
And seems to know about the mapping: https://github.com/conan-io/conan/blob/e0a8ee058bc8dc2d9811b8aeb6999f69aeb78d85/conan/tools/microsoft/visual.py#L53-L60
It seems like Conan could should be able to use the msvc.toolset information from the build profile and populate the version field correctly.
Context
Follow up to https://github.com/conan-io/conan/issues/11623
Some IDEs are capable of targeting multiple toolsets (e.g. VS2015, VS2019, VS2022), and toolset.value is the way for the IDE to know which vcvarsall.bat to load and use internally while compiling.
It's the same step that Visual Studio takes for you when the IDE invokes CMake. Visual Studio parses the active Configure Preset for the host and target architecture specified by toolset and architecture. Visual Studio then sources the specified environment from vcvarsall.bat. When you build from the Windows command line with Ninja, you'll need to take this step yourself. Excerpt from MSDN Sourcing the environment when building with command-line generators on Windows
| IDE | Support |
|---|---|
| VSCode | Already Supported https://github.com/microsoft/vscode-cmake-tools/pull/2524 |
| QtCreator | In Progress QTCREATOR-BUG 28693 |
| CLion | Feature Request |
Thanks for your support!
Have you read the CONTRIBUTING guide?
- [X] I've read the CONTRIBUTING guide
Hi @thorntonryan
thanks for your detailed report.
Quick question, isn't Conan generating the right toolset inside the conan_toolchain.cmake? Because it is there:
{% if generator_platform %}
set(CMAKE_GENERATOR_PLATFORM "{{ generator_platform }}" CACHE STRING "" FORCE)
{% endif %}
{% if toolset %}
set(CMAKE_GENERATOR_TOOLSET "{{ toolset }}" CACHE STRING "" FORCE)
{% endif %}
The reason why things are by default if possible in the toolchain file is because conan needs to be compatible down to CMake 3.15, so no presets. The more things we put in the presets, the more complicated is for developers with CMake < 3.20 to issue a command line that will work for them.
Hrmm. Doesn't look like it.
If I run the following:
$ conan new hello/0.1 --template cmake_lib
And then install that project:
$ conan install conanfile.py -pr:b x86_64-windows-msvc143 -pr:h x86-windows-msvc143
$ conan profile show x86-windows-msvc143
Configuration for profile x86-windows-msvc143:
[settings]
os=Windows
os_build=Windows
arch_build=x86_64
compiler=Visual Studio
compiler.version=17
build_type=RelWithDebInfo
arch=x86
$ conan profile show x86_64-windows-msvc143
Configuration for profile x86_64-windows-msvc143:
[settings]
os=Windows
os_build=Windows
arch_build=x86_64
compiler=Visual Studio
compiler.version=17
build_type=RelWithDebInfo
arch=x86_64
Conan generates the following:
CMakePresets.json
{
"version": 3,
"vendor": {
"conan": {}
},
"cmakeMinimumRequired": {
"major": 3,
"minor": 15,
"patch": 0
},
"configurePresets": [
{
"name": "relwithdebinfo",
"displayName": "'relwithdebinfo' config",
"description": "'relwithdebinfo' configure using 'Ninja' generator",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_POLICY_DEFAULT_CMP0091": "NEW",
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
},
"architecture": {
"value": "x86",
"strategy": "external"
},
"toolchainFile": "C:\\projects\\build\\conan\\build\\RelWithDebInfo\\generators\\conan_toolchain.cmake",
"binaryDir": "C:\\projects\\build\\conan\\build\\RelWithDebInfo"
}
],
"buildPresets": [
{
"name": "relwithdebinfo",
"configurePreset": "relwithdebinfo"
}
],
"testPresets": [
{
"name": "relwithdebinfo",
"configurePreset": "relwithdebinfo"
}
]
}
CMakeUserPresets.json
{
"version": 4,
"vendor": {
"conan": {}
},
"include": [
"C:\\projects\\build\\conan\\build\\RelWithDebInfo\\generators\\CMakePresets.json"
]
}
conan_toolchain.cmake
# Conan automatically generated toolchain file
# DO NOT EDIT MANUALLY, it will be overwritten
# Avoid including toolchain file several times (bad if appending to variables like
# CMAKE_CXX_FLAGS. See https://github.com/android/ndk/issues/323
include_guard()
message(STATUS "Using Conan toolchain: ${CMAKE_CURRENT_LIST_FILE}")
if(${CMAKE_VERSION} VERSION_LESS "3.15")
message(FATAL_ERROR "The 'CMakeToolchain' generator only works with CMake >= 3.15")
endif()
# Definition of VS runtime, defined from build_type, compiler.runtime, compiler.runtime_type
cmake_policy(GET CMP0091 POLICY_CMP0091)
if(NOT "${POLICY_CMP0091}" STREQUAL NEW)
message(FATAL_ERROR "The CMake policy CMP0091 must be NEW, but is '${POLICY_CMP0091}'")
endif()
set(CMAKE_MSVC_RUNTIME_LIBRARY "$<$<CONFIG:RelWithDebInfo>:MultiThreadedDLL>")
# Extra c, cxx, linkflags and defines
if(DEFINED CONAN_CXX_FLAGS)
string(APPEND CMAKE_CXX_FLAGS_INIT " ${CONAN_CXX_FLAGS}")
endif()
if(DEFINED CONAN_C_FLAGS)
string(APPEND CMAKE_C_FLAGS_INIT " ${CONAN_C_FLAGS}")
endif()
if(DEFINED CONAN_SHARED_LINKER_FLAGS)
string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " ${CONAN_SHARED_LINKER_FLAGS}")
endif()
if(DEFINED CONAN_EXE_LINKER_FLAGS)
string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ${CONAN_EXE_LINKER_FLAGS}")
endif()
get_property( _CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE )
if(_CMAKE_IN_TRY_COMPILE)
message(STATUS "Running toolchain IN_TRY_COMPILE")
return()
endif()
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
# Definition of CMAKE_MODULE_PATH
# Explicitly defined "buildirs" of "build" context dependencies
# the generators folder (where conan generates files, like this toolchain)
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
# Definition of CMAKE_PREFIX_PATH, CMAKE_XXXXX_PATH
# The Conan local "generators" folder, where this toolchain is saved.
list(PREPEND CMAKE_PREFIX_PATH ${CMAKE_CURRENT_LIST_DIR} )
if(NOT DEFINED CMAKE_FIND_ROOT_PATH_MODE_PACKAGE OR CMAKE_FIND_ROOT_PATH_MODE_PACKAGE STREQUAL "ONLY")
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE "BOTH")
endif()
if(NOT DEFINED CMAKE_FIND_ROOT_PATH_MODE_PROGRAM OR CMAKE_FIND_ROOT_PATH_MODE_PROGRAM STREQUAL "ONLY")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM "BOTH")
endif()
if(NOT DEFINED CMAKE_FIND_ROOT_PATH_MODE_LIBRARY OR CMAKE_FIND_ROOT_PATH_MODE_LIBRARY STREQUAL "ONLY")
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY "BOTH")
endif()
if(NOT DEFINED CMAKE_FIND_ROOT_PATH_MODE_INCLUDE OR CMAKE_FIND_ROOT_PATH_MODE_INCLUDE STREQUAL "ONLY")
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE "BOTH")
endif()
if (DEFINED ENV{PKG_CONFIG_PATH})
set(ENV{PKG_CONFIG_PATH} "C:/projects/build/conan/build/RelWithDebInfo/generators;$ENV{PKG_CONFIG_PATH}")
else()
set(ENV{PKG_CONFIG_PATH} "C:/projects/build/conan/build/RelWithDebInfo/generators;")
endif()
message(STATUS "Conan toolchain: Setting BUILD_SHARED_LIBS = OFF")
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries")
# Variables
# Variables per configuration
# Preprocessor definitions
# Preprocessor definitions per configuration
Unfortunately, I'm not seeing CMAKE_GENERATOR_PLATFORM or CMAKE_GENERATOR_TOOLSET there.
If I try the same thing with the msvc compiler:
$ conan install conanfile.py -pr:b x86_64-windows-msvc-143 -pr:h x86-windows-msvc-143
$ conan profile show x86-windows-msvc-143
Configuration for profile x86-windows-msvc-143:
[settings]
os=Windows
os_build=Windows
arch_build=x86_64
compiler=msvc
compiler.version=193
build_type=RelWithDebInfo
arch=x86
compiler.cppstd=20
compiler.runtime=dynamic
$ conan profile show x86_64-windows-msvc-143
Configuration for profile x86_64-windows-msvc-143:
[settings]
os=Windows
os_build=Windows
arch_build=x86_64
compiler=msvc
compiler.version=193
build_type=RelWithDebInfo
arch=x86_64
compiler.cppstd=20
compiler.runtime=dynamic
Conan generates the following:
CmakePresets.json
{
"version": 3,
"vendor": {
"conan": {}
},
"cmakeMinimumRequired": {
"major": 3,
"minor": 15,
"patch": 0
},
"configurePresets": [
{
"name": "relwithdebinfo",
"displayName": "'relwithdebinfo' config",
"description": "'relwithdebinfo' configure using 'Ninja' generator",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_POLICY_DEFAULT_CMP0091": "NEW",
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
},
"architecture": {
"value": "x86",
"strategy": "external"
},
"toolchainFile": "C:\\projects\\build\\conan\\build\\RelWithDebInfo\\generators\\conan_toolchain.cmake",
"binaryDir": "C:\\projects\\build\\conan\\build\\RelWithDebInfo"
}
],
"buildPresets": [
{
"name": "relwithdebinfo",
"configurePreset": "relwithdebinfo"
}
],
"testPresets": [
{
"name": "relwithdebinfo",
"configurePreset": "relwithdebinfo"
}
]
}
CMakeUserPresets.json
{
"version": 4,
"vendor": {
"conan": {}
},
"include": [
"C:\\projects\\build\\conan\\build\\RelWithDebInfo\\generators\\CMakePresets.json"
]
}
conan_toolchain.cmake
# Conan automatically generated toolchain file
# DO NOT EDIT MANUALLY, it will be overwritten
# Avoid including toolchain file several times (bad if appending to variables like
# CMAKE_CXX_FLAGS. See https://github.com/android/ndk/issues/323
include_guard()
message(STATUS "Using Conan toolchain: ${CMAKE_CURRENT_LIST_FILE}")
if(${CMAKE_VERSION} VERSION_LESS "3.15")
message(FATAL_ERROR "The 'CMakeToolchain' generator only works with CMake >= 3.15")
endif()
# Definition of VS runtime, defined from build_type, compiler.runtime, compiler.runtime_type
cmake_policy(GET CMP0091 POLICY_CMP0091)
if(NOT "${POLICY_CMP0091}" STREQUAL NEW)
message(FATAL_ERROR "The CMake policy CMP0091 must be NEW, but is '${POLICY_CMP0091}'")
endif()
set(CMAKE_MSVC_RUNTIME_LIBRARY "$<$<CONFIG:RelWithDebInfo>:MultiThreadedDLL>")
message(STATUS "Conan toolchain: C++ Standard 20 with extensions OFF")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Extra c, cxx, linkflags and defines
if(DEFINED CONAN_CXX_FLAGS)
string(APPEND CMAKE_CXX_FLAGS_INIT " ${CONAN_CXX_FLAGS}")
endif()
if(DEFINED CONAN_C_FLAGS)
string(APPEND CMAKE_C_FLAGS_INIT " ${CONAN_C_FLAGS}")
endif()
if(DEFINED CONAN_SHARED_LINKER_FLAGS)
string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " ${CONAN_SHARED_LINKER_FLAGS}")
endif()
if(DEFINED CONAN_EXE_LINKER_FLAGS)
string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ${CONAN_EXE_LINKER_FLAGS}")
endif()
get_property( _CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE )
if(_CMAKE_IN_TRY_COMPILE)
message(STATUS "Running toolchain IN_TRY_COMPILE")
return()
endif()
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
# Definition of CMAKE_MODULE_PATH
# the generators folder (where conan generates files, like this toolchain)
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
# Definition of CMAKE_PREFIX_PATH, CMAKE_XXXXX_PATH
# The Conan local "generators" folder, where this toolchain is saved.
list(PREPEND CMAKE_PREFIX_PATH ${CMAKE_CURRENT_LIST_DIR} )
if(NOT DEFINED CMAKE_FIND_ROOT_PATH_MODE_PACKAGE OR CMAKE_FIND_ROOT_PATH_MODE_PACKAGE STREQUAL "ONLY")
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE "BOTH")
endif()
if(NOT DEFINED CMAKE_FIND_ROOT_PATH_MODE_PROGRAM OR CMAKE_FIND_ROOT_PATH_MODE_PROGRAM STREQUAL "ONLY")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM "BOTH")
endif()
if(NOT DEFINED CMAKE_FIND_ROOT_PATH_MODE_LIBRARY OR CMAKE_FIND_ROOT_PATH_MODE_LIBRARY STREQUAL "ONLY")
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY "BOTH")
endif()
if(NOT DEFINED CMAKE_FIND_ROOT_PATH_MODE_INCLUDE OR CMAKE_FIND_ROOT_PATH_MODE_INCLUDE STREQUAL "ONLY")
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE "BOTH")
endif()
if (DEFINED ENV{PKG_CONFIG_PATH})
set(ENV{PKG_CONFIG_PATH} "C:/projects/build/conan/build/RelWithDebInfo/generators;$ENV{PKG_CONFIG_PATH}")
else()
set(ENV{PKG_CONFIG_PATH} "C:/projects/build/conan/build/RelWithDebInfo/generators;")
endif()
message(STATUS "Conan toolchain: Setting BUILD_SHARED_LIBS = OFF")
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries")
# Variables
# Variables per configuration
# Preprocessor definitions
# Preprocessor definitions per configuration
If I then add toolset_arch to my global.conf:
tools.cmake.cmaketoolchain:generator=Ninja
+tools.cmake.cmaketoolchain:toolset_arch=x64
Then I see toolset partially added to the generated CMakePresets.json:
"generator": "Ninja",
"cacheVariables": {
"CMAKE_POLICY_DEFAULT_CMP0091": "NEW",
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
},
+"toolset": {
+ "value": "host=x64",
+ "strategy": "external"
+},
"architecture": {
"value": "x86",
"strategy": "external"
},
But, in order to get VSCode (and hopefully Qt Creator soon) to detect / pick the right toolset, it needs to be:
"toolset": {
- "value": "host=x64",
+ "value": "v193,host=x64",
"strategy": "external"
},
And like the "Visual Studio" compiler, I'm not seeing CMAKE_GENERATOR_PLATFORM or CMAKE_GENERATOR_TOOLSET there either.
The reason why things are by default if possible in the toolchain file is because conan needs to be compatible down to CMake 3.15, so no presets. The more things we put in the presets, the more complicated is for developers with CMake < 3.20 to issue a command line that will work for them.
Completely understandable. I appreciate your commitment to maintaining support/stability for folks on older versions of CMake.
I guess I was under the impression that when external was used, CMake ignored those values...so I'd be surprised if it complicated command line usage in any way.
That's certainly what the CMake 3.20 cmake-presets doc seems to suggest:
"external" Do not set the value, even if the generator supports it. This is useful if, for example, a preset uses the Ninja generator, and an IDE knows how to set up the Visual C++ environment from the architecture and toolset fields. In that case, CMake will ignore the field, but the IDE can use them to set up the environment before invoking CMake.
Same for the MSDN doc according to Select your target and host architecture when building with the Visual C++ toolset:
The
architecture.strategyandtoolset.strategyvalues tell CMake how to handle the architecture and toolset fields.setmeans CMake sets the respective value, andexternalmeans CMake won't set the respective value.
As best I can tell, these toolset / architecture fields appear to be the way to tell the IDE what env to load. And since https://github.com/conan-io/conan/pull/11666, Conan already has limited support for this with Visual Studio, so I was hoping it may be possible to extend what we write slightly that way we can support more IDEs like VSCode (and soon Qt Creator and maybe eventually CLion). At least I struggle to see how it could be worse than the status quo.
Conan just needs to prefix the toolset.value with the toolset version somehow.
https://github.com/conan-io/conan/blob/aef2eea04fa5c457ae28950b836264d969ec1322/conan/tools/cmake/presets.py#L70
Really bad psuedo code:
+toolset_version = msvc_version_to_toolset_version(conanfile.settings.get_safe("compiler.version"))
+toolset_value = toolset_version
+if toolset_arch:
+ toolset_value = toolset_value + "," + toolset_arch
ret["toolset"] = {
- "value": toolset_arch,
+ "value": toolset_value
"strategy": "external"
}
Anyways, I can always work around the issue if needed. I think it'd be consistent and an improvement with what Conan is already doing, and improved CMakePresets support seems like the direction a lot of IDEs are going, but I totally understand the compatibility concerns. If the request is not in alignment with where Conan is going at present, feel free to close the issue :)
Thanks again for considering the request. Conan is a tremendous product and you, your team, and this community do a tremendous job. Keep up the good work!
CMAKE_GENERATOR_TOOLSET only affects the Visual Studio generators (well, and also Xcode and Green Hills MULTI, for non-MSVC usage). And it doesn't set the environment directly even then - it just puts the toolset into the .vcxproj files, leaving the ultimate resolution for MSBuild. It doesn't have any effect at all when you are using Ninja/Make/etc - those rely on you having already called vcvarsall. conan handle that for itself, by putting the vcvars call into conanbuild.bat (and thus into anything launched by the conanfile.py's self.run. But IDEs mostly don't have any way to make use of a .bat file that would launch a new shell with the environment altered, since the process is already running.
These "strategy": "external" toolset entries seem to be what the major IDE vendors are coalescing on, so it would be nice if conan would include that information (even though it is semi-redundant to conanvcvars.bat).
@thorntonryan, does this workaround still work for you with Conan 2.0? I am getting "No CMAKE_CXX_COMPILER could be found." which means that the VSCode does not load vcvars.
@mpusz ,
Using Conan 1.58 and a project using cmake_layout, looks like I needed to tweak the generated CMakeUserPresets.json in the following way:
```diff
{
"version": 4,
"vendor": {
"conan": {}
},
"include": [
"C:\\path\\to\\build\\Debug\\generators\\CMakePresets.json",
"C:\\path\\to\\buid\\RelWithDebInfo\\generators\\CMakePresets.json"
- ]
+ ],
+ "configurePresets": [
+ {
+ "name": "Debug",
+ "displayName": "Debug",
+ "inherits": "debug",
+ "toolset": {
+ "value": "v143,host=x64",
+ "strategy": "external"
+ },
+ "cacheVariables": {
+ "CMAKE_CXX_COMPILER": "cl.exe",
+ "CMAKE_MAKE_PROGRAM": "ninja.exe"
+ }
+ },
+ {
+ "name": "RelWithDebInfo",
+ "displayName": "RelWithDebInfo",
+ "inherits": "relwithdebinfo",
+ "toolset": {
+ "value": "v143,host=x64",
+ "strategy": "external"
+ },
+ "cacheVariables": {
+ "CMAKE_CXX_COMPILER": "cl.exe",
+ "CMAKE_MAKE_PROGRAM": "ninja.exe"
+ }
+ }
+ ],
+ "buildPresets": [
+ {
+ "name": "Debug",
+ "displayName": "Debug",
+ "configurePreset": "Debug",
+ "configuration": "Debug"
+ },
+ {
+ "name": "RelWithDebInfo",
+ "displayName": "RelWithDebInfo",
+ "configurePreset": "RelWithDebInfo",
+ "configuration": "RelWithDebInfo"
+ }
+ ]
}
Honestly not sure why these need to be defined. I thought I've called cmake from a VS Dev prompt before and it finds cl.exe automatically , so I'm not sure why VSCode seems to need it.
But at least it finds the right cl.exe.
Maybe try that?
Thanks! By adding the following:
{
"version": 3,
"vendor": {
"conan": {}
},
"cmakeMinimumRequired": {
"major": 3,
"minor": 15,
"patch": 0
},
"configurePresets": [
{
"name": "conan-msvc-193",
"displayName": "'conan-msvc-193' config",
"description": "'conan-msvc-193' configure using 'Ninja Multi-Config' generator",
"generator": "Ninja Multi-Config",
"cacheVariables": {
"CMAKE_POLICY_DEFAULT_CMP0091": "NEW",
+ "CMAKE_CXX_COMPILER": "cl.exe"
},
"architecture": {
"value": "x64",
"strategy": "external"
},
+ "toolset": {
+ "value": "v143,host=x64",
+ "strategy": "external"
+ },
"toolchainFile": "D:\\repos\\units\\build\\msvc-193\\generators\\conan_toolchain.cmake",
"binaryDir": "D:\\repos\\units\\build\\msvc-193"
}
],
"buildPresets": [
{
"name": "conan-msvc-193-release",
"configurePreset": "conan-msvc-193",
"configuration": "Release"
}
],
"testPresets": [
{
"name": "conan-msvc-193-release",
"configurePreset": "conan-msvc-193",
"configuration": "Release"
}
]
}
I was able to make MSVC 193 work somehow. The only problem compared to running from VS Dev prompt is that I get the following warning:
warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
However, when I tried to do the same for MSVC 192 installed under VS2022 it didn't work. I also tried with -c tools.microsoft.msbuild:vs_version=17 provided to conan install command line with no luck.
Wonder if this could be accomplished using the new msvs_toolset helper:
https://github.com/conan-io/conan/pull/13041
There is already conf::tools.cmake.cmaketoolchain:toolset_arch in place which controls the generation of the toolset section / injects host= into the toolset.value.
Except this is not correctly prefixed with settings::compiler.toolset, respectively is missing entirely when the config entry for toolset_arch wasn't overwritten.
Hi all,
I am checking this, but need some guidance, it would be necessary to update the reproduction, it seems that latest Conan 2.0.17 is adding toolset to the presets, still, it doesn't automatically work for me in VSCode, which seems the ultimate goal.
Steps:
conan new cmake_exe -d name=app -d version=0.1conan install . -c tools.cmake.cmaketoolchain:generator=NinjaThe resulting presets will have:"toolset": { "value": "v143", "strategy": "external" }, "architecture": { "value": "x64", "strategy": "external" },- I open
code .the current folder - I have the cmake tools from Microsoft, version v1.16.32
- When configuring and trying to build, it will still not find the compiler
- Even if I edit the CMakePresets.json adding the above CXX as env-vars or cache vars, still not work
- Even if I edit and add
v143,host=x64manually to the presets, still doesn't work
Can anyone please provide with detailed updated repro? Thanks!
Without host=x64, "value": "v143" is under-specified and defaults to the old x86 host toolchain.
I expect you got the warning
[preset] Configure preset ...: No toolset architecture specified for cl.exe, using "host=x86" by default
Did you have the x86 host toolchain installed? Just guessing, but Microsoft may finally have switched to x64 as the default (and only) installed host toolset for v143.
Without host=x64, "value": "v143" is under-specified and defaults to the old x86 host toolchain.
But even if I add it manually to my presets, still same error. (I will clarify in my above steps). Not really a x86 toolchain issue, it seems that even with the host=x64 it is not working.
You clicked here?
When you do that, what messages do you get in the "Output" panel?
[driver] Removing C:/Users/Diego/conanws/kk/build/Release/CMakeCache.txt
[driver] Removing C:\Users\Diego\conanws\kk\build\Release\CMakeFiles
[proc] Executing command: C:\ws\cmake\cmake-3.25.3-windows-x86_64\bin\cmake.EXE -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=C:/Users/memsharded/conanws/kk/build/Release/generators/conan_toolchain.cmake -SC:/Users/memsharded/conanws/kk -BC:/Users/memsharded/conanws/kk/build/Release -G Ninja
[cmake] -- Using Conan toolchain: C:/Users/memsharded/conanws/kk/build/Release/generators/conan_toolchain.cmake
[cmake] -- Conan toolchain: C++ Standard 14 with extensions OFF
[cmake] -- The CXX compiler identification is unknown
[cmake] CMake Error at CMakeLists.txt:2 (project):
[cmake] No CMAKE_CXX_COMPILER could be found.
[cmake]
[cmake] Tell CMake where to find the compiler by setting either the environment
[cmake] variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
[cmake] to the compiler, or to the compiler name if it is in the PATH.
CMAKE_C_COMPILER and CMAKE_CXX_COMPILER are both required as cache variables for Ninja. Set both to "cl.exe".
No warnings prefixed with [preset], so that should have been sane.
The invocation of vswhere is silent in that output
Yes, that is right, adding both
"cacheVariables": {
"CMAKE_POLICY_DEFAULT_CMP0091": "NEW",
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_CXX_COMPILER": "cl.exe",
"CMAKE_C_COMPILER": "cl.exe"
}
Seems to make it work. The output was sometimes confusing, because it runs automatically before adding it, so it is not clear if it is running with your latest changes or running the previous state.
Maybe making
conan install . -c tools.cmake.cmaketoolchain:generator=Ninja
-c tools.build:compiler_executables="{'c': 'cl.exe', 'cpp': 'cl.exe'}"
-c tools.cmake.cmaketoolchain:toolset_arch=x64
to add cl.exe to Presets (at the moment it only adds it to conan_toolchain.cmake.
By the way, the way to define the x64 toolset is:
conan install . -c tools.cmake.cmaketoolchain:generator=Ninja -c tools.cmake.cmaketoolchain:toolset_arch=x64
and that will make
"toolset": {
"value": "v143,host=x64",
"strategy": "extern
automatically
CMAKE_C_COMPILER and CMAKE_CXX_COMPILER are both required as cache variables for ~Ninja~ ~VSCode~ VSCodes' cmake-tools integration.
Minor correction, but this requirement is a subtle wrinkle of ~VSCode's~ VSCode's cmake-tools implementation: https://github.com/microsoft/vscode-cmake-tools/blob/main/src/preset.ts#L753-L754
Yeah, my understanding is that the integration of cmake-tools for VSCode checks the CMAKE_XX_COMPILER to decide to call vcvars automatically.
One other thing that seems missing here is a way to have the toolset be something like "v143,version=14.29" when trying to use an installation that contains Side-by-side minor version MSVC toolsets. That's the syntax adopted by cmake -T in CMake 3.12 and greater and also copied for VScode's handlling of toolset { . strategy: "external" }`, specifically in varsForVSInstallation)
So maybe [conf]tools.cmake.cmaketoolchain:toolset_version, translated to ,version=... and appended similarly to toolset_arch?
Hmm, actually this seems to be partially in place already:
GenericSystemBlock.get_toolset already has code to use settings.compiler.version and settings.compiler.update such that compiler.version=193 and compiler.update=7 would result in toolset=...,version=14.37. Which I think is good enough - Visual Studio doesn't support side-by-side patch versions, just side-by-side minors, so there's little reason to what to specify a 3- or 4-digit version anyway. And if you care, you probably care enough that putting it in settings (and thus getting distinct package_id) is appropriate.
But conan.tools.microsoft.visual._vcvars_vers does not seem to have similar code to consider settings.compiler.update, so it will only do 14.1, 14.2, or 14.3, but never distinguish -vcvars_ver=14.37 vs -vcvars_ver=14.38. Which means conanbuild.bat wouldn't get the same minor version that CMakePresets does....
Split off the VCvars issue as #15522, since that's not actually about CMakePresets
https://github.com/conan-io/conan/issues/15522 has been merged it will be in Conan 2.3.
I was having another look, this is the current state:
- The Coan integrations already generate the right Presets
toolsetinformation - I cannot manage to make it work the previous workaround of adding
for VSCode automatically launching vcvars, this is not happening anymore."cacheVariables": { "CMAKE_POLICY_DEFAULT_CMP0091": "NEW", "CMAKE_BUILD_TYPE": "Release", "CMAKE_CXX_COMPILER": "cl.exe", "CMAKE_C_COMPILER": "cl.exe" }
Can anyone please confirm this? The only missing gap would be the CMAKE_<LANG>_COMPILER definitions? Can you make it work with such workaround?
@memsharded
conan 2.5.0
We use latest Visual Studio 2022 (without Code) and we open our CMake projects with Open Folder function (without generating MSBuild solution). We also have MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.29) minor toolset installed.
As generator we use Ninja (we have tc = CMakeToolchain(self, generator="Ninja") in our conanfile).
We use following profile (host and build are the same):
[settings]
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=17
compiler.runtime=dynamic
compiler.runtime_type=Release
compiler.version=192
os=Windows
Important thing is that compiler.update is not set.
Conan generates CMakePresets.json with following toolset block:
"toolset": {
"value": "v142",
"strategy": "external"
},
When using generated presets Visual Studio (without Code) initializes environment for MSVC 19.40 (the latest for Visual Studio 2022, not the one we requested in a profile) and inside IDE in a CMake output tab we have:
1> CommandPromptType=Native
1> DevEnvDir=C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\
1> ExtensionSdkDir=C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs
1> EXTERNAL_INCLUDE=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.40.33807\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.40.33807\ATLMFC\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include;C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\um;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\shared;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\winrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\cppwinrt;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um
1> Framework40Version=v4.0
...
1> [CMake] -- The CXX compiler identification is MSVC 19.40.33811.0
...
1> [CMake] -- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe - skipped
...
The fix here is to specify toolset version in a toolset block like so:
"toolset": {
"value": "v142,version=14.2",
"strategy": "external"
},
After changing generated preset, Visual Studio (without Code) initializes environment for MSVC 14.29 (the one we requested from profile):
1> Environment settings:
1> CommandPromptType=Native
1> DevEnvDir=C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\
1> ExtensionSdkDir=C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs
1> EXTERNAL_INCLUDE=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.29.30133\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.29.30133\ATLMFC\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include;C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\um;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\shared;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\winrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\cppwinrt;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um
1> Framework40Version=v4.0
...
1> [CMake] -- The CXX compiler identification is MSVC 19.29.30154.0
...
1> [CMake] -- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64/cl.exe - skipped
...
We also use Visual Studio Code. As for the VS Code, the toolset block that conan generates now
"toolset": {
"value": "v142",
"strategy": "external"
},
is enough to initialize environment for correct minor toolset requested in a profile (MSVC 14.29). There was a bug in Visual Studio Code CMake Tools extension reported and fixed which is why having just v142 here is enough .
Changing "value": "v142" to "value": "v142,version=14.2" doesn't change anything for Visual Studio Code, but as I explained earlier it fixes the behavior of Visual Studio (without Code).
The generation of toolset block is happening there
https://github.com/conan-io/conan/blob/47d4e749d06fd51179834a6a5c61af916a1f500a/conan/tools/cmake/presets.py#L142-L150
Which leads us to
https://github.com/conan-io/conan/blob/47d4e749d06fd51179834a6a5c61af916a1f500a/conan/tools/cmake/toolchain/blocks.py#L920-L929
To fix the Visual Studio (without Code) behavior in this case we need to add ,version=... even when compiler_update is not set like so:
# It is full one(19.28), not generic 19.2X
# The equivalent of compiler 19.26 is toolset 14.26
toolset += ",version=14.{}{}".format(compiler_version[-1], compiler_update if compiler_update is not None else "")
One more thing regarding toolset value. I believe Conan also should add ,host=... to specify host tools architecture. From the logs I provided I can tell that without specifying it Visual Studio (without Code) defaults to x64 (look at the compiler path detected). And when using Visual Studio Code there are lines in logs which tell me that Visual Studio Code defaults to x86:
[preset] Configure preset ... : No toolset architecture specified for cl.exe, using "host=x86" by default
...
[cmake] -- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.29.30133/bin/HostX86/x64/cl.exe - skipped
...
In my case I expect conan to generate such toolset block:
"toolset": {
"value": "v142,version=14.2,host=x64",
"strategy": "external"
},
Which will work both in Visual Studio and Visual Studio Code.
Conan also should add
"cacheVariables":
"CMAKE_CXX_COMPILER": "cl.exe",
"CMAKE_C_COMPILER": "cl.exe"
}
to generated CMakePresets for msvc compiler. Without this Visual Studio Code finds clang I have in my PATH.