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

vcpkg.cmake toolchain file not using triplet environment variables #23607

Open
HunterZ opened this issue Mar 17, 2022 · 23 comments
Open

vcpkg.cmake toolchain file not using triplet environment variables #23607

HunterZ opened this issue Mar 17, 2022 · 23 comments
Labels
category:community-triplet A PR or issue related to community triplets not officially validated by the vcpkg team.

Comments

@HunterZ
Copy link

HunterZ commented Mar 17, 2022

Describe the bug
Documentation for using vcpkg with MinGW at https://github.com/microsoft/vcpkg/blob/master/docs/users/mingw.md says to define the following environment variables to point it to the correct triplet for the compiler:

export VCPKG_DEFAULT_TRIPLET=x64-mingw-dynamic
export VCPKG_DEFAULT_HOST_TRIPLET=x64-mingw-dynamic

Having done this, the vcpkg/scripts/buildsystems/vcpkg.cmake toolchain file still internally determines a triplet of x64-windows which it stores in my CMakeCache.txt like so:

//Vcpkg target triplet (ex. x86-windows)
VCPKG_TARGET_TRIPLET:STRING=x64-windows

The toolchain file should honor the environment variable setting! Having to set and environment variable and muck around with overriding CMake variables is terrible. This should also be mentioned in the article at https://github.com/microsoft/vcpkg/blob/master/docs/users/mingw.md because as written, those instructions don't get you to a working environment.

Environment

  • OS: Windows 11
  • Compiler: MinGW64 GCC (Rev10, Built by MSYS2 project) 11.2.0

To Reproduce
Steps to reproduce the behavior:

  1. install MSYS2+MinGW64 environment
  2. clone+install vcpkg into MSYS2 /opt/vcpkg, per instructions at https://github.com/microsoft/vcpkg/blob/master/docs/users/mingw.md
  3. set environment variables as mentioned above
  4. edit vscode cmake-tools config to use vcpkg toolchain file
  5. install libtcod package via vcpkg
  6. create CMake project with libtcod dependency, per libtcod package instructions

Expected behavior
CMake configure succeeds in finding and configuring libtcod import target.

Failure logs
log.txt

Additional context
I was able to prove that VCPKG_TARGET_TRIPLET:STRING=x64-windows is the problem by manually changing the cache file setting to VCPKG_TARGET_TRIPLET:STRING=x64-mingw-dynamic.

@JackBoosY JackBoosY self-assigned this Mar 17, 2022
@JackBoosY JackBoosY added the category:community-triplet A PR or issue related to community triplets not officially validated by the vcpkg team. label Mar 17, 2022
@JackBoosY
Copy link
Contributor

JackBoosY commented Mar 17, 2022

cc @dg0yt

@JackBoosY
Copy link
Contributor

[cmake] CMake Error at C:/msys64/opt/vcpkg/scripts/buildsystems/vcpkg.cmake:805 (_find_package):
[cmake]   Could not find a package configuration file provided by "libtcod" with any
[cmake]   of the following names:
[cmake] 
[cmake]     libtcodConfig.cmake
[cmake]     libtcod-config.cmake

@JackBoosY
Copy link
Contributor

Can't repro in x86-windows triplet.

@dg0yt
Copy link
Contributor

dg0yt commented Mar 17, 2022

Failure logs
log.txt

... shows no indication of x64-windows.

4. edit vscode cmake-tools config to use vcpkg toolchain file

Ensure that vscode uses the same values of the environment variables. The export ... instructions affect the shell session only, and everything which is started within that session.

In the end, I think this is a VS Code context problem. vcpkg.cmake does use the environment variables as expected, but it does not see the variable value you expect it to see.

Maybe it is easier if you skip 5. and start with manifest mode. This will ensure the right dependencies for your project's triplet.

@HunterZ
Copy link
Author

HunterZ commented Mar 18, 2022

Can't repro in x86-windows triplet.

