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

fix for msvc toolset version overflow #15588

Merged

Conversation

memsharded
Copy link
Member

@memsharded memsharded commented Feb 2, 2024

Changelog: Fix: Fix for future msvc toolset version overflow
Docs: Omit

After #15947

Close #15583
Close #16239

@memsharded memsharded added this to the 2.1 milestone Feb 2, 2024
@memsharded memsharded marked this pull request as ready for review February 5, 2024 09:59
Copy link
Contributor

@jcar87 jcar87 left a comment

Choose a reason for hiding this comment

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

Reading the Microsoft blog post, I interpret a new compiler version that would be "194" ? https://devblogs.microsoft.com/cppblog/msvc-toolset-minor-version-number-14-40-in-vs-2022-v17-10/

If that is the case, there would be further implications, e.g.:

Note that if I read the following right, conan profile detect will detect it as compiler.version=194:

version = f"{version_regex.group('major')}{version_regex.group('minor')[0]}"

conans/test/unittests/tools/cmake/test_cmaketoolchain.py Outdated Show resolved Hide resolved
@memsharded memsharded modified the milestones: 2.1, 2.2 Feb 7, 2024
@memsharded memsharded modified the milestones: 2.2.0, 2.3.0 Mar 15, 2024
@memsharded memsharded requested a review from jcar87 March 22, 2024 14:39
@memsharded
Copy link
Member Author

@jcar87 I have proposed a full compiler.version=194 => VS 17 2022 mapping, please review and lets discuss

@memsharded memsharded marked this pull request as ready for review April 15, 2024 11:32
jcar87
jcar87 previously approved these changes May 3, 2024
@Nekto89
Copy link
Contributor

Nekto89 commented May 3, 2024

I've tried this branch locally with VS2022 Update 10 Preview 6 + CMake 3.29.2 and it doesn't work

conan install --remote conancenter --requires=sqlite3/3.45.3 --build=sqlite3/3.45.3 -pr:b test_profile -pr:h test_profile

======== Input profiles ========
Profile host:
[settings]
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=17
compiler.runtime=dynamic
compiler.runtime_type=Release
compiler.update=0
compiler.version=194
os=Windows
[conf]
tools.cmake.cmaketoolchain:generator=Visual Studio 17 2022

Profile build:
[settings]
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=17
compiler.runtime=dynamic
compiler.runtime_type=Release
compiler.update=0
compiler.version=194
os=Windows
[conf]
tools.cmake.cmaketoolchain:generator=Visual Studio 17 2022


======== Computing dependency graph ========
sqlite3/3.45.3: Not found in local cache, looking in remotes...
sqlite3/3.45.3: Checking remote: conancenter
sqlite3/3.45.3: Downloaded recipe revision 1b6b291b7d3730cef1f0264370964d2c
Graph root
    cli
Requirements
    sqlite3/3.45.3#1b6b291b7d3730cef1f0264370964d2c - Downloaded (conancenter)

======== Computing necessary packages ========
sqlite3/3.45.3: Forced build from source
Requirements
    sqlite3/3.45.3#1b6b291b7d3730cef1f0264370964d2c:a1ba2c5fa80c7ce590ee96bd34de63fd16172f7f - Build

======== Installing packages ========
sqlite3/3.45.3: Sources downloaded from 'conancenter'
sqlite3/3.45.3: Calling source() in D:\conan2s\sqlitcfd8cb20ebdfc\s\src
sqlite3/3.45.3: Unzipping 10.6MB, this can take a while
Unzipping 100 %

