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

Environment variables not being picked up during preset configuration #4253

Open
TSonono opened this issue Jan 24, 2025 · 4 comments
Open

Environment variables not being picked up during preset configuration #4253

TSonono opened this issue Jan 24, 2025 · 4 comments

Comments

@TSonono
Copy link
Contributor

TSonono commented Jan 24, 2025

Brief Issue Summary

When configuring a project with a configuration preset, $env{<environment-variable>} is not picking up environment variables defined in extension setting cmake.environment. Same result when setting cmake.configureEnvironment. In the reproducer, I would expect the output of message(${CACHE_VARIABLE_FROM_PRESET}) to be hello/preset, but it just becomes /preset. Is this a bug or expected behavior? From https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html:

$env{}
Environment variable with name . The variable name may not be an empty string. If the variable is defined in the environment field, that value is used instead of the value from the parent environment. If the environment variable is not defined, this evaluates as an empty string.

I would expect the extension setting cmake.environment in this case to define the "parent" environment of the preset execution, as the environment field mentioned in the quote above is referencing to the environment field within the preset itself (the environment variables defined in the environment field in the preset file are being picked up correctly by the way). Since when I run AN_ENV_VARIABLE=hello cmake --preset ninja directly from CLI, behavior is as expected (output of message is hello/preset).

VSCode version: 1.96.4
Extension version: 1.19.52
CMake version: 3.26.4

This may be a duplicate of the issue partially described in #4218

Attached small vscode workspace reproducer:
cmake-preset-bug.zip

@gcampbell-msft
Copy link
Collaborator

@TSonono Thanks for the issue.

The story is primarily that the design of the extension, as well as CMake Presets, officially supports the "environment" block within the CMakePresets.json configure preset. Therefore, it is much better if you update the "environment" block of the Preset.

If the reason you aren't doing this is because you don't want to share this change with other developers, you can utilize a CMakeUserPresets.json file.

Secondarily, this does sound like it could be an oversight in our design of the various environment settings provided through VS Code when used with presets. However, those settings were originally created for use with Kits. We primarily are focused on supporting Presets, so we simply made those settings such that they temporarily add to the environment before invoking commands when presets are being used.

In short:

  1. Please prefer to use Presets standards for defining environments through your presets.
  2. This could be an oversight in our design of the settings when used in Presets scenarios, as it would make sense that if they can be used for the commands, then you'd expect that wherever macro expansion is supported, we would support that. As it currently stands, this is by design, but we are willing to consider slight modifications, if for some reason the officially supported Presets design doesn't fully support your scenario.

Please let me know if you have any other questions or if I can help in any way. Thanks!

@gcampbell-msft gcampbell-msft added more info needed More info is needed from the community for us to properly triage and investigate. and removed triage labels Jan 24, 2025
@gcampbell-msft gcampbell-msft added this to the On Deck milestone Jan 24, 2025
@TSonono
Copy link
Contributor Author

TSonono commented Jan 24, 2025

@gcampbell-msft Thanks for your response

Please prefer to use Presets standards for defining environments through your presets.

I think one could argue that the way I'm using preset follows the standards given the quote I copied earlier from the CMake docs:

$env{}
Environment variable with name . The variable name may not be an empty string. If the variable is defined in the environment field, that value is used instead of the value from the parent environment. If the environment variable is not defined, this evaluates as an empty string.

and given how the CLI invocation produced the expected behavior.

Regarding using CMakeUserPresets.json, while this is the work-around I'm currently employing, it's not super effective depending on how the CMakePresets.json file is constructed. Take an example where you have a base preset that is referencing an $env{} that can not be set in the CMakePresets.json file itself. In the same file, you have say 7 child presets that inherit this parent preset. This would mean that you would have to make 7 presets in your CMakeUserPresets.json that inherits each child preset in CMakePresets.json respectively. Now, in each of these presets in your CMakeUserPresets.json file, you have to set the environment variable in the environment block. And if there's a new child preset checked in to CMakePresets.json, you would have manually once again add the new child preset to your CMakeUserPresets.json file. Not to mention all the "duplicate" preset entries that would appear in the preset selection view in vscode where the only difference would be that the child preset from the CMakeUserPresets.json file has the environment block defined. I would therefore argue that it could make sense to change the current behavior of the extension in this regard.

@gcampbell-msft
Copy link
Collaborator

@TSonono I completely agree, you are using the preset following the standards regarding the use of $env{} variable. However the settings we provide like cmake.environment, etc, aren't from Presets, they are from the extension and for context, originate from when the extension only had Kits support a long time ago.

"and given how the CLI invocation produced the expected behavior". What do you mean by this? The CLI outside of VS Code won't know about the cmake.environment or other settings. Maybe I don't fully understand what mean by this, thanks.

You make a good point regarding the Presets set up. Would an alternative set up work, where you create a CMakeUserPresets.json that inherits the base, and then all of the child presets inherit the CMakeUserPresets.json preset? This would mitigate all of the duplicates and allow you to essentially have a new base (that also inherits the base from CMakePresets.json).

However, I do think this is something that we could investigate addressing, so I'll put it on our backlog. Thanks!

@gcampbell-msft gcampbell-msft moved this from Blocked to Pending Prioritization in CMake Tools Jan 24, 2025
@gcampbell-msft gcampbell-msft added Feature: settings Feature: presets and removed more info needed More info is needed from the community for us to properly triage and investigate. labels Jan 24, 2025
@TSonono
Copy link
Contributor Author

TSonono commented Jan 27, 2025

@gcampbell-msft

"and given how the CLI invocation produced the expected behavior". What do you mean by this? The CLI outside of VS Code won't know about the cmake.environment or other settings. Maybe I don't fully understand what mean by this, thanks.

Yes, this is outside of VS Code, I'm just trying to highlight that when using cmake through CLI, the preset environment variables are being picked up as expected, unlike when using presets through VS Code.

You make a good point regarding the Presets set up. Would an alternative set up work, where you create a CMakeUserPresets.json that inherits the base, and then all of the child presets inherit the CMakeUserPresets.json preset? This would mitigate all of the duplicates and allow you to essentially have a new base (that also inherits the base from CMakePresets.json).

If I understand you correctly here, you are suggesting that the child presets from CMakePresets.json inherit the preset that I create in CMakeUserPresets.json (the new base) that has inherited the base from CMakePresets.json. This wouldn't work as (from CMake docs) "Presets in CMakePresets.json may not inherit from presets in CMakeUserPresets.json".

Or if you are saying that the child presets that should inherit the new base are also in CMakeUserPresets.json, they would still become dupes since they already exist in CMakePresets.json.

However, I do think this is something that we could investigate addressing, so I'll put it on our backlog. Thanks!

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Pending Prioritization
Development

No branches or pull requests

2 participants