That completely misses the point of the issue report, which is that the vcpkg.cmake toolchain file does not pick x64-mingw-dynamic as the triplet when invoked in a MinGW64 MSYS environment that has been configured per vcpkg instructions.

Failure logs
log.txt

... shows no indication of x64-windows.

It's not my fault that vcpkg.cmake doesn't log the triplet determination anywhere. As mentioned in the "additional context" section in my issue report, however, I confirmed via inspection and modification of CMakeCache.txt that the problem is the incorrect triplet determination by vcpkg.cmake.

  1. edit vscode cmake-tools config to use vcpkg toolchain file

Ensure that vscode uses the same values of the environment variables. The export ... instructions affect the shell session only, and everything which is started within that session.

In the end, I think this is a VS Code context problem. vcpkg.cmake does use the environment variables as expected, but it does not see the variable value you expect it to see.

Maybe it is easier if you skip 5. and start with manifest mode. This will ensure the right dependencies for your project's triplet.

It's not vscode, it's vcpkg.cmake. Here, look, I've reproduced it purely on the command line:
log2.txt

This log file is conclusive proof that vcpkg.cmake is not using the environment variables to inform triplet determination, and is therefore failing in a MinGW64 MSYS2 environment configured per https://github.com/microsoft/vcpkg/blob/master/docs/users/mingw.md

@HunterZ
Copy link
Author

HunterZ commented Mar 18, 2022

Update - I've dug into your vcpkg.cmake script via both inspection and cmake --trace commands, and it looks like there are actually two problems here:

  1. vcpkg.cmake doesn't reference environment variables VCPKG_DEFAULT_HOST_TRIPLET or VCPKG_DEFAULT_TRIPLET at all.
  2. The triplet determination logic performs an if(MINGW) check in an apparent attempt to detect a MinGW environment, but this fails due to the fact that a toolchain file runs long before CMake is able to invoke C:/msys64/mingw64/share/cmake-3.22.3/Modules/Platform/Windows-GNU.cmake in order to set that variable. This method of detecting MinGW is therefore fatally flawed.

It would probably be better to replace the if(MINGW) check with an MSYSTEM environment variable check, e.g. if("$ENV{MSYSTEM}" MATCHES "MINGW").

@dg0yt
Copy link
Contributor

dg0yt commented Mar 18, 2022

Let's take a step back and look at the documentation:

@HunterZ
Copy link
Author

HunterZ commented Mar 18, 2022

Let's take a step back and look at the documentation:

This is why I ultimately suggested the elseif("$ENV{MSYSTEM}" MATCHES "MINGW") (or similar) fix for vcpkg.cmake, which doesn't depend on those environment variables. I have tested this change in my own vcpkg install, and it successfully deduces the MinGW triplet. The currently implemented elseif(MINGW) check is bogus and not doing anyone any good.

I think it is important to understand that the initial triplet needs to be made permanent (by a CMake cache variable) to avoid messing up the build by accident, after changing the environment variable for another build, or after forgetting to set it after login.

Hold on, I'm pretty sure that's not how CMake cache variables work. Cache variables do not change after the cache is populated during configure, even when you re-run the configure step. The only ways they can change after cache creation are:

  • Use of FORCE in a script (which nobody is suggesting here)
  • Manually editing them in the cache file (not relevant)
  • Blowing away the entire cache and regenerating from scratch, in which case you absolutely do want it to be affected by the current environment - and then it will stick because of the way cache variables work

@dg0yt
Copy link
Contributor

dg0yt commented Mar 18, 2022

I think it is important to understand that the initial triplet needs to be made permanent (by a CMake cache variable) to avoid messing up the build by accident, after changing the environment variable for another build, or after forgetting to set it after login.

Hold on, I'm pretty sure that's not how CMake cache variables work. Cache variables do not change after the cache is populated during configure, even when you re-run the configure step. The only ways they can change after cache creation are:

