Issue Type: Bug
We use make to build our software. To build I have to setup a task that does the following:
"command": "cd subproject && make"
Setting this up as a shell task and using the $gcc problemMatcher the problem links do not find the file because they do not include the subproject folder in the path.
There needs to be a way to specify the root path to use for the problem matcher.
Extension version: 0.17.6
VS Code version: Code 1.25.1 (1dfc5e557209371715f655691b1235b6b26a06be, 2018-07-11T15:33:29.235Z)
OS version: Darwin x64 16.7.0
System Info
|Item|Value|
|---|---|
|CPUs|Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz (8 x 2200)|
|GPU Status|2d_canvas: enabled
flash_3d: enabled
flash_stage3d: enabled
flash_stage3d_baseline: enabled
gpu_compositing: enabled
multiple_raster_threads: enabled_on
native_gpu_memory_buffers: enabled
rasterization: enabled
video_decode: enabled
video_encode: enabled
vpx_decode: enabled
webgl: enabled
webgl2: enabled|
|Load (avg)|2, 2, 2|
|Memory (System)|16.00GB (0.06GB free)|
|Process Argv|/Applications/Visual Studio Code.app/Contents/MacOS/Electron ..|
|Screen Reader|no|
|VM|0%|
Have you seen this documentation?
I believe the problem in your case is that our built-in problem matcher only matches paths relative to the ${workspaceFolder}. If you defined your own in tasks.json (you can copy ours from the package.json or use the one in the example linked above), and changed the fileLocation property to be relative to the folder you want, does that work for you?
EDIT:
Credit to @ocboogie below. Bringing this solution to the top of the thread. Add the following to your task and set the fileLocation to where you want your relative paths to start from.
{
...
"problemMatcher": {
"base": "$gcc",
"fileLocation": ["relative", "${workspaceRoot}/builddir"]
}
}
That works but it's a lot of copy and paste. Could a parameter be added to the task so the build root could be passed into the extension's matcher? Something like this:
"label": "build",
"type": "shell",
"taskDir": "${workspaceFolder}/MyProjectRoot", //< the shell first changes pwd to this then executes command
"command": "make",
"problemMatcher": [
"$gcc"
],
"group": "build"
And the matcher would then have:
"fileLocation": [ "relative", "${taskDir}" ],
We don't own the tasks system so I think you would have to ask the VS Code team for a new parameter on the task schema. You might be able to make it work with an environment variable added to
"options": {
"env": []
}
and then reference that in your custom problem matcher with the ${env:VAR} syntax. If that works, we would accept a PR into our repository if you added that problem matcher to package.json.
The below example appears to work for bash shells but isn't portable. I didn't know about the options in the task so thanks. I'm not sure what a portable version of this would look like though.
"label": "build",
"type": "shell",
"command": "make",
"options": {
"cwd": "MyProjectFolder"
},
"problemMatcher": {
"owner": "cpptools",
"fileLocation": [ "relative", "${env:PWD}" ],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
I imagine it would be something like:
"options": {
"env": [ "matchFolder": "${workspaceFolder}/subdir" ]
}
...
"fileLocation": [ "relative", "${env:matchFolder}" ]
Though I'm not sure if VS Code would resolve the variable inside the variable or not. "matchFolder" might have to be an absolute path.
weird. That doesn't work. ${env:PWD} resolves and if I echo $matchFolder it is set in the shell environment but the variable is just blank if i use it as ${env:matchFolder} in the fileLocation. That makes no sense at all.
It could be a bug in VS Code.
I tried adding a global problem matcher with the correct build directory, yet it does not seem to be invoked. When and how is the global problem matcher invoked? Some of us use the cmake tools extension in addition to cpptools others run the build from the integrated promt, and of course we're hitting this regularly, since it's more or less standard for cmake building in a "build" subdirectory or the project. Usually the paths are relative to the compile_commands though and we're already supplying that path...
If the Problem Matcher doesn't already track the output from make when it switches to another directory ("make: Entering directory '/foo/bar'" etc), then it will not be useful for any project which uses recursive make, which is quite a few... I'd say that's a rather important feature. Messing with manually added root paths doesn't really solve the problem.
If there already is support for this (I haven't checked), the OP must simply use make -C subdir instead of cd subdir && make.
The workaround I use is to modify the Makefile rule slightly to use something like: $(CC) $(CFLAGS) $(CFLAGS.$<) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $(abspath $<) which will expand the absolute file-name. I then updated the Problem Matcher to use absolute file names instead of relative file-names. gcc error and warning messages echo the absolute file-name that was provided on the command line and the Problem Matcher works correctly.
Because vscode Problem Matchers doesn't seem to work with multiple relative subdirectories for recursive make this is the only way I've found for it to work.
You can get rid of all the copy and pasting just by using the base property in the problemMatcher schema.
Here's how VSCode describes the base property (found here)
The name of a base problem matcher to use. If specified the
base problem matcher will be used as a template and properties
specified here will replace properties of the base problem
matcher
and can be used like the following:
{
"type": "shell",
"label": "build",
"command": "ninja",
"options": {
"cwd": "${workspaceRoot}/builddir"
},
"problemMatcher": {
"base": "$gcc",
"fileLocation": ["relative", "${workspaceRoot}/builddir"]
}
}
This will just "extend" gcc problemMatcher and change the fileLocation property.
Just got bitten by this issue after I switched from developing on the virtual machine to VSCode on Windows + WSL...
The workaround with "problemMatcher" and "fileLocation: relative" didn't help and I cannot play with the makefiles.
Hope there's gonna be some ultimate solution delivered in the future since this is really annoying :/

Hi,
I can now navigate to the correct line from the Problems tab by using the following matcher:
"version": "2.0.0",
"tasks": [
{
"label": "Make App",
"problemMatcher": {
"base": "$gcc",
"fileLocation": [
"absolute"
]
},
"type": "shell",
"options": {
"cwd": "${workspaceRoot}/build",
},
"command": "make App",
"group": {
"kind": "build",
"isDefault": true
}
}
]
But still, when I scroll through the Terminal and I do the Ctrl+Click on an error, Visual Studio opens the correct file, but the cursor stays on the 1st line, not the one mentioned in the error.
The exemplary error message looks like this:
/home/rafal/Software/App/src/camera/ctrl.cpp:42:85: required from here
Do you know how I can tweak the problem matcher to fix this issue?
@mgr-inz-rafal You have to change the pattern to something like
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"message": 4
}
to get rid of the missing "severity" in the input. You could also override the default "severity" if you want.
I'm not sure, but I think I tried such regex or similar. Even though it correctly matches the groups (see the picture below), VSCode still takes me to the top of the file.

What is the exact regular expression you're using in the json? e.g. the \ will need to be escaped to \\.
I use the one you proposes, copy&pasted as is in your post. Just to create the picture above I had to modify it slightly.
To increase sureness, this is my entire tasks.json as it is right now. VSCode still only jumps to the top of the file.
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Make",
"problemMatcher": {
"base": "$gcc",
"fileLocation": [
"absolute"
],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"message": 4
}
},
"type": "shell",
"options": {
"cwd": "${workspaceRoot}/build",
},
"command": "make App",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
That is strange. I don't see why that isn't working. It could be a VS Code bug.
Yes, that could be it. Is there a way to enable some debug diagnostics for the problem matcher to see what exactly is going on after I click on the error message?
OK, today I updated the VSCode and it looks like the issue is fixed :)
Using .* in regular expressions subjects you to the whims of the implementation. For example, it could choose to match the : as well if it wanted. It's safer to use something more specific, like [^:]* at the beginning to ensure it matches anything but a colon.
@bobbrow But that doesn't work for Windows paths that have a colon in it, but there's probably a more complicated regex that would work.
Yes, that won't work for Windows paths, but I was thinking @mgr-inz-rafal was dealing with a linux path in this case.
I just ran into this issue. Was this ever resolved?
The solution is here. VS Code doesn't know the basepath for relative paths, so you need to tell it.
As I said in https://github.com/microsoft/vscode-cpptools/issues/2266#issuecomment-434703970 , any fixed build path, regardless of how it's configured, will not solve the full problem. But since the OP's specific problem can use the mentioned solution, maybe the lack of make-style subdir tracking should be handled in a separate issue?
@bobbrow I was asking if the issue of nested make files was resolved. The solution you posted would only work if all sequential make calls were made relative to the root Makefile. @nattgris had explained my issue perfectly, but I have no way of controlling how the imported libraries do their nested make calls. The only viable solution for this edge case would be the implementation of regex in the 2nd parameter of fileLocation.
@yeggles, I don't believe the nested makefile issue is resolved. I think you'd need a feature from VSCode to make it work.
This issue appears to be resolved, so closing it. If there is still an outstanding issue here, please let us know.
Most helpful comment
You can get rid of all the copy and pasting just by using the
baseproperty in theproblemMatcherschema.Here's how VSCode describes the
baseproperty (found here)and can be used like the following:
This will just "extend" gcc problemMatcher and change the
fileLocationproperty.