Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] CMakePresets support for msvc toolset version #13136

Open
1 task done
thorntonryan opened this issue Feb 15, 2023 · 25 comments
Open
1 task done

[feature] CMakePresets support for msvc toolset version #13136

thorntonryan opened this issue Feb 15, 2023 · 25 comments
Milestone

Comments

@thorntonryan
Copy link
Contributor

thorntonryan commented Feb 15, 2023

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:

toolset: [None, v110_xp, v120_xp, v140_xp, v141_xp]

At least for the legacy toolsets

And seems to know about the mapping:

def msvc_version_to_toolset_version(version):
toolsets = {'170': 'v110',
'180': 'v120',
'190': 'v140',
'191': 'v141',
'192': 'v142',
"193": 'v143'}
return toolsets.get(str(version))

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 #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
microsoft/vscode-cmake-tools#2524
QtCreator In Progress
QTCREATOR-BUG 28693
CLion Feature Request

Thanks for your support!

Have you read the CONTRIBUTING guide?

  • I've read the CONTRIBUTING guide
@memsharded
Copy link
Member

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.

@thorntonryan
Copy link
Contributor Author

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.

@thorntonryan
Copy link
Contributor Author

thorntonryan commented Feb 16, 2023

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.

@thorntonryan
Copy link
Contributor Author

thorntonryan commented Feb 16, 2023

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.strategy and toolset.strategy values tell CMake how to handle the architecture and toolset fields. set means CMake sets the respective value, and external means 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 #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.

"value": toolset_arch,

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"
}

@thorntonryan
Copy link
Contributor Author

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!

@puetzk
Copy link

puetzk commented Feb 16, 2023

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).

@mpusz
Copy link

mpusz commented May 27, 2023

@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.

@thorntonryan
Copy link
Contributor Author

thorntonryan commented May 30, 2023

@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?

@mpusz
Copy link

mpusz commented May 31, 2023

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.

@thorntonryan
Copy link
Contributor Author

thorntonryan commented May 31, 2023

Wonder if this could be accomplished using the new msvs_toolset helper:
#13041

@Ext3h
Copy link

Ext3h commented Jan 10, 2024

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.

@memsharded memsharded added this to the 2.1 milestone Jan 10, 2024
@memsharded
Copy link
Member

memsharded commented Jan 24, 2024

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.1
  • conan install . -c tools.cmake.cmaketoolchain:generator=Ninja
    The 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=x64 manually to the presets, still doesn't work

Can anyone please provide with detailed updated repro? Thanks!

@Ext3h
Copy link

Ext3h commented Jan 24, 2024

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.

@memsharded
Copy link
Member

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.

@Ext3h
Copy link

Ext3h commented Jan 24, 2024

image
You clicked here?

When you do that, what messages do you get in the "Output" panel?

@memsharded
Copy link
Member

[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.

@Ext3h
Copy link

Ext3h commented Jan 24, 2024

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

@memsharded
Copy link
Member

memsharded commented Jan 24, 2024

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.

@memsharded
Copy link
Member

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

@thorntonryan
Copy link
Contributor Author

thorntonryan commented Jan 24, 2024

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

@memsharded
Copy link
Member

Yeah, my understanding is that the integration of cmake-tools for VSCode checks the CMAKE_XX_COMPILER to decide to call vcvars automatically.

@puetzk
Copy link

puetzk commented Jan 25, 2024

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?

@puetzk
Copy link

puetzk commented Jan 25, 2024

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....

@puetzk
Copy link

puetzk commented Jan 25, 2024

Split off the VCvars issue as #15522, since that's not actually about CMakePresets

@memsharded memsharded modified the milestones: 2.1, 2.2 Feb 15, 2024
@memsharded memsharded modified the milestones: 2.2.0, 2.3.0 Mar 19, 2024
@memsharded
Copy link
Member

#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 toolset information
  • I cannot manage to make it work the previous workaround of adding
    "cacheVariables": {
                  "CMAKE_POLICY_DEFAULT_CMP0091": "NEW",
                  "CMAKE_BUILD_TYPE": "Release",
                  "CMAKE_CXX_COMPILER": "cl.exe",
                  "CMAKE_C_COMPILER": "cl.exe"
              }
    for VSCode automatically launching vcvars, this is not happening anymore.

Can anyone please confirm this? The only missing gap would be the CMAKE_<LANG>_COMPILER definitions? Can you make it work with such workaround?

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

No branches or pull requests

5 participants