* Use of `FORCE` in a script (which nobody is suggesting here)

* Manually editing them in the cache file (not relevant)

* Blowing away the entire cache and regenerating from scratch, in which case you absolutely _do_ want it to be affected by the current environment - and then it will stick because of the way cache variables work

That's why I'm saying. A cache variable is suited to make the triplet choice permanent enough.

@HunterZ
Copy link
Author

HunterZ commented Mar 18, 2022

That's why I'm saying. A cache variable is suited to make the triplet choice permanent enough.

I'm confused then how anything I've suggested contradicts that. vcpkg.cmake's triplet determination logic stores the result in a VCPKG_TARGET_TRIPLET cache variable when the cache is first generated, and then it doesn't change. Therefore it will always reflect the environment in which the CMake project was configured. Therefore making the determination based on environment variables when the project is configured is good.

Anyway, what about my elseif("$ENV{MSYSTEM}" MATCHES "MINGW") (or similar) suggested fix for vcpkg.cmake, which doesn't depend on those environment variables? I have tested this change in my own vcpkg install, and it successfully deduces the MinGW triplet. The currently implemented elseif(MINGW) check is bogus and not doing anyone any good.

@dg0yt
Copy link
Contributor

dg0yt commented Mar 20, 2022

Anyway, what about my elseif("$ENV{MSYSTEM}" MATCHES "MINGW") (or similar) suggested fix for vcpkg.cmake, which doesn't depend on those environment variables? I have tested this change in my own vcpkg install, and it successfully deduces the MinGW triplet. The currently implemented elseif(MINGW) check is bogus and not doing anyone any good.

It should be considered but would need to deal with the actual value.

IMO there are three options when VCPKG_TARGET_TRIPLET is not set.

  • No mingw triplet autodetection, i.e. remove MINGW check.
  • Use ENV{MSYSTEM}. Works for MSYS2 environments.
  • Use ENV{VCPKG_DEFAULT_TRIPLET}. Works for all environments.

Background:

  • CMake expects the toolchain file (here: vcpkg.cmake + chainloaded toolchain file) to initialize everything which is need to determine a target configuration.
    VCPKG_TARGET_TRIPLET is the official interface for guiding the vcpkg toolchain to determine the target configuration, and it works as expected.
  • MINGW is an information about the target compilers.
    At the location of elseif(MINGW), MINGW can't be expected to be defined at all. This makes it pointless at this spot.
    (Q: Would the MinGW Makefile generator set this variable? But I wouldn't use it with MSYS2 anyways.)
  • The presence of ENV{MSYSTEM} is an information about a particular host environment (MSYS2).
    From this environment, it is possible to target other platforms (Android, Linux, even MSVC), but this is probably sufficiently handled by explicit setting of VCPKG_TARGET_TRIPLET.
  • ENV{MSYSTEM} also carries information about the active MSYS2 subsystem. Two subsystems are supported by vcpkg community triplets, the others aren't. You probably want to choose the target CPU which matches MSYSTEM, don't you?
  • Building with mingw on non-Windows systems doesn't provided any auto-dection of the target triplet. One might say that it is sufficiently covered by explicit setting of VCPKG_TARGET_TRIPLET. Only when already providing a mingw toolchain file, it somewhat feels like an extra burden.

@HunterZ
Copy link
Author

HunterZ commented Mar 20, 2022

It should probably be noted that the three options listed don't have to be mutually exclusive, as it would be possible to implement cascading logic that checks two or even all three of these conditions in some order of preference.

@dg0yt
Copy link
Contributor

dg0yt commented Mar 20, 2022

It should probably be noted that the three options listed don't have to be mutually exclusive, as it would be possible to implement cascading logic that checks two or even all three of these conditions in some order of preference.

The initial wording was "alternatives", but I changed that to "options" before posting ;-)
IMHO it is better to keep the main toolchain file simple.

@aminya
Copy link
Contributor