-------- Installing package sqlite3/3.45.3 (1 of 1) --------
sqlite3/3.45.3: Building from source
sqlite3/3.45.3: Package sqlite3/3.45.3:a1ba2c5fa80c7ce590ee96bd34de63fd16172f7f
sqlite3/3.45.3: Copying sources to build folder
sqlite3/3.45.3: Building your package in D:\conan2s\b\sqlit36f41fbbdecce\b
sqlite3/3.45.3: Calling generate()
sqlite3/3.45.3: Generators folder: D:\conan2s\b\sqlit36f41fbbdecce\b\build\generators
sqlite3/3.45.3: CMakeToolchain generated: conan_toolchain.cmake
sqlite3/3.45.3: CMakeToolchain generated: D:\conan2s\b\sqlit36f41fbbdecce\b\build\generators\CMakePresets.json
sqlite3/3.45.3: Generating aggregated env files
sqlite3/3.45.3: Generated aggregated env files: ['conanbuild.bat', 'conanrun.bat']
sqlite3/3.45.3: Calling build()
sqlite3/3.45.3: Running CMake.configure()
sqlite3/3.45.3: RUN: cmake -G "Visual Studio 17 2022" -DCMAKE_TOOLCHAIN_FILE="generators/conan_toolchain.cmake" -DCMAKE_INSTALL_PREFIX="D:/conan2s/b/sqlit36f41fbbdecce/p" -DCMAKE_POLICY_DEFAULT_CMP0091="NEW" "D:/conan2s/b/sqlit36f41fbbdecce/b/src/.."
-- Using Conan toolchain: D:/conan2s/b/sqlit36f41fbbdecce/b/build/generators/conan_toolchain.cmake
-- Conan toolchain: CMAKE_GENERATOR_TOOLSET=v144,version=14.40
-- Conan toolchain: Setting BUILD_SHARED_LIBS = OFF
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19044.
CMake Error at CMakeLists.txt:2 (project):
  Failed to run MSBuild command:

    C:/Program Files/Microsoft Visual Studio/2022/Professional/MSBuild/Current/Bin/amd64/MSBuild.exe

  to get the value of VCTargetsPath:

    MSBuild version 17.10.4+10fbfbf2e for .NET Framework
    Build started 5/3/2024 10:49:18 AM.

    Project "D:\conan2s\b\sqlit36f41fbbdecce\b\build\CMakeFiles\3.29.2\VCTargetsPath.vcxproj" on node 1 (default targets).
    C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Microsoft\VC\v170\Microsoft.CppBuild.targets(456,5): error MSB8020: The build tools for v144 (Platform Toolset = 'v144') cannot be found. To build using the v144 build tools, please install v144 build tools.  Alternatively, you may upgrade to the current Visual Studio tools by selecting the Project menu or right-click the solution, and then selecting "Retarget solution". [D:\conan2s\b\sqlit36f41fbbdecce\b\build\CMakeFiles\3.29.2\VCTargetsPath.vcxproj]
    Done Building Project "D:\conan2s\b\sqlit36f41fbbdecce\b\build\CMakeFiles\3.29.2\VCTargetsPath.vcxproj" (default targets) -- FAILED.

    Build FAILED.

    "D:\conan2s\b\sqlit36f41fbbdecce\b\build\CMakeFiles\3.29.2\VCTargetsPath.vcxproj" (default target) (1) ->
    (PrepareForBuild target) ->
      C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Microsoft\VC\v170\Microsoft.CppBuild.targets(456,5): error MSB8020: The build tools for v144 (Platform Toolset = 'v144') cannot be found. To build using the v144 build tools, please install v144 build tools.  Alternatively, you may upgrade to the current Visual Studio tools by selecting the Project menu or right-click the solution, and then selecting "Retarget solution". [D:\conan2s\b\sqlit36f41fbbdecce\b\build\CMakeFiles\3.29.2\VCTargetsPath.vcxproj]

        0 Warning(s)
        1 Error(s)

    Time Elapsed 00:00:00.20


  Exit code: 1



-- Configuring incomplete, errors occurred!

sqlite3/3.45.3: ERROR:
Package 'a1ba2c5fa80c7ce590ee96bd34de63fd16172f7f' build failed
sqlite3/3.45.3: WARN: Build folder D:\conan2s\b\sqlit36f41fbbdecce\b\build
ERROR: sqlite3/3.45.3: Error in build() method, line 159
        cmake.configure(build_script_folder=os.path.join(self.source_folder, os.pardir))
        ConanException: Error 1 while executing

What exactly should be used in profile?
Update compiler.version=193+update 10 also can't be used

ERROR: Invalid setting '10' is not a valid 'settings.compiler.update' value.
Possible values are ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

@jcar87
Copy link
Contributor

jcar87 commented May 3, 2024

Thanks for testing @Nekto89

