Skip to content

[vcpkg|manifest|MSBuild] vcpkg should follow the toolset version set in the project properties instead of always using the latest toolset version when using vcpkg in a VS project via manifeast #23308

Closed

Description

The selected Platform Toolset in the MSBuild Project file is ignored. Also the vcvars.bat toolset is ignored.
"vcpkg install" will build with the latest toolset installed, even if a different toolset is selected.

Environment

  • OS: Windows 10
  • Compiler: Visual Studio 2017, 2019, 2022

To Reproduce
Steps to reproduce the behavior:

  1. Install Visual Studio 2022 with v141 Toolset
    or Install Visual Studio 2017 and Visual Studio 2022 on the same machine
  2. vcpkg install integrate
  3. Create project with vcpkg.json and use manifests
  4. Select "v141" als "Platform Toolset" for the project

"vcpkg install" as run by the vcpkg.target.props MSBuild integration will build the libraries with VS2022/v143, even though v141 as a toolset is installed.

While the binaries are still ABI compatible, iow - can be used with the v141 toolset/project, this is still wrong behaviour. Here is why:

The boost libraries create boost-vc140*.lib import libraries, regardless of the toolset. So linking works. But the DLLs contain the toolset name. So the DLLs build will be boost_chrono-vc143-mt-x64-1_78.dll, even though the project has v141 as the platform.

In a team where different people have different Visual Studio versions installed - and especially on a build server with different Visual Studio versions - this will cause great problems with installers etc... Essentially the build is no longer reproducable, as you have no control over the toolset used for the libraries.

Expected behavior
vcpkg install should set the VCPKG_PLATFORM_TOOLSET to the value in the MSBuild project file.
Or, if run from a "Visual Studio 20xx commandline" or with vcvars.bat run, vcpkg should read and honor the environment variables set.

When I run VS2017 vcvars.bat, I specifically request the Visual Studio 2017 toolset and do not want vcpkg to choose another one.

Only if no PlatformToolset is specified or no vcvars and Environment Variables are available, only then is vcpkg allowed to choose.

