microsoft / vscode-cpptools

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

Request: Single global C_Cpp_properties.json file for a multi-root workspace (not one per workspace folder) #2060

Open dsanz006 opened 6 years ago

dsanz006 commented 6 years ago

For my current project, I am using a multi-root workspace. My problem is that the C/C++ Extension doesn't allow me to have a single global C_Cpp_properties.json file for the entire workspace: it forces me to create a different properties file for each folder. My workspace folder structure is something like this:

<workspace root>/src/ <workspace root>/lib1/ <workspace root>/lib2/ <workspace root>/vscode_workspace/

where vscode_workspace/ doesn't contain any code: it only contains myWorkspace.code-workspace and .vscode/C_Cpp_properties.json. The myWorkspace.code-workspace file looks something like this:

{ "folders": [ { "path": "../src" }, { "path": "../lib1" }, { "path": "../lib2" }, ] }

However, my C_Cpp_properties.json file is not detected correctly, the extension wants me to have a properties file on each src/ lib1/ and lib2/ folders.

I know that with the latest update I can define some parameters of the C_Cpp_properties.json file in the .code-workspace file under the "settings" field, but this is not valid for my case as I have different configurations that require different includePaths and defines.

Actually, the ideal solution for what I want to do would be that different configurations are supported in the .code-workspace file, whithout a need for the C_Cpp_properties.json file at all.

dsanz006 commented 6 years ago

Just to clarify: this is a request to allow having a single C_Cpp_properties.json file in multi-root workspaces.

I opened a new request issue, #2096, for the other part I mentioned: allowing different configurations in the .code-workspace file.

jazzmx commented 5 years ago

Same issue here. I need to copy the same c_cpp_properties.json file into each folder (root) of the workspace. I also have the multiple configurations issue: a native compile and a cross-compile configuration, so when I want to switch configuration, I need to manually switch each folder (root) in the workspace. Having a global workspace configuration file supporting multiple configuration would be a really great improvement! And thank you for the great work!

dsanz006 commented 5 years ago

There is a similar issue with the launch configurations in multiroot workspaces, as one would need one launch.json file per workspace folder. VS Code solves this issue by allowing to have worksapace launch configurations in the .code-workspace file, under the "launch" key, as described here: https://code.visualstudio.com/docs/editor/multi-root-workspaces#_workspace-launch-configurations

A similar solution could work here I think.

ShaneLillieRAD commented 5 years ago

Any chance we'll see this make its way into a milestone soon? The project I work with is too large to have a config file in every folder of the workspace so this one issue is really the biggest hurdle in the way of using VS Code on it.

sean-mcmanus commented 5 years ago

@ShaneLillieRAD One potential workaround is use to add C_Cpp.default.* settings to your workspace's settings.json that contains the shared settings. Folder without a c_cpp_properties.json will use those settings and those wth a c_cpp_properties.json can use ${default} to reference the workspace setting if they want. Does that work for you?

ShaneLillieRAD commented 5 years ago

I don't believe it does, unless there's something that I'm missing in how it should be setup. We are currently doing this in our settings.json in the workspace's .vscode folder:

{
  "C_Cpp.default.cStandard": "c11", 
  "C_Cpp.default.includePath": [
    "${workspaceFolder}/../../../../blah", 
    ....
  ], 
  "C_Cpp.default.cppStandard": "c++17"
}

and in the workspace folder's .vscode/c_cpp_properties.json we have basically just a list of configurations that look similar to this:

    {
      "intelliSenseMode": "msvc-x64", 
      "name": "Appname Win7 Release", 
      "cppStandard": "${default}", 
      "cStandard": "${default}", 
      "includePath": [
        "${default}"
      ], 
      "defines": [
        "${default}", 
        "Release_", 
         "Win7_"
      ]
    }, 
    {
      "intelliSenseMode": "msvc-x64", 
      "name": "Appname Win10 Debug", 
      "cppStandard": "${default}", 
      "cStandard": "${default}", 
      "includePath": [
        "${default}"
      ], 
      "defines": [
        "${default}", 
        "Debug_", 
        "Win10_",
      ]
    },

