自己用VSCode已经三年多了,大多数是写python程序,偶尔也写C++程序,但也不复杂,也不牵扯其他第三方库,就算牵扯第三方库,也大多是先写好CMakeLists文件,然后用标准的cmake… make流程编译和运行它。但是今天突然想用VSCode的调试功能,程序是以前写好的C++程序,涉及opencv和Qt库,然后就是各种配置、各种尝试,先后出现多种莫名奇妙的错误提示,但最后还是把它搞定了,所以记录下来,一是让自己以后忘记了还可以快速查找,二是让还在VScode上折腾C++调试的同学一些提示:
{
"version": "0.2.0",
"configurations": [
{
"name": "g++ - Build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceRoot}/test",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "test",
"miDebuggerPath": "/usr/bin/gdb"
}
]
}
此文件要注意的3个地方,第一:“program”: “${workspaceRoot}/test”,表示程序编译build后生成的文件路径和名字(此处可执行文件名为test);第二:“preLaunchTask”: “test”,这个参数即是你F5调试运行时的可执行程序,名字要跟"program"一样;第三:此生成文件名必须要跟task.json中"label"关键字的名字相同,同时最好跟"args“关键字生成的可执行文件名字相同,免得乱七八糟的各种找不到错误。
请注意其中的"label"关键字和g++命令-o生成的可执行文件名字”test“。
{
"version": "2.0.0",
"tasks": [
{
"label": "test",
"type": "shell",
"command": "g++",
"args": [
"-g",
"-std=c++11",
"${workspaceRoot}/src/*.cpp",
"-o",
"test",
"-I",
"/usr/local/include",
"-I",
"${workspaceRoot}/include",
"-I",
"/usr/local/include/opencv4",
"-I",
"/usr/local/include/opencv4/opencv2",
"-I",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include",
"-L",
"/usr/local/lib",
"-L",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/lib",
"-l",
"opencv_aruco",
"-l",
"opencv_bgsegm",
"-l",
"opencv_bioinspired",
"-l",
"opencv_calib3d",
"-l",
"opencv_ccalib",
"-l",
"opencv_core",
"-l",
"opencv_datasets",
"-l",
"opencv_dnn_objdetect",
"-l",
"opencv_dnn",
"-l",
"opencv_dpm",
"-l",
"opencv_face",
"-l",
"opencv_features2d",
"-l",
"opencv_flann",
"-l",
"opencv_freetype",
"-l",
"opencv_fuzzy",
"-l",
"opencv_hfs",
"-l",
"opencv_highgui",
"-l",
"opencv_imgcodecs",
"-l",
"opencv_img_hash",
"-l",
"opencv_imgproc",
"-l",
"opencv_line_descriptor",
"-l",
"opencv_ml",
"-l",
"opencv_objdetect",
"-l",
"opencv_optflow",
"-l",
"opencv_phase_unwrapping",
"-l",
"opencv_photo",
"-l",
"opencv_plot",
"-l",
"opencv_reg",
"-l",
"opencv_rgbd",
"-l",
"opencv_saliency",
"-l",
"opencv_shape",
"-l",
"opencv_stereo",
"-l",
"opencv_stitching",
"-l",
"opencv_structured_light",
"-l",
"opencv_superres",
"-l",
"opencv_surface_matching",
"-l",
"opencv_text",
"-l",
"opencv_tracking",
"-l",
"opencv_videoio",
"-l",
"opencv_video",
"-l",
"opencv_videostab",
"-l",
"opencv_xfeatures2d",
"-l",
"opencv_ximgproc",
"-l",
"opencv_xobjdetect",
"-l",
"opencv_xphoto",
"-l",
"icui18n",
"-l",
"icuuc",
"-l",
"icudata"
],
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
这个文件用来配置第三方库的头文件查找目录,这里我用到了opencv和Qt5.
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/local/include/opencv4/opencv2",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include/QtCore",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include/QtGui",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include/QtQml",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include/QtQuick",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include/QtWidgets"
],
"browse": {
"path": [
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include/QtCore",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include/QtGui",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include/QtQml",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include/QtQuick",
"/home/jiaken2660/Qt5.9.9/5.9.9/gcc_64/include/QtWidgets",
"${workspaceRoot}"
]
},
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu11",
"cppStandard": "c++11",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
此处假设opencv安装是没有问题的,因为我用cmake和make生成程序是没问题的,这里主要是没有正确链接到opencv库,请看task.json的配置方式,此处跟写CMakeLists文件有点不一样,前面不需要lib打头,后面也不需要.so结尾。
undefined reference to `cv::imread(std::string const&, int)'
undefined reference to `cv::noArray()'
undefined reference to `cv::_OutputArray::_OutputArray(cv::Mat&)'
undefined reference to `cv::_InputArray::_InputArray(cv::Mat const&)'
undefined reference to `cv::imwrite(std::string const&, cv::_InputArray const&, std::vector<int, std::allocator<int> > const&)'
undefined reference to `cv::_InputArray::_InputArray(cv::Mat const&)'
undefined reference to `cv::imshow(std::string const&, cv::_InputArray const&)'
undefined reference to `cv::waitKey(int)'
此处提示有点看不懂,初看是libQt5Core.so.5链接不对,所以始终没找到解决的方式,后来就想先把warning解决吧,于是把libicui18n.so.56、libicuuc.so.56和libicudata.so.56作为链接库加到task.json文件中,问题解决。
/usr/bin/ld: warning: libicui18n.so.56, needed by //opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libicuuc.so.56, needed by //opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libicudata.so.56, needed by //opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5, not found (try using -rpath or -rpath-link)
//opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5:对‘u_strToLower_56’未定义的引用
//opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5:对‘ucnv_getStandardName_56’未定义的引用
//opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5:对‘ucnv_getAlias_56’未定义的引用
//opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5:对‘uenum_next_56’未定义的引用
//opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5:对‘u_strToUpper_56’未定义的引用
//opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5:对‘ucnv_setSubstChars_56’未定义的引用
//opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5:对‘ucal_getTimeZoneDisplayName_56’未定义的引用
//opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5:对‘ucnv_fromUnicode_56’未定义的引用
//opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5:对‘u_errorName_56’未定义的引用
//opt/Qt5.10.0/5.10.0/gcc_64/lib/libQt5Core.so.5:对‘uenum_close_56’未定义的引用
...
要想没有其他错误,请看第一节三个文件的配置,尤其是文件名必须一致。