Indeed the compiler with "MSVC toolset 19.40.xxx" is still part of the v143 platform toolset.

@memsharded I think it looks okay now, but I will double check the activation of vcvars, and the ability to force the 193 compiler version when the 19.4 is also available (and would otherwise be picked up by default)

There is another place that is worth looking into:

vcvars_ver = {"v140": "14.0",
"v141": "14.1",
"v142": "14.2",
"v143": "14.3"}.get(toolset_version)

The code there parses the compiler.runtime_version setting, which is only optionally when the compiler is clang on Windows - but now we can't disambiguate whether the vcvars need to be for 193 or 194. I would probably consider checking which update is installed and available, and use the most recent? Otherwise, using the 193 runtime should be compatible anyway, so it is the safest choice, but I would then leave a comment.

new_combinations.append(comb)
combinations = new_combinations

conanfile.output.info(f"COMbINATIONS {combinations}")
Copy link
Contributor

Choose a reason for hiding this comment

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

COMbINATIONS typo here, but maybe consider having both FACTORS and COMBINATIONS not being all caps? Also found it a little confusing, from a user perspective I dont know what factors or combinations are.

@jcar87
Copy link
Contributor

jcar87 commented May 3, 2024

Tested:

  • conan profile detect detects 194 when the preview is installed ✅

  • When consuming a package with compiler.version=194, and a binary exists for 193 but not for 194, it falls back to finding the compatible binary: ✅

======== Computing necessary packages ========
zlib/1.3.1: FACTORS [[{'compiler.version': '193'}]]
zlib/1.3.1: COMbINATIONS [{'compiler.version': '193'}]
zlib/1.3.1: Checking 1 compatible configurations
zlib/1.3.1: Main binary package 'bf083199c71b5d660bf9523713b0cd79bc0919fb' missing. Using compatible package 'ea5dc84deb25b32a77ec23c39a1811e3f441ee54': compiler.version=193
  • Creating a package with compiler.version=194 results in CMake picking up v143 toolset with the 19.40 compiler ❌
    What I get instead:
-- Using Conan toolchain: C:/xxx/conan-center-index/recipes/zlib/all/test_package/build/msvc-194-armv8-14-release/generators/conan_toolchain.cmake
-- Conan toolchain: CMAKE_GENERATOR_TOOLSET=v143
-- Conan toolchain: C++ Standard 14 with extensions OFF
-- The C compiler identification is MSVC 19.39.33523.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.39.33519/bin/Hostarm64/arm64/cl.exe - skipped

Here there seem to be multiple factors at play:

Only when using CMAKE_GENERATOR_INSTANCE so that CMake uses the Visual Studio 2022 Update 10 preview:

  • Without defining the compiler.update setting, CMake still detects and uses the 19.39 compiler, even if the compiler.version=194
  • Setting compiler.version=193 and compiler.update=0 AND setting then CMake detects the correct compiler (19.40)

A meson-toolchain recipe seems fine, which also instantiates vcvars:

conanvcvars.bat: Activating environment Visual Studio 17 - amd64_arm64 - winsdk_version=None - vcvars_ver=14.4
[vcvarsall.bat] Environment initialized for: 'x64_arm64'
The Meson build system
Version: 1.2.2

Build type: cross build
..\src\meson.build:1: WARNING: Keyword argument "default_options" defined multiple times.
WARNING: This will be an error in future Meson releases.
Project name: pkgconf
Project version: 2.2.0
C compiler for the host machine: cl (msvc 19.40.33808 "Microsoft (R) C/C++ Optimizing Compiler Version 19.40.33808 for ARM64")
C linker for the host machine: link link 14.40.33808.0
C compiler for the build machine: cl (msvc 19.40.33808 "Microsoft (R) C/C++ Optimizing Compiler Version 19.40.33808 for ARM64")
C linker for the build machine: link link 14.40.33808.0

@jcar87
Copy link
Contributor

jcar87 commented May 3, 2024

if my understanding is correct, there are some scenarios

A user that has side-by-side installations of VS2022 and VS2022.10 preview:

A) User runs conan profile detect
  • conan profile detect will detect compiler.version=194
  • But CMake will not even consider the preview installation, and will use the 19.3x compiler regardless (with no error) - all binaries still work, but it's not the newer compiler - this is wrong

B) User still has a profile with compiler.version=193

Everything works fine, both CMake and conan profile "agree"

C) User has a profile with compiler.version=194 and compiler.update=0

CMake will fail.

User only has Visual Studio 2022.10 preview installed OR tells cmake which installation to use via CMAKE_GENERATOR_INSTANCE

A) User runs conan profile detect
  • conan profile detect will detect compiler.version=194
  • CMake detects the preview installation, but still picks up the 19.3x compiler - this seems to be the current default set in Visual Studio altogether - everything builds and works, but it's not using the 19.4x compiler

B) User has a profile with compiler.version=194 and compiler.update=0

This works fine - Conan passes v143,version=14.40 as the generator toolset, and it uses the new compiler version.

C) User still has a profile with compiler.version=193

This is "correct" - since CMake uses the 19.3x MSVC toolset by default, however, if upon release it moves to use 19.4x instead, then this would be wrong.

As it stands, I wouldn't merge this PR - all the right things are there, but

  • conan profile detect assumes compiler.version=194 if Update 10 is installed - but unsure it is the default version
  • If the Preview is installed side by side with a released version, CMake defaults to the release
  • If preview is installed on its own or we tell CMake to use it, CMake still picks up the 19.3x toolset in the abscence of compiler.update being defined.

All the right things are there - but at the moment if the update 10 is using the 19.3x toolset as the default, nothing is wrong - I would reassess on release

@jcar87 jcar87 dismissed their stale review May 3, 2024 14:59

see comments

@Nekto89
Copy link
Contributor

Nekto89 commented May 3, 2024

* If preview is installed on its own or we tell CMake to use it, CMake _still_ picks up the 19.3x toolset in the abscence of `compiler.update` being defined.

What do you mean by this? I just checked without conan

cmake -G"Visual Studio 17 2022" -Tv143 ..
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19044.
-- The C compiler identification is MSVC 19.40.33808.0

VC\Auxiliary\Build\Microsoft.VCToolsVersion.v143.default.txt and .props contain latest 14.40.33807. Same for Microsoft.VCToolsVersion.default.txt

@jcar87
Copy link
Contributor

jcar87 commented May 3, 2024

Hi @Nekto89 thanks for following up. Could you paste the bit of the CMake configuration log where it prints the location of cl.exe?