With that setup VS Code is unable to find included headers despite, I believe, the path being correct in the settings.json (relative to the workspace folder, not the workspace's .vscode folder).

sean-mcmanus commented 5 years ago

I just tried it with a simple workspace with 2 folders that references "${workspaceFolder}/../../Headers" and it worked for me with 0.24.1. Do you know what would be different in your case or can you provide a sample repro project?

Can you use C/C++: Log Diagnostics to see what paths are getting used for IntelliSense?

airbrett commented 5 years ago

@ShaneLillieRAD It looks like you and I are trying to accomplish the same thing. Have you tried using the .code-workspace file rather than settings.json? I couldn't get settings.json to work but when I put the C_Cpp.default.* settings into my workspace file things started working. This is what my file looks like:

{
    "folders": [
        {
            "path": "."
        },
        {
            "path": "C:/Users/Myself/Desktop/Test/"
        },
        {
            "path": "C:/Work/Libs/Widget/trunk",
            "name": "Widget"
        },
        {
            "path": "C:/Work/3rdParty/boost_1_60_0",
            "name": "Boost"
        }
    ],
    "settings": {
        "C_Cpp.default.includePath": [
            "C:/Users/Myself/Desktop/Test//**",
            "C:/Work/Libs/Widget/trunk",
            "C:/Work/3rdParty/boost_1_60_0"
        ],
        "C_Cpp.default.compilerPath": "C:/Work/3rdParty/mingw32-i686-5.3.0-release-posix-dwarf-rt_v4-rev0/bin/g++.exe",
        "C_Cpp.default.intelliSenseMode": "gcc-x64"
    }
}
ShaneLillieRAD commented 5 years ago

@sean-mcmanus this is what I get from the diagnostics:

-------- Diagnostics - 7/25/2019, 2:25:32 PM
Version: 0.24.1
Current Configuration:
{
    "intelliSenseMode": "msvc-x64",
    "name": "Appname Win7 Release",
    "cppStandard": "c++17",
    "cStandard": "c11",
    "includePath": [
        "${workspaceFolder}/../../../../src/net/libs",
        "${workspaceFolder}/**",
        "${workspaceFolder}/../../../../src/core/libs",
        "${workspaceFolder}/../../../../src/apps/appname"
    ],
    "defines": [
        "Release_",
        "Win7_"
    ],
    "browse": {
        "path": [
            "${workspaceFolder}/../../../../src/net/libs",
            "${workspaceFolder}/**",
            "${workspaceFolder}/../../../../src/core/libs",
            "${workspaceFolder}/../../../../src/apps/appname"
        ],
        "limitSymbolsToIncludedHeaders": true
    }
}

Those paths seems fine relative to the directory that contains the .code-workspace file. I'll try @airbrett 's suggestion next to see if that gets it working. Unfortunately coming up with a repro example may not be very easy while still capturing how our structure is setup.

sean-mcmanus commented 5 years ago

Yeah, my workspace settings are in the .code-workspace (not settings.json).

The log is missing the data I need -- I need the "Includes: " section after "Translation Unit Configurations". The info you provided is basically just a copy of the c_cpp_properties.json.

In my repro, the path that the .code-workspace file is in is not being used as the "${workspaceFolder}".

ShaneLillieRAD commented 5 years ago

Ah, ok. I didn't have a .cpp opened when I ran it the first time. Here is what comes out of the Includes section:

    Includes:
        D:\EXTERNALS\VCPKG\INSTALLED\X64-WINDOWS-STATIC\INCLUDE
        C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 14.0\VC\INCLUDE
        C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 14.0\VC\ATLMFC\INCLUDE
        C:\PROGRAM FILES (X86)\WINDOWS KITS\10\INCLUDE\10.0.17763.0\UM
        C:\PROGRAM FILES (X86)\WINDOWS KITS\10\INCLUDE\10.0.17763.0\UCRT
        C:\PROGRAM FILES (X86)\WINDOWS KITS\10\INCLUDE\10.0.17763.0\SHARED
        C:\PROGRAM FILES (X86)\WINDOWS KITS\10\INCLUDE\10.0.17763.0\WINRT
        C:\PROGRAM FILES (X86)\WINDOWS KITS\10\INCLUDE\10.0.17763.0\CPPWINRT

So nothing that's actually from my settings.json. And the Configuration actually changed to what looks to be the default:

Current Configuration:
{
    "name": "Win32",
    "includePath": [
        "${workspaceFolder}/**",
        "${vcpkgRoot}/x64-windows-static/include"
    ],
    "defines": [
        "_DEBUG",
        "UNICODE",
        "_UNICODE"
    ],
    "windowsSdkVersion": "10.0.17763.0",
    "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/cl.exe",
    "knownCompilers": [
        {
            "path": "/usr/bin/gcc",
            "isC": true
        },
        {
            "path": "/usr/bin/g++",
            "isC": false
        },
        {
            "path": "/usr/bin/cpp",
            "isC": false
        },
        {
            "path": "C:\\cygwin64\\bin\\gcc.exe",
            "isC": true
        },
        {
            "path": "C:\\cygwin64\\bin\\g++.exe",
            "isC": false
        },
        {
            "path": "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/cl.exe",
            "isC": false
        },
        {
            "path": "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/cl.exe",
            "isC": true
        }
    ],
    "cStandard": "c11",
    "cppStandard": "c++17",
    "intelliSenseMode": "msvc-x64",
    "browse": {
        "path": [
            "${workspaceFolder}/**",
            "${vcpkgRoot}/x64-windows-static/include"
        ],
        "limitSymbolsToIncludedHeaders": true
    }
}

Out of curiosity I ran the echo ${workspaceFolder} task from the variables reference documentation and it does print out the directory containing my .code-workspace file, so that seems to be a correct assumption at least for me?

Sounds like the fix tho may just be to put those settings into the .code-workspace file instead of settings.json.

sean-mcmanus commented 5 years ago

I'm confused now. Yeah, it looks like it's not using the correct settings. You may want to enable debug logging to get more info on what is going wrong with the configuration.

echo ${workspaceFolder} gives me the folder where the task.json is located, i.e. not the folder where .code-workspace exists at (see https://code.visualstudio.com/docs/editor/variables-reference ).

Yeah, settings.json is just for User/Folder settings (when I said "workspace's settings.json" I meant the settings section in the .code-workspace file).

ShaneLillieRAD commented 5 years ago

Well now I'm confused because the log is saying this:

  Folder: D:/.../SRC/NET/LIBS/ will be indexed
  Folder: D:/.../_LOCAL/VSCODE/NET/APPNAME/ will be indexed
  Folder: D:/.../SRC/CORE/LIBS/ will be indexed
  Folder: D:/.../SRC/NET/APPS/APPNAME/ will be indexed

I've edited the paths to take out some of the parts, but all of them are correct.

bobbrow commented 5 years ago

Not sure if this helps, but you can address each folder individually with the variable syntax. You would put something like this in your Workspace settings if you wanted to effectively merge all of your c_cpp_properties.json files together (3 folders opened named "root1", "root2", and "root3").

    "settings": {
        "C_Cpp.default.includePath": [
            "${workspaceFolder:root1}/**",
            "${workspaceFolder:root2}/**",
            "${workspaceFolder:root3}/**"
        ]
    }
sean-mcmanus commented 5 years ago

The "Folders....will be indexed" is for the browse.path setting, which we attempt to populate from the includePath if no browse.path exists.

nitingupta910 commented 5 years ago

I'm hitting another problem in multi-root workspaces -- I have two folders added to workspace:

With includePath set to [${workspaceFolder}/linux/**, ${workspaceFolder}/mydriver/**] vscode can correctly resolve headers in linux when editing files in mydriver. However, go-to-definition does not work for any symbol defined in linux when working in mydriver/foo.c.

bobbrow commented 5 years ago

@nitingupta910, did you see my comment above? Try ${workspaceFolder:linux}/** and ${workspaceFolder:mydriver}/** instead.

gentooise commented 5 years ago

@ShaneLillieRAD One potential workaround is use to add C_Cpp.default.* settings to your workspace's settings.json that contains the shared settings. Folder without a c_cpp_properties.json will use those settings and those wth a c_cpp_properties.json can use ${default} to reference the workspace setting if they want. Does that work for you?

Hi @sean-mcmanus I'm trying to follow your instructions here, because I have the same issue. But as soon as I remove c_cpp_properties.json from specific folder I get this additional configuration that seems to pollute my environment:

Current Configuration:
{
    "name": "Win32",
    "includePath": [
        "${workspaceFolder}/**"
    ],
    "defines": [
        "_DEBUG",
        "UNICODE",
        "_UNICODE"
    ],
    "windowsSdkVersion": "10.0.17134.0",
    "knownCompilers": [
        {
            "path": "C:\\MinGW\\bin\\gcc.exe",
            "isC": true
        },
        {
            "path": "C:\\MinGW\\bin\\g++.exe",
            "isC": false
        },
        {
            "path": "C:\\MinGW\\bin\\cpp.exe",
            "isC": false
        },
        {
            "path": "C:\\MinGW\\bin\\gcc.exe",
            "isC": true
        },
        {
            "path": "C:\\MinGW\\bin\\g++.exe",
            "isC": false
        },
        {
            "path": "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.15.26726/bin/Hostx64/x64/cl.exe",
            "isC": false
        },
        {
            "path": "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.15.26726/bin/Hostx64/x64/cl.exe",
            "isC": true
        }
    ],

    [...]

}

This is my c_cpp_properties.json:

{
    "configurations": [
        {
            "name": "ARM",
            "cStandard": "c99",
            "cppStandard": "c++03",
            "intelliSenseMode": "gcc-x86",
            "configurationProvider": "vector-of-bool.cmake-tools",
            "compilerPath": "${workspaceFolder:Project}/.vscode/compile.bat",
            "compileCommands": "${workspaceFolder:Project}/.vscode/compile_commands.json"
        }
    ],
    "version": 4
}

which I wanted to replace with the following defaults in my .code-workspace file:

        "C_Cpp.default.cStandard": "c99",
        "C_Cpp.default.cppStandard": "c++03",
        "C_Cpp.default.intelliSenseMode": "gcc-x86",
        "C_Cpp.default.configurationProvider": "vector-of-bool.cmake-tools",
        "C_Cpp.default.compilerPath": "${workspaceFolder:Project}/.vscode/compile.bat",
        "C_Cpp.default.compileCommands": "${workspaceFolder:Project}/.vscode/compile_commands.json"

Basically, I think my issue is that there is no default entry to specify a configuration (with a name) inside .code-workspace file.

Do you have any suggestion @bobbrow @sean-mcmanus?

J-Sorenson commented 4 years ago

This would be nice, but I think #2096 would be the better implementation (at least for my setup). Either way, we need at least one of these solutions to get developed.

lygstate commented 4 years ago

How about add such configuration with

{
    "folders": [
        {
            "path": "."
        },
        {
            "path": "C:\Test"
        }
    ],
    "settings": {
        "files.associations": {
            "prjparams.h": "c",
            "stdio.h": "c",
            "usrappinit.h": "c",
            "corecrt_wstdio.h": "c",
            "mempartlibp.h": "c",
            "handlelibp.h": "c",
            "wdbendpktdrv.h": "c",
            "aiosysdrv.h": "c",
            "aio.h": "c",
            "config.h": "c",
            "configall.h": "c",
            "vxworks.h": "c",
            "prjcomps.h": "c"
        },
        "C_cpp.workspacePropertiesPath": "${${workspaceFolder:integration}}/.vscode/c_cpp_properties.json"
    }
}
david-antiteum commented 4 years ago

We have a very large, monolithic, repository. We can use workspaces to load only part of the code (and use the rest of the repo as external references). This will allow us to reduce the parsing cost while narrowing symbols to the parts in where we are working. We can slice our repo in several ways creating tens of workspace. Our initial idea is to create a top folder in the repo called workspaces to store all these workspace files.

Loading a common c_cpp_properties.json is a must, as loading other common settings. Having the ability to overwrite some settings at workspace level will be great.

So. I need the implementation of #2060 and not really #2096 :)

Thanks.

selassje commented 4 years ago

The most convenient approach would be to allow setting a default path of a c_cpp_properties,json in the .code-workspace file. Those configurations would be used when none are found on the root folder level.

sean-mcmanus commented 4 years ago

@selassje There is no VS Code API our extension can use to get the .code-workspace that is being used -- the closest to that would be to add a setting, which could be set in the .code-workspace file or other locations.

Well, there's a VS Code issue tracking potentially exposing that path...

selassje commented 4 years ago

@sean-mcmanus Works for me.

hacantorcooke commented 4 years ago

Is there any update/workaround on this? Like others, I essentially need configurations at the workspace level. The defaults would work except they seem to only allow one entry, not an array of configurations. I.E. it seems workspaces have no concept of configurations. I want my includes/defines to change based on configuration.

Another concept would be VS Code treating the folder I want to add like a sym-link rather than treating it as an independent root. That would make the other folders look like sub-dirs and then I assume the c_cpp_properties would get inherited just for that workspace.

sean-mcmanus commented 4 years ago

@hacantorcooke No update. You could potentially use multiple different workspaces with different workspace C_Cpp.default.* settings.

github-actions[bot] commented 4 years ago

This feature request has received enough votes to be added to our backlog.

hacantorcooke commented 3 years ago

Just wanted to report back. Since my last comment, I have been using the sym-link method. I added symlinks to my multi-root folders in my actual file-system under the "main folder." So when VS-Code opens it, it sees all the folders I want under my one main root.

This has worked pretty well but I still get complaints because I have added symlinks to the repo which means people grepping will get multiple results.

Just wanted to add this info in that if there's a way to effectively do a symlink in VS-code/extension, it would likely work without too much extra work.

pmolodo commented 2 years ago

Just to make sure I'm clear - there's still no way to set a default compileCommands to point to compile_commands.json, correct?

sean-mcmanus commented 2 years ago

@pmolodo Maybe set "C_Cpp.default.compileCommands": "${workspaceFolder}/compile_commands.json"?

pmolodo commented 2 years ago

Ah, yes, I missed that. Thanks!

positron96 commented 5 months ago

Can anybody give a status update? I assume it's not solved as it's open, but is it planned?