microsoft / vscode-cpptools

Official repository for the Microsoft C/C++ extension for VS Code.
Other
5.53k stars 1.56k forks source link

[feature] Use script files to preload environment variables in `launch.json`. #9329

Open hwhsu1231 opened 2 years ago

hwhsu1231 commented 2 years ago

Feature Request

It is related to this issue: https://github.com/conan-io/conan/issues/11042

About 1 month ago, I posted the above issue on Conan. The key point of that issue is as follows:

However, although VirtualRunEnv generators provide scripts(conanrun.(bat|sh)) to setup the environment variables, it seems that VSCode doesn't provide the features to preload those *.bat or *.sh file in launch.json, dynamically. The only way to do that is to use envFile option to load *.env file to setup environment.

Therefore, my request was that VirtualRunEnv generates the corresponding *.env file, so that we can use it in envFile option in launch.json. And it seems that Conan official agreed with my feature request of that issue: https://github.com/conan-io/conan/issues/11042#issuecomment-1102213822.

However, if VSCode (or cpptools) can provide the feature of "dynamically preloading script files" in launch.json, that would be great.

sean-mcmanus commented 2 years ago

If the request is on VS Code then you'd want to open an issue at https://github.com/microsoft/vscode . Or some Conan VS Code extension? I'm not sure if our extension would be able to implement this ourselves. @WardenGnaw or @elahehrashedi might know.

elahehrashedi commented 2 years ago

There are a few different ways to preload env variables from script files.

    "configurations": [
        {
            "name": "build and debug active file",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
            "args": [],
            "cwd": "${fileDirname}",
            "environment": [],
            ...
            "envFile": "script_file_name.env"
            "preLaunchTask": "extract env from script task"
        }
    ]

and the example of the task would be something like this:

    "tasks": [
        {
            "type": "cppbuild",
            "label": "extract env from script task", 
            "command": "VirtualRunEnv",
            "args":["script_file_name.bat"],
            "group": "none"
        }
    ]

@hwhsu1231 Which one of these would work better for you?

hwhsu1231 commented 2 years ago

@elahehrashedi For the simplicity of usage, I think the "second" way is more suitable to my situation.

  • Adding a new entity to the launch.json configuration, for example, "envFromScript" (we can find a better name for it later):

About the "third" way, I attempted to use "prelaunchTask" to preload the script file generated by VirtualRunEnv generator. However, it failed. It seems that launch.json and tasks.json don't share the same shell environment. If the "third" way is able to work, users can do more functional operations such as "passing arguments to the script files"...etc. However, it is not necessary in my situation.

Therefore, I suggest that support the "second" way first, and then consider the "third" way.

By the way, what is the mechanism of the "first" way? Do you mean providing commands in the Command Palette? I don' t think it is a good idea. It is better to bind this action to the launch.json, instead of separating.

hwhsu1231 commented 2 years ago

If "VSCode(or cpptools)" can provide the "second" way in launch.json, then I hope "Visual Studio" provides the similar feature in launch.vs.json as well.

About 2 months ago, I posted a feature request in Visual Studio Feedbacks:

Provide "loading *.env file" or "loading script file" feature in launch.vs.json to set up environemnt variables.

elahehrashedi commented 2 years ago

About 2 months ago, I posted a feature request in Visual Studio Feedbacks:

I recommend you post your issue for Vs Code here: https://github.com/microsoft/vscode/issues

elahehrashedi commented 2 years ago

About the "third" way, I attempted to use "prelaunchTask" to preload the script file generated by VirtualRunEnv generator. However, it failed. It seems that launch.json and tasks.json don't share the same shell environment. If the "third" way is able to work, users can do more functional operations such as "passing arguments to the script files"...etc. However, it is not necessary in my situation.

Some more explanation about the third approach, this task is not designed to provide env variables directly for launch, but it will create the env file as a part of the prelaunchtask (e.g. script_file_name.env), and this line in launch.json will load that file.

            "envFile": "script_file_name.env"
            "preLaunchTask": "extract env from script task"

So for example if the arg in task is defined as ["script_file_name.bat"], after running the task, an env file with the same name will be created, e.g. script_file_name.env

SpaceIm commented 1 year ago

CLion has this feature, an "env script" (having a collection of export FOO=...) can be sourced just before running debugger or executable target (without debugger), in the same context in which executable is run. It allows to programmatically generate an env script with complex env vars before hands (in case described by @hwhsu1231 conan would generate such script, but it could be any other tool) instead of manually hardcoding these complex and moving env vars for each target.

I have no idea if such feature should be implemented in VSCode itself or in extension implementing a specific type of launch.json.

For the moment I have written a custom command calling conan installation of dependencies then parsing env script generated by conan in order to generate an "env file" in a specific location. This "env file" is referenced in launch.json since cppdbg & cppvsdbg types have this field envFile, but it's not very convenient and absolutely not user friendly for beginners.

paulharris commented 1 year ago

I'd like this feature. For now, on Windows, I use the cmd prompt, change to the dir, activate conan env, and run the project's build/conanrun.bat and then run code . Then VS Code launches in the required environment. I imagine I'd have to close, deactivate+activate the runenv, and relaunch if the deps changed.

Ashark commented 3 months ago

Any update on this? I would like the "envFromScript" approach.

Ashark commented 3 months ago

I have checked if the kit's environment could be used as a workaround. Because kits have environmentSetupScript.

The result is again kinda weird.

In case I use launch/debug without launch.json (just by clicking on icon, see https://github.com/microsoft/vscode-cmake-tools/blob/main/docs/debug-launch.md#debugging-without-a-launchjson), then the environment from kit's env script is applied! But... If I launch using some configuration from launch.json, it is not applied :(.

Is this expected behavior? I highly doubt it.

skycaptain commented 1 month ago

To add another use-case: Most cross-compiling SDKs require sourcing an environment script that sets variables for both compilation and debugging targets with the included GDB. It would be really helpful to use these environment variables in launch.json, e.g.:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "(gdb) Launch",
      "type": "cppdbg",
      "request": "launch",
      // $CMAKE_CROSSCOMPILING_EMULATOR is available after sourcing the environment-setup script below
      "program": "${env:CMAKE_CROSSCOMPILING_EMULATOR} ${command:cmake.launchTargetPath}",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}",
      // This also adds the native sysroot to PATH
      "environmentSetupScript": "${env:SDK_HOME}/environment-setup-cortexa57-oe-linux",
      "externalConsole": false,
      // $GDB is available after sourcing the environment-setup script above 
      "miDebuggerPath": "${env:GDB}",
      "MIMode": "gdb",
      ...
    }
  ]
}