On my machine in that directory C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Auxiliary\Build
some contain 14.40, but some point to 14.39, and CMake uses 14.39 (and I've not touched any of these files)

@Nekto89
Copy link
Contributor

Nekto89 commented May 3, 2024

Hi @Nekto89 thanks for following up. Could you paste the bit of the CMake configuration log where it prints the location of cl.exe?

On my machine in that directory C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Auxiliary\Build some contain 14.40, but some point to 14.39, and CMake uses 14.39 (and I've not touched any of these files)

cmake -G"Visual Studio 17 2022" ..
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19044.
-- The C compiler identification is MSVC 19.40.33808.0
-- The CXX compiler identification is MSVC 19.40.33808.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (8.2s)
-- Generating done (0.0s)
cmake -G"Visual Studio 17 2022" -Tv143 ..
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19044.
-- The C compiler identification is MSVC 19.40.33808.0
-- The CXX compiler identification is MSVC 19.40.33808.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (8.1s)
-- Generating done (0.1s)
cmake -G"Visual Studio 17 2022" -Tv143,version=14.40 ..
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19044.
-- The C compiler identification is MSVC 19.40.33808.0
-- The CXX compiler identification is MSVC 19.40.33808.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (7.9s)
-- Generating done (0.0s)
cmake -G"Visual Studio 17 2022" -Tv143,version=14.40.17.10 ..
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19044.
-- The C compiler identification is MSVC 19.40.33808.0
-- The CXX compiler identification is MSVC 19.40.33808.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (7.7s)
-- Generating done (0.0s)

I don't have 14.39 on my machine. It was automatically updated to 14.40. I've also explicitly added 14.40 in VS Installer.
image

@memsharded
Copy link
Member Author

Some more info:

@memsharded memsharded modified the milestones: 2.3.0, 2.4.0 May 6, 2024
@jcar87
Copy link
Contributor

jcar87 commented May 6, 2024

Thanks @Nekto89! I've been doing more troubleshooting using the Windows Sandbox

  • Visual Studio Installer for 17.9.6 : -> 14.40 does not show as an option (as expected)
  • Visual Studio Installer for 17.10.0 preview 6.0 -> leaving the default to "latest" will install the 14.40 MSVC toolset and that will be correctly picked up by both CMake and MSBuild - note that from what I can see CMake picks this up only if the "preview" is the only version of Visual Studio installed (having 17.9 AND the preview, 17.9 seems to take priority)
  • Visual Studio Installer for 17.10.0 preview 6.0 -> but selecting the 14.39 toolset as well as the the 14.40 one - that's where I was having issues. This actually seems to be a bug: https://developercommunity.visualstudio.com/t/MicrosoftVCToolsVersionv143defaulttx/10041951#T-N10601904 - where the .default.txt file gets overwritten by all v143 variants, so only one stands (presumably the one that was last installed?). This would also explain the inconsistency I was seeing (some files were pointing to 14.40, some to 14.39), and this is why both CMake and MSBuild were using 19.39 as the default instead of 14.40 which was available (and was more recent)

@memsharded - I think this was just a fluke with my installation and a manifestation of that visual studio installer bug - I think we can assume that both a clean install of the new version, or an upgrade, will be correctly configured to use 14.40 as the "msvc toolset" version. This is really only an issue of users rely on conan profile detect (because we don't necessarily derive the default version in the same way that CMake does), or if a user explicitly sets the profile to compiler.version=194

As for the v144: it doesn't exist as a platform toolset and so far never has. This PR https://gitlab.kitware.com/cmake/cmake/-/commit/d2df2e94e50a003fc635a1913f70ccc784696f15 from CMake is a bit confusing at first, but it makes sense, what they were doing was a mapping where if a user passed version=14.39.xx to CMAKE_GENERATOR_TOOLSET, without specifying the platform toolset, CMake would then deduce the "platform toolsetversion from the first 3 digits tov143- that logic would have a "bug" if a user provided14.40.xxbecause it would've then chosenv144which doesn't exist, and it needs to be mapped tov143(essentially, similar logic to what we have in our PR, it just looks confusing to seev144` in text). The xmake changes are confusing in what they call a "toolset version", so it's probably a misnomer, but then again the naming conventions are confusing on their own

@memsharded memsharded merged commit 3232cf6 into conan-io:release/2.3 May 13, 2024
2 checks passed
@memsharded memsharded deleted the fix/msvc_toolset_version_overflow branch May 13, 2024 11:53
@risa2000
Copy link

I have just updated to VS 17.10 (official release) and got hit by this bug in conan 1.64.1.
Side question: Will it be fixed in this version?

Following the discussion here I would like to add few comments regardless:

In the release version there is no reference to v14.40 "tools version" in C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build directoy. Apparently "tools" in this directory refer to "Platform toolset".
However the failing conan build is fixed when I manually substitute the following command in conanvcvars.bat (CMake)

@echo off
set "VSCMD_START_DIR=%CD%" && call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC/Auxiliary/Build/vcvarsall.bat"  amd64 -vcvars_ver=14.3

with -vcvars_ver=14.4.

Which apparently identifies MSVC Toolset version and apparently is an abbreviation from v14.40 (as per the comment here https://devblogs.microsoft.com/cppblog/msvc-toolset-minor-version-number-14-40-in-vs-2022-v17-10/) which is extremely confusing as the version should be then 14.40 (as 4 != 40)!

Now even more confusing (and where conan enters the picture) is that I am using msvc flavor to identify the toolchain in conan.profile, which does not operate with toolset versions (platform or msvc) but compiler version, i.e.

[settings]
os=Windows
os_build=Windows
arch=x86_64
arch_build=x86_64
compiler=msvc
compiler.version=193
compiler.cppstd=20
compiler.runtime=dynamic

but it seems that compiler.version should be derived from the actual cl version, which, in VS 17.10 is

Microsoft (R) C/C++ Optimizing Compiler Version 19.40.33808 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

and technically should be identified as 194.

Now the problem is that despite the fact that this is apparently a minor compiler update from v19.39 to v19.40 it breaks all conan derived dependencies because for some reason conan believes that crossing the tens (39->40) somehow designates a major compiler change which needs to be compartmentalized into a separate package configuration.
From the MS explanation cited above however it looks like there is no such relation.

In fact I do not see any reason why the current toolset (v14.40) in platform toolchain (v143) should not be able to equally process the code emitted by both v194 and v193 compilers.

The distinctions conan chooses for maintaining the package binary compatibility seems to be wrong.

@memsharded
Copy link
Member Author

Side question: Will it be fixed in this version?

It is likely that it might not be possible. The changes are not that trivial, and it might be too complex or even breaking. Conan 2 was released in February 2023, after 2.5 years in alpha and beta releases, Conan 1 is no longer getting significant new features and updates, specifically if they have risk.

I'd say that what you are reporting in the rest of your comment is all related to Conan 1 behavior? Is this the case? If not it would be good to clarify it, and open a new ticket against latest Conan 2.3.1.

@risa2000
Copy link

@memsharded
Actually, I made the remaining comments under impression that they equally apply to conan 2.x.
Does the way conan uses profile settings to distinguish incompatible packages changed in 2.x compared to 1.x?
Does conan uses the same attributes (e.g. compiler.version) to make that distinction?
I cannot confirm that, since I am using 1.64.1., so maybe someone familiar with 2.x can.

@memsharded memsharded modified the milestones: 2.4.0, 2.3.1 May 22, 2024
@memsharded
Copy link
Member Author

Does the way conan uses profile settings to distinguish incompatible packages changed in 2.x compared to 1.x?
Does conan uses the same attributes (e.g. compiler.version) to make that distinction?

Conan 2 added specific treatment of the compiler.version=194, you can check the diff in: https://github.com/conan-io/conan/pull/15588/files, and you can see it is not a trivial change.

That change implements the correct mappings for 194 <-> v143 toolset, the mapping from VS IDE 17 <-> 193, 194 compiler versions, and it also includes a binary compatibility rule to fall back from 194->193 so users don't need to create new binaries when updating to VS 17.10

@risa2000
Copy link

I guess my point was that the attributes conan uses (to determine the binary compatibility) no longer correspond to the factual state and the approach should be revised.

I have been dealing with binary packages built as far as with VS 2015 and usually face binaries from VS 2019 while having the major part from up-to-date VS 2022. According to the conan logic a new VS is automatically a breaking change and packages built for example with compiler.version=192 (VS 2019) are not compatible with compiler.version=193 (VS 2022). The resolution for me so far has been simply overriding the conan searching by specifying explicitly the older version in conan.profile. So far it always worked.

This has been just an anecdotal experience which however corresponds to what Microsoft say on the topic https://learn.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=msvc-170
Another nice summary is here https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B
Basically from VS 2015 the binaries are compatible (if you follow some rules)

In a wiki table you may also notice that the compiler version is actually made out of four digits and corresponds to major+minor version number (of the cl.exe binary). So it is not compiler versions 192 or 193, but twenty different (minor) versions ranging from 1920 to 1939 (now 1940). Yet all those versions are binary compatible (and even more than few older ones).

That conan declares that versions 192 and 193 are not binary compatible, or that the binary compatibility breaks exactly when the minor version reaches full tens has no longer support in what Microsoft says. It may have worked in the past this way (possibly before VS 2015), but even then it seems to have been rather incidental.

From the info cited above one way to define binary compatibility would be either use Microsoft own definiton and declare the ranges of compiler versions and map those ranges to an "abstract" compatibility version, or go with an observation that the braking changes are typically happening when compiler major version changes (so anything from 1900 to 1999 is compatible).

I was only using compiler version in the above argument as it seems to be the most suitable candidate for the task. There seem to be somewhat one-to-one mapping to MSVC toolset version (although there is a gap in major versions between VS 2013 and VS 2015, while compiler version is consistent).

But if conan used MSVC toolset version (the one with four digits - not the Platform toolchain version - the one with three digits) basically the same argument as above would apply.

I understand that 10 years ago the idea might have looked sound and might have even be the only one that worked, but this has diverged over the years to the point where it no longer reflects the reality, nor helps the user. The fact that you had to write "a non trivial" patch to fix may also suggest that the original scheme no longer serves its purpose.

@memsharded
Copy link
Member Author

I understand that 10 years ago the idea might have looked sound and might have even be the only one that worked, but this has diverged over the years to the point where it no longer reflects the reality, nor helps the user. The fact that you had to write "a non trivial" patch to fix may also suggest that the original scheme no longer serves its purpose.

This was not 10 years ago, but a discussion in the tribe for 2.0, pushed by Conan users, that wanted to use the compiler version and not the IDE version as Conan 1.X did in the past.

Regarding the default binary compatibility, in theory the binaries are compatible, but in practice we have learned from thousands of users and from the experience of ConanCenter that this doesn't hold in practice that well. Many libraries and C++ code will have pre-processor definitions based on the compiler version that affects their functionality, ABI and even APIs. We know that in practice developers have added these conditional preprocessor definitions mostly based on the compiler version tied to their IDE version, and jumping when jumping to a new IDE version, that means 190 for VS 2015, 191 for VS2017, 192 for VS2019 and 193 for VS2022.

This has proved quite solid binary compatibility default in practice for a few years at large scale, and the recent change in MSVC versioning does not justify changing this default yet.

And in any case, this is just a default, we understand that some users might want to use other behavior, so It is easy with Conan, and specifically with the new compatibility.py plugin in Conan 2 to define custom binary compatibility rule. Adding a fallback compatibility for any previous compiler.version would be just a few lines in that plugin.

Microsoft changed their compiler versioning approach, and a solid proof is that for the first time it uses a toolset v143 that does not correlate to the compiler version anymore. Not only Conan, but the rest of the ecosystem (CMake, Meson) have had to patch their code in their very latest versions to also deal with this change.

@risa2000
Copy link

@memsharded

This was not 10 years ago, but a discussion in the tribe for 2.0, pushed by Conan users, that wanted to use the compiler version and not the IDE version as Conan 1.X did in the past.

Do not take me wrong. I am not saying (I hope) that using compiler versions was a bad idea, quite contrary. I am saying that the logic built on top of that no longer works.

By artificially narrowing the spread (of differences) by tenths of minor version number you can also reduce the chances for potential conflicts by simple statistics. But there you are trying solving a problem which is not yours. Because if my code does not link (or build) with a third party package, because the third party package uses (or defines) some incompatible macros, this is a problem with the third party code (or mine), not with the toolchain or its binary compatibility.

I can use (or rather misuse) some built-in macros in a way that even the same toolchain will produce inconsistent code when linking two modules where each used different compiler options. And these modules will be perfectly binary compatible according to conan rules. But this does not mean that the toolchain is bad. It just means that there is always a way how to break things if someone does not care (or does not know what he is doing).

@memsharded
Copy link
Member Author

I understand your point, but unfortunately this is for an ideal world and not how it works in real life. When creating binaries for ConanCenter +1500 packages, we cannot check each project, go to those open source projects and tell them: "hey, you are doing it wrong, you need to change the way you use these macros". So building maybe a few more binaries that would be strictly necessary for some libraries is a much better default that the opposite, because the opposite will result in ConanCenter users having very obscure errors at link time or even worse, at runtime that will be very complicated to debug. Building one binary per 191, 192, 193 compiler version is easy and not that expensive, but the damage caused to users that hit binary compatibility problems is simply much worse. Furthermore, even in the case there could be some binary compatibility accross compiler versions, it is also a possibility that binaries built with more modern compilers have performance optimization or even fixes, so building new binaries when a new compiler 193 comes out even if the binary for 192 was already existing still has benefits for users.

There is simply no perfect rule for binary compatibility, and this is the reason Conan allows users to define their own, but our experience is that being overly optimistic has a net bad effect on users, so we prefer a possibly less optimistic scenario (a binary per 191, 192, 193 compiler version) than the opposite as default. As always in computer science, this is just a trade-off, but we are happy so far with this decision.

@risa2000
Copy link

@memsharded
Fair enough. It is your code and your call.

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