vscode-cpptools
vscode-cpptools copied to clipboard
C++ IntelliSense/autocomplete is not working for OpenCV or Eigen
Environment
- OS and Version:
Ubuntu 18.04.6 LTS
- VS Code Version:
1.71.2
- C/C++ Extension Version:
v1.12.4
- Other extensions you installed (and if the issue persists after disabling them): yup, the issue persists even after disabling all of them (of course except the C/C++ extension).
- If using SSH remote, specify OS of remote machine:
- A clear and concise description of what the bug is, including information about the workspace (i.e. is the workspace a single project or multiple projects, size of the project, etc).
I'm working on a single C++ project which also uses third-party libraries like OpenCV
and Eigen
. I already have a CMake file and the project builds fine without any issues. (FYI: I'm not using the Microsoft CMake tools extension for building the project. I manually build using the command line) However, when it comes to IntelliSense/Autocomplete, it does not work for these third-party libraries. I tried updating the "C_Cpp.default.includePath"
in settings.json
file and/or "includePath"
in c_cpp_properties.json
file. But that didn't work.
Bug Summary and Steps to Reproduce
Bug Summary:
I'm working on a single C++ project which also uses third-party libraries like OpenCV
and Eigen
. I already have a CMake file and the project builds fine without any issues. (FYI: I'm not using the Microsoft CMake tools extension for building the project. I manually build using the command line) However, when it comes to IntelliSense/Autocomplete, it does not work for these third-party libraries. I tried updating the "C_Cpp.default.includePath"
in settings.json
file and/or "includePath"
in c_cpp_properties.json
file. But that didn't work.
Steps to reproduce:
- Go to '...'
- Click on '....'
- Scroll down to '....'
- See error
- As I can't put the actual code here, here is the toy example:
#include <iostream>
#include <opencv2/core.hpp>
int main(int argc, char const *argv[]) {
cv::Mat mat = cv::Mat::eye(3, 3, CV_64FC1);
std::cout << mat.
return 0;
}
- So, in the above code, when I write
mat.
, I should see some suggestions likerows
,cols
,type()
, etc. However, I don't get any suggestions. - On top of that, even the simple variable autocomplete does not work e.g. if I write
std::court << m
, I should seemat
. But, nope... that doesn't work either.
Expected behavior
- In the above code, when I write
mat.
, I should see some suggestions likerows
,cols
,type()
, etc. However, I don't get any suggestions. - On top of that, even the simple variable autocomplete does not work e.g. if I write
std::court << m
, I should seemat
. But, nope... that doesn't work either. - I should be able to see the function definition of any
OpenCV
functions upon pressing F12 or Ctrl + click. Sadly, it's not working!
Code sample and Logs
- `c_cpp_properties.json` :
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"${default}"
],
"defines": [],
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "linux-clang-x64"
}
],
"version": 4
}
-
settings.json
(only relevant part):
{
.
.
"[cpp]": {
"editor.defaultFormatter": "xaver.clang-format"
},
"C_Cpp.clang_format_path": "/usr/bin/clang-format",
"C_Cpp.clang_format_style": "file",
"C_Cpp.clang_format_fallbackStyle": "none",
"C_Cpp.default.includePath": [
"/usr/local/<blah_blah>/include/opencv4/opencv2/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc/**",
"/usr/local/include/Eigen",
"/usr/local/include/Eigen/*",
"/usr/local/include/Eigen/**"
],
"cmake.configureOnOpen": false,
.
.
.
}
-
C/C++: Log Diagnostic
(FYI: I've replaced some explicit paths with<string>
):
-------- Diagnostics - 9/20/2022, 2:04:12 PM
Version: 1.12.4
Current Configuration:
{
"name": "Linux",
"includePath": [
"/usr/local/<blah_blah>/include/opencv4/opencv2/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc/**",
"/usr/local/include/Eigen",
"/usr/local/include/Eigen/*",
"/usr/local/include/Eigen/**"
],
"defines": [],
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++14",
"intelliSenseMode": "linux-clang-x64",
"intelliSenseModeIsExplicit": false,
"cStandardIsExplicit": false,
"cppStandardIsExplicit": false,
"mergeConfigurations": false,
"compilerPathIsExplicit": false,
"browse": {
"path": [
"/usr/local/<blah_blah>/include/opencv4/opencv2/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc/**",
"/usr/local/include/Eigen",
"/usr/local/include/Eigen/*",
"/usr/local/include/Eigen/**",
"${workspaceFolder}"
],
"limitSymbolsToIncludedHeaders": true
}
}
Translation Unit Mappings:
[ /home/<my_project>/milan_opencv_test_01.cpp ]:
/home/<my_project>/milan_opencv_test_01.cpp
[ /home/<my_project>/milan_opencv_test_03.cpp ]:
/home/<my_project>/milan_opencv_test_03.cpp
Translation Unit Configurations:
[ /home/<my_project>/milan_opencv_test_01.cpp ]:
Process ID: 26578
Memory Usage: 258 MB
Compiler Path: /usr/bin/clang
Includes:
/usr/local/<blah_blah>/include/opencv4/opencv2/core
/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs
/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc
/usr/local/include/Eigen
/usr/include/c++/7
/usr/include/x86_64-linux-gnu/c++/7
/usr/include/c++/7/backward
/usr/local/include
/usr/lib/llvm-12/lib/clang/12.0.0/include
/usr/include/x86_64-linux-gnu
/usr/include
/usr/local/<blah_blah>/include/opencv4/opencv2/flann
Standard Version: c++14
IntelliSense Mode: linux-clang-x64
Other Flags:
--clang
--clang_version=120000
[ /home/<my_project>/milan_opencv_test_03.cpp ]:
Process ID: 26777
Memory Usage: 258 MB
Compiler Path: /usr/bin/clang
Includes:
/usr/local/<blah_blah>/include/opencv4/opencv2/core
/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs
/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc
/usr/local/include/Eigen
/usr/include/c++/7
/usr/include/x86_64-linux-gnu/c++/7
/usr/include/c++/7/backward
/usr/local/include
/usr/lib/llvm-12/lib/clang/12.0.0/include
/usr/include/x86_64-linux-gnu
/usr/include
/usr/local/<blah_blah>/include/opencv4/opencv2/flann
Standard Version: c++14
IntelliSense Mode: linux-clang-x64
Other Flags:
--clang
--clang_version=120000
Total Memory Usage: 516 MB
------- Workspace parsing diagnostics -------
Number of files discovered (not excluded): 33060
Screenshots
Additional context
For OpenCV
, the directory tree looks somewhat like this:
milan@my_machine:/usr/local/<blah_blah>$ tree -L 5
.
├── bin
│ ├── opencv_annotation
│ └── ...
├── include
│ └── opencv4
│ └── opencv2
│ ├── ...
│ ├── core
│ │ ├── ...
│ │ ├── core_c.h
│ │ ├── core.hpp
│ │ ├── ...
│ │ └── ...
│ ├── core.hpp
│ ├── ...
│ └── ...
├── lib
│ ├── cmake
│ │ └── opencv4
│ │ ├── OpenCVConfig.cmake
│ │ └── ...
│ ├── ...
│ ├── libopencv_core.so -> libopencv_core.so.4.2
│ ├── libopencv_core.so.4.2 -> libopencv_core.so.4.2.0
│ ├── libopencv_core.so.4.2.0
│ ├── ...
│ ├── ...
│ ├── opencv4
│ │ └── 3rdparty
│ │ ├── ...
│ │ └── ...
│ ├── python2.7
│ │ └── dist-packages
│ │ └── cv2
│ └── python3.6
│ └── dist-packages
│ └── cv2
└── share
├── licenses
│ └── opencv4
│ ├── ...
│ └── ...
└── opencv4
├── ...
│ └── ...
├── ...
└── ...
Please let me know if any further information is required to address this issue. Thanks in advance!
In the past, I had a similar issue for PCL
(Point Cloud Library): https://github.com/microsoft/vscode-cpptools/issues/5843
If you're using CMake, the recommended way to configure is via the CMake Tools extension, setting it as the configurationProvider. The usage of includePath with "**" is only intended for small, simple projects in which the ordering of includes doesn't matter and there are not files with the same name in different folders, e.g. /usr/local/<blah_blah>/include/opencv4/opencv2/flann is getting placed after the system includes, which may not work. Your screenshot shows a red squiggle on the #include <opencv2/core.hpp
line so I'm guessing an include can't be found, which is likely the cause for the other issues. Was there a reason you didn't want to use CMake Tools as the configurationProvider?
Thank you @sean-mcmanus for a quick reply!
A quick question: when you said using the CMake Tools extension as a configurationProvider
, did you mean building the codebase/project using that extension right within VSCode rather than manually running some command in the command line? Even the CMake Tools extension would talk to/run the cmake
binary, right?
Was there a reason you didn't want to use CMake Tools as the configurationProvider?
We have some scripts to build the codebase for x86
as well as for aarch64
(using cross-compiler). So, I want to stick to the pre-defined processes (at work). Also, I'm not sure how I can configure the CMake Tools extension to do the same job(s).
You don't have to use the CMake Tools extension to build -- you can build via a command line if you want. You just set "configurationProvider": "ms-vscode.cmake-tools" and run CMake: Configure
.
So, first, I updated my c_cpp_properties.json
file by adding this line:
"configurationProvider": "ms-vscode.cmake-tools"
and then ran CMake: Configure
command. It asked me to chose the proper compiler but then nothing happend. It kept showing me [main] Configuring folder: <my_project_folder>
After some trial & error, I ran CMake: Reset CMake Tools Extension State (For Troubleshooting)
.
Now, upon running CMake: Configure
, I get this:
If I select the second option: [Unspecified] Unspecified (Let CMake guess ...
, I get the following error:
[main] Configuring folder: <my_project_folder>
[proc] Executing command: /usr/local/bin/cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -S/home/<my_project>/build -B/home/<my_project>/build -G Ninja
[cmake] Not searching for unused variables given on the command line.
[cmake] CMake Error at /usr/local/share/cmake-3.19/Modules/CMakeDetermineSystem.cmake:129 (message):
[cmake] Could not find toolchain file:
[cmake] /home/<my_project>/build/../
[cmake] Call Stack (most recent call first):
[cmake] CMakeLists.txt:24 (project)
[cmake]
[cmake]
[cmake] CMake Error: CMake was unable to find a build program corresponding to "Ninja". CMAKE_MAKE_PROGRAM is not set. You probably need to select a different build tool.
[cmake] CMake Error: CMAKE_CUDA_COMPILER not set, after EnableLanguage
[cmake] -- Configuring incomplete, errors occurred!
[proc] The command: /usr/local/bin/cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -S/home/<my_project>/build -B/home/<my_project>/build -G Ninja exited with code: 1 and signal: null
If I select the third option: GCC 7.5.0 Using compilers: C = /usr/bin/gcc-7, CXX = /usr/bin/g++-7
, I get similar error:
[proc] Executing command: /usr/bin/gcc-7 -v
[main] Configuring folder: <my_project_folder>
[proc] Executing command: /usr/local/bin/cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc-7 -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++-7 -S/home/<my_project>/build -B/home/<my_project>/build -G Ninja
[cmake] Not searching for unused variables given on the command line.
[cmake] CMake Error at /usr/local/share/cmake-3.19/Modules/CMakeDetermineSystem.cmake:129 (message):
[cmake] Could not find toolchain file:
[cmake] /home/<my_project>/build/../
[cmake] Call Stack (most recent call first):
[cmake] CMakeLists.txt:24 (project)
[cmake]
[cmake]
[cmake] CMake Error: CMake was unable to find a build program corresponding to "Ninja". CMAKE_MAKE_PROGRAM is not set. You probably need to select a different build tool.
[cmake] CMake Error: CMAKE_CUDA_COMPILER not set, after EnableLanguage
[cmake] -- Configuring incomplete, errors occurred!
[proc] The command: /usr/local/bin/cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc-7 -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++-7 -S/home/<my_project>/build -B/home/<my_project>/build -G Ninja exited with code: 1 and signal: null
P.S. In my project repo, the CMakeLists.txt
file and toolchain
file are located in different directories!
Oh, looks like it may require Ninja to be installed? I don't see that in the docs at https://code.visualstudio.com/docs/cpp/CMake-linux . @bobbrow might know more. Ninja speeds up the builds (usually). I'm not sure about the toolchain file, it's possible there could be some setting you may need to set. I'm not sure yet if we should transfer this issue to the CMake Tools extension or not.
An alternative to CMake Tools is setting the compileCommands property. The other alternative is to get the includePath ordering to match what you're building with.
Running some install command like sudo apt-get install -y ninja-build
might work.
Oh, looks like it may require Ninja to be installed?
It's already installed:
$ sudo apt install ninja-build
Reading package lists... Done
Building dependency tree
Reading state information... Done
ninja-build is already the newest version (1.8.2-1).
An alternative to CMake Tools is setting the compileCommands property.
Umm, what do I have to add for this command in the c_cpp_properites.json
file?
The other alternative is to get the includePath ordering to match what you're building with.
Sorry, but I didn't quite understand. Could you please elaborate?
Without going into depth about CMake Tools (though I'd be happy to help you troubleshoot if you open an issue here: https://github.com/microsoft/vscode-cmake-tools/issues/new/choose)... the squiggles problem you have appears to be related to the fact that your include path is set to this:
"C_Cpp.default.includePath": [
"/usr/local/<blah_blah>/include/opencv4/opencv2/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/core/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgcodecs/**",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc.hpp",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc/*",
"/usr/local/<blah_blah>/include/opencv4/opencv2/imgproc/**",
"/usr/local/include/Eigen",
"/usr/local/include/Eigen/*",
"/usr/local/include/Eigen/**"
But you are including the headers with this syntax:
#include <opencv2/core.hpp>
If you are planning to include the opencv2
folder in your #include
directives, your include path should look like this:
"C_Cpp.default.includePath": [
"/usr/local/<blah_blah>/include/opencv4",
"/usr/local/include/Eigen",
"/usr/local/include/Eigen/*",
"/usr/local/include/Eigen/**"
This is because the relative path you put in the #include
directive is appended to all of the options in the includePath
you specify until a match is found. **
just means add all subfolders of this folder to the list of absolute paths that we will try. I suspect that you can simplify your paths to Eigen as well, but didn't see an example of how you are using it in this thread.
Thank you so much @bobbrow
After adding "/usr/local/<blah_blah>/include/opencv4"
in includePath
, autocompletion is working.
-
In the past, I believe there was an issue with
**
i.e. recursive search. However, now, if I replace"/usr/local/<blah_blah>/include/opencv4/opencv2/core.hpp"
,"/usr/local/<blah_blah>/include/opencv4/opencv2/core"
, ..., etc. with"/usr/local/<blah_blah>/include/opencv4/**"
, autocompletion still works. So, you would recommend using**
rather than putting all the possible paths from that directory, correct? -
On the same note, I noticed that autocompletion for
Eigen
works (it's very slow though and I think that's why I missed it in the first place). In my source code, it's included as#include <Eigen/Core>
. However, in theincludePath
, I have put"/usr/local/include/Eigen"
. Shouldn't it be just"/usr/local/include"
? Here is how thetree
in/usr/local/include/Eigen
dir looks like:
milan@my_machine:/usr/local/include/Eigen$ tree
.
├── Cholesky
├── CholmodSupport
├── CMakeLists.txt
├── Core
├── Dense
├── Eigen
├── ...
├── ...
├── src
│ ├── Cholesky
│ │ ├── ...
│ │ └── ...
│ ├── ...
│ ├── Core
│ │ ├── arch
│ │ │ ├── AltiVec
│ │ │ │ ├── ...
│ │ │ │ └── ...
│ │ │ ├── ...
│ │ │ └── ZVector
│ │ │ └── ...
│ │ ├── ...
│ │ ├── DenseBase.h
│ │ ├── DenseCoeffsBase.h
│ │ ├── DenseStorage.h
│ │ ├── ...
│ │ └── Visitor.h
│ ├── Eigenvalues
│ │ ├── ...
│ │ └── ...
│ └── ...
│ └── ...
├── ...
└── ...
40 directories, 302 files
- I noticed that the autocompletion does not work if the code is in between some preprocessor directives, auto-completion does not work. e.g.
Let say in the
cmake
, there isadd_definitions(-DSOME_FLAG)
. This line can be commented or uncommented depending on the build requirements. So, in the below code, the autocompletion works on line 3 but not on line 5!
int main(int argc, char const *argv[]) {
cv::Mat mat = cv::Mat::eye(3, 3, CV_64FC1);
std::cout << mat.
#ifdef SOME_FLAG
std::cout << mat.
#endif
return 0;
}
- Sure, I can create an issue on https://github.com/microsoft/vscode-cmake-tools/issues/new/choose However, to confirm, what other advantages I would have after being able to run the
CMake: Configure
command without any error? Would it also help with auto-completion for the code protected by preprocessor directives? (Just the above bullet point)
Thanks again!
- So, you would recommend using
**
rather than putting all the possible paths from that directory, correct?
**
is a convenience for when you don't know what the actual include path is. It is recommended when you don't know all the paths you may need to include. If you include all of your headers like this: #include <opencv2/...>
, then you don't need it. You just need the path to the folder that contains opencv2
.
- However, in the
includePath
, I have put"/usr/local/include/Eigen"
. Shouldn't it be just"/usr/local/include"
?
/usr/local/include
is likely already part of your system include path (we get this by asking your compiler), so I think you can just remove those lines for Eigen.
- I noticed that the autocompletion does not work if the code is in between some preprocessor directives, auto-completion does not work. e.g. Let say in the
cmake
, there isadd_definitions(-DSOME_FLAG)
. This line can be commented or uncommented depending on the build requirements.
If you are dependent on SOME_FLAG
being present so that IntelliSense will work in the block, you need to add it to c_cpp_properties.json
in the "defines"
array. For example, "defines": [ "SOME_FLAG" ]
- Sure, I can create an issue on https://github.com/microsoft/vscode-cmake-tools/issues/new/choose However, to confirm, what other advantages I would have after being able to run the
CMake: Configure
command without any error? Would it also help with auto-completion for the code protected by preprocessor directives? (Just the above bullet point)
If you get CMake: Configure
to work, then you don't have to configure the includePath or defines at all. CMake will tell us what they should be for every source file it knows about. And if you have preprocessor flags that change based on the configuration (e.g. DEBUG vs RELEASE), those will automatically update in IntelliSense when you change the active CMAKE_BUILD_TYPE. All you do is run the C/C++: Change Configuration Provider
command to enable CMake Tools as the provider once you get the extension working.
This issue has been closed because it needs more information and has not had recent activity.