aminya commented May 18, 2022

I am adding Mingw detection to project_options. My code invokes an external CMake process. Then in the current CMake process, I parse the CMakeCache.txt file to detect the compiler and its architecture.

However, I noticed that vcpkg doesn't respect VCPKG_DEFAULT_TRIPLET and VCPKG_DEFAULT_HOST_TRIPLET. It seems to be using MinGW variable and defaults to dynamic toolchain.
aminya/project_options#126

How can I change this to use the static toolchain (if the license allows)?

@dg0yt
Copy link
Contributor

dg0yt commented Jul 17, 2022

While created independent of this issue, #25529 might resolve the issue.

@HunterZ
Copy link
Author

HunterZ commented Jul 19, 2022

While created independent of this issue, #25529 might resolve the issue.

This seems like it might be a viable implementation of the third bullet under your previous list of options, as vcpkg z-print-config does seem to return the correct host_triplet in my MINGW64 environment:

$ vcpkg z-print-config
{
  "buildtrees": "C:\\msys64\\opt\\vcpkg\\buildtrees",
  "default_triplet": "x64-mingw-dynamic",
  "downloads": "C:\\msys64\\opt\\vcpkg\\downloads",
  "host_triplet": "x64-mingw-dynamic",
  "installed": "C:\\msys64\\opt\\vcpkg\\installed",
  "manifest_mode_enabled": false,
  "packages": "C:\\msys64\\opt\\vcpkg\\packages",
  "tools": "C:\\msys64\\opt\\vcpkg\\downloads\\tools",
  "vcpkg_root": "C:\\msys64\\opt\\vcpkg",
  "versions_output": "C:\\msys64\\opt\\vcpkg\\buildtrees\\versioning_\\versions"
}

Of course, this is because I have set the environment variables like so:

VCPKG_DEFAULT_HOST_TRIPLET=x64-mingw-dynamic
VCPKG_DEFAULT_TRIPLET=x64-mingw-dynamic

...and unsetting them reverts host_triplet to x64-windows.

Note that the proposed change does not address the likelihood that it's physically impossible for the elseif(MINGW) check to ever evaluate to true, thus making it almost certainly technical debt. It may be worth keeping this issue open to capture that loose end, even if/when the pull request is approved.

@HunterZ
Copy link
Author

HunterZ commented Oct 11, 2022 via email

@HunterZ
Copy link
Author

HunterZ commented Oct 11, 2022 via email

@JackBoosY JackBoosY removed their assignment Oct 13, 2022
@JonLiu1993
Copy link
Member

This issue hasn’t been updated in 3 month, if it is still an issue, please reopen this issue.

@dg0yt
Copy link
Contributor

dg0yt commented Jul 29, 2024

@JonLiu1993 Look, this issue is still relevant

@JonLiu1993 JonLiu1993 reopened this Jul 30, 2024
Copy link

This is an automated message. Per our repo policy, stale issues get closed if there has been no activity in the past 180 days. The issue will be automatically closed in 14 days. If you wish to keep this issue open, please add a new comment.

@github-actions github-actions bot added the Stale label Feb 12, 2025
@HunterZ
Copy link
Author

HunterZ commented Feb 23, 2025

Closing and unsubscribing due to badgering by user hostile bot. You've had almost 3 years to address this. It's not my fault that nobody cares.

@HunterZ HunterZ closed this as completed Feb 23, 2025
@JackBoosY
Copy link
Contributor

I think we should consider this case and this is NOT a community triplet issue.
cc @BillyONeal to take a look.

@JonLiu1993 JonLiu1993 reopened this Feb 24, 2025
@github-actions github-actions bot removed the Stale label Feb 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category:community-triplet A PR or issue related to community triplets not officially validated by the vcpkg team.
Projects
None yet
Development

No branches or pull requests

6 participants
@HunterZ @dg0yt @aminya @JackBoosY @JonLiu1993 and others