Activity

  1. LilyWangLL commented on Feb 28, 2022

    @LilyWangLL
    Contributor

    Thanks for posting this issue. Did you add the following code in your VCPKG_PATH/triplets/install_triplet.cmake?

    set(VCPKG_PLATFORM_TOOLSET v141)
    
  2. hajokirchhoff commented on Feb 28, 2022

    @hajokirchhoff
    Author

    Did you add the following code in your VCPKG_PATH/triplets/install_triplet.cmake?
    No. What's the reason for your question?

  3. LilyWangLL commented on Mar 1, 2022

    @LilyWangLL
    Contributor

    Add this code can use specified version of Visual Studio.

  4. hajokirchhoff commented on Mar 1, 2022

    @hajokirchhoff
    Author

    Ah, you mean a community triplet? Yes, we are using a custom triplet 'x64-windows-v141', but I still think, vcpkg should honor the Toolset in the project, because now we have to have a custom triplet and duplicate the toolset in the triplet and the project file.

  5. changed the title [-][vcpkg|manifest|MSBuild] vcpkg integrate install and vcpkg install fails to honor platform toolset[/-] [+][vcpkg|manifest|MSBuild] vcpkg should follow the toolset version set in the project properties instead of always using the latest toolset version when using vcpkg in a VS project via manifeast[/+] on Mar 2, 2022
  6. added
    category:vcpkg-featureThe issue is a new capability of the tool that doesn’t already exist and we haven’t committed
    and removed on Mar 2, 2022
  7. Cheney-W commented on Mar 2, 2022

    @Cheney-W
    Contributor

    Vcpkg currently does not have the kind of functionality you expect, the only way to control the toolset version is to set the value of the VCPKG_PLATFORM_TOOLSET variable in the triplet file.

  8. hajokirchhoff commented on Mar 2, 2022

    @hajokirchhoff
    Author

    Is this planned? (Can I help?)
    Currently, after I call vcvars (Visual Studio 20xx command line), I can expect all subsequent tools to use the toolset I selected. Except vcpkg.

  9. Cheney-W commented on Mar 2, 2022

    @Cheney-W
    Contributor

    We welcome you to submit a PR to implement this feature.

  10. hajokirchhoff commented on Mar 2, 2022

    @hajokirchhoff
    Author

    I've seen the part in the vcpkg-tool, where "vswhere" get's called. This would be the place where I could bypass vswhere and use the environment variables directly, if they have been set. Something like

    if defined(VCINSTALLDIR)
       set vc_instance_to_use = VCINSTALLDIR
    else
       run vswhere to find the visual studio instance
    

    VCINSTALLDIR gets set when you open the "Visual Studio 2017(whatever) command line".

    Would that be acceptable?

  11. Cheney-W commented on Mar 3, 2022

    @Cheney-W
    Contributor
  12. BillyONeal commented on Mar 5, 2022

    @BillyONeal
    Member

    VCINSTALLDIR gets set when you open the "Visual Studio 2017(whatever) command line".

    Not paying attention to the calling environment is intended behavior since the same command line giving the same results is a design goal. Implementing this feature request would require somehow generating a triplet and/or toolchain on the fly pointing to the compilers selected by Visual Studio.

  13. hajokirchhoff commented on Mar 5, 2022

    @hajokirchhoff
    Author

    I know that it's a design goal, but I think that the design goal breaks with other scripts/buildsystems, such as MSBuild.

    "Generating a triplet" would probably mean simply setting VCPKG_PLATFOR_TOOLSET here, which is what do in a custom triplet for the compiler. My point is that this variable should inherit the value from the variable in the MSBuild file. Or it should inherit the value, if vcvars.bat has explicitly called before starting vcpkg.

    If the platform toolset has been selected before starting vcpkg, vcpkg should not choose a different one on its own.

    Think of it: You have 'n' PCs in use by 'n' developers. You have no control over what compilers the have installed in addition to the one you have agreed on. You are selecting the Toolset in the *.vcproj files, so everyone uses the same compilers.

    Except for the vcpkg consumed libraries. With them it's near random and depends on whatever compiler this particular developer has installed on his/her machine.

    Now you have to manually create a custom triplet just to make sure, vcpkg is using the same compiler as your project. And you have to distribute the custom triplet or use a triplet_overlay_path etc....

    All just because VCPKG_PLATFORM_TOOLSET does not inherit the same value as .

  14. hajokirchhoff commented on Mar 5, 2022

    @hajokirchhoff
    Author

    since the same command line giving the same results is a design goal
    But it is not giving the same results on different PCs in a team. And that's a problem imho.

  15. BillyONeal commented on Mar 8, 2022

    @BillyONeal
    Member

    "Generating a triplet" would probably mean simply setting VCPKG_PLATFOR_TOOLSET here, which is what do in a custom triplet for the compiler.

    That's insufficient; all the relevant compiler paths need to be passed in.

    Or it should inherit the value, if vcvars.bat has explicitly called before starting vcpkg.

    No, it should not.

    If the platform toolset has been selected before starting vcpkg, vcpkg should not choose a different one on its own.

    Like I said, getting MSBuild to feed in the values it knows about would be good, but this is not a small feature and needs to deal with the triplet names somehow.

    Think of it: You have 'n' PCs in use by 'n' developers. You have no control over what compilers the have installed in addition to the one you have agreed on. You are selecting the Toolset in the *.vcproj files, so everyone uses the same compilers.
    Except for the vcpkg consumed libraries. With them it's near random and depends on whatever compiler this particular developer has installed on his/her machine.

    You are mistaken about this; the status quo for vcxproj is that you get the random compiler the developer installed on their machine. The platform toolset version does not uniquely identify a compiler.

    All just because VCPKG_PLATFORM_TOOLSET does not inherit the same value as .

    I'm saying that is necessary, but not sufficient, to deliver the feature you want here.

  16. hajokirchhoff commented on Mar 8, 2022

    @hajokirchhoff
    Author

    "Generating a triplet" would probably mean simply setting VCPKG_PLATFOR_TOOLSET here, which is what do in a custom triplet for the compiler.

    That's insufficient; all the relevant compiler paths need to be passed in.
    Are you sure? Note: I am not trying to specify a specific compiler instance, I am trying to set a specific toolset version.

    The difference between the triplet x64-windows and a custom x64-windows-v141 is exactly one line:
    set(VCPKG_PLATFORM_TOOLSET "v141")

    in the triplet.cmake. So one idea would simply be to copy the PlatformToolset value to the VCPKG variable.

  17. hajokirchhoff commented on Mar 8, 2022

    @hajokirchhoff
    Author

    You are mistaken about this; the status quo for vcxproj is that you get the random compiler the developer installed on their machine. The platform toolset version does not uniquely identify a compiler.

    No, I don't think so. It's not a random at all. The PlatformToolset may not exactly give the path to "cl.exe", but if I want to compile with v141, it compiles with v141 and not v143.

    Scenario:

    • VS2017 installed (contains v141)
    • VS2022 installed (contains v143), but also the v141 components (contains a second v141).

    So there are two different "v141" compilers on my machine and another "v143".

    All I care for is that if my PlatformToolset says "v141", I want a "v141" cl.exe to compile my sources. It doesn't matter, if its the one from VS2017 or VS2022. That's the point of the "PlatformToolset". Letting me choose v141, even if I use the 2022 IDE (which by default uses v143).

    But it must be a v141.

    What vcpkg currently does is choose the latest compiler. So it will choose v143 on a machine, where v143 is installed (among others), and v141 on other machines. I have no control over it, even if my project file explicitly states v141. That is a problem.

  18. hajokirchhoff commented on Mar 8, 2022

    @hajokirchhoff
    Author

    Or it should inherit the value, if vcvars.bat has explicitly called before starting vcpkg.

    No, it should not.

    I beg to differ. There are actually two different situations regarding to vcpkg.

    Where vcpkg initially came from, it'd make a lot of sense to prevent inheritance of environment variables. vcpkg was called exactly once and installed the required libraries. The toolchains to use the libraries came after this.

    But with manifests the situation changed. Now vcpkg is part of a toolchain. vcpkg is no longer run before everything else and is no longer acting alone. Instead with MSBuild it is called by MSBuild and should respect the settings.

    And I think that, when used with manifests, when I (a script) specifically call vcvars.bat before calling vcpkg, I want vcpkg to be part of my toolchain. Otherwise I'd call vcpkg install and be done with it. But I don't. I do not want the global vcpkg_installed folder, I want a very specific one, which is why I am using a manifest.

    Bottom line: With manifests, vcpkg should honor the selected Toolset, since it became part of a toolchain.

    Think of it: Imagine with CMake you were setting up the environment, selecting tools etc... And one of the tools called by CMake then just completely ignores anything you specified before. This tool integrates poorly with CMake.

    Again: The difference is, if vcpkg is seen as a stand-alone, run-once operation or if is part of a complex build mechanism.

    So, if vcvars has been called, all the necessary paths and environment variables have been set. Why not (in manifest mode at least) let vcpkg use it, instead of calling another (different) vcvars.

  19. BillyONeal commented on Mar 9, 2022

    @BillyONeal
    Member

    For manifests' integration with build tools, yes, we should have some mechanism to get those to agree. However, just being in a vcvars prompt is not an integration with build tools and the behavior there is very much intentional.

  20. hajokirchhoff commented on Mar 17, 2022

    @hajokirchhoff
    Author

    I'm interested in the reasoning behind why being in a vcvars prompt is not integration with build tools. Do you have some url for me where I can read up?

    Also, what is the plan for integrating in manifest mode? I'd like to help.

  21. BillyONeal commented on Mar 19, 2022

    @BillyONeal
    Member

    I'm interested in the reasoning behind why being in a vcvars prompt is not integration with build tools. Do you have some url for me where I can read up?

    vcvars is not a build tool. I don't have documentation to prove a negative. If your run msbuild in there, for example, it also completely ignores what vcvars says and does what the vcxproj says instead.

    Also, what is the plan for integrating in manifest mode? I'd like to help.

    I don't think we have a design for that right now. Presumably we would need to generate a 'pseudo triplet file' or similar with settings extracted from the consuming build system but it is unclear if the information is available at such time to make most of the catalog functional right now.

  22. camptatopenmars commented on Jun 8, 2022

    @camptatopenmars

    I just spent a day pulling my hair out on a linker issue only to discover that vcpkg has been using the v143 toolchain... when I'm building with v142. There has recently been a breaking ABI change in v143 apparently. I'm using manifests, I love vcpkg but also share the view that it is a reasonable expectation that if my msbuild project is using v142 that vcpkg would as well. I could change the various triplet files to specify v142 in vcpkg/triplets... but now I've forked the vcpkg repository and I'd prefer to not need to do that.

  23. locked and limited conversation to collaborators on Jul 21, 2022
  24. converted this issue into a discussion #25905 on Jul 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

category:vcpkg-featureThe issue is a new capability of the tool that doesn’t already exist and we haven’t committed

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions