解決したいこと
- VSCodeでc/cpp言語の開発をしているとき、外部ライブラリやヘッダファイルの場所が正しく設定されていないと、関数定義へのジャンプなどが使えない
-
.vsode/c_cpp_properties.json
のincludePath
にパス設定をすることで解決できるが、いちいち調べて設定するのが面倒くさい - cmakeをしたらパスは分かっているはずなので、cmakeにその設定をしてもらう
- 参考: https://stackoverflow.com/questions/36122358/visual-studio-code-c-include-path/50360945#50360945
解決方法
- CMakeLists.txtに
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
を追加する- これによって、build先に
compile_commands.json
が生成される - 注意: なので、cmakeファイルを一通り書いたら、コードを書く前に一度cmakeコマンドを実行する必要がある
- これによって、build先に
-
c_cpp_properties.json
に以下を追加し、上記設定を読み込む"compileCommands": "${workspaceFolder}/build/compile_commands.json"
↓以下、具体例↓
前提
- Ubuntu, g++, gdb, cmake
- VSCode
- ms-vscode.cpptools
- 例題
- main関数から外部ライブラリとしてOpenCVを使う例を考える
構成
├── .vscode/
│ ├── c_cpp_properties.json
│ └── launch.json
├── CMakeLists.txt
├── main.cpp
└── build/
コード
main.cpp
- 以下の例だと、OpenCVを使用しているが、このままだとヘッダファイルも開けないし、cv::xxx関数の定義へのジャンプもできない
- また、include文の下に波線のエラーが出る
main.cpp
#include <cstdio>
#include <opencv2/opencv.hpp>
int main(int argc, char* argv[])
{
printf("Start\n");
int a = 123;
printf("a = %d\n", a);
cv::Mat image = cv::Mat::zeros(32, 32, CV_8UC3);
cv::imshow("image", image);
cv::waitKey(-1);
printf("Finish\n");
return 0;
}
CMakeLists.txt
- cmake内でOpenCVの設定はしているのでビルドは通る
-
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
によってその設定をjsonで出力させているのがポイント - この設定は、topのCMakeLists.txt内で1つあればOKっぽい。例えば、子モジュールをadd_subdirectoryして、その子モジュールが他のライブラリに依存していたら、そこへの参照設定もちゃんと出力してくれた
CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_FLAGS "-std=c++14 -Wall")
set(CMAKE_CXX_FLAGS_DEBUG "-g3 -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
set(ProjectName "main")
project(${ProjectName})
add_executable(${ProjectName} main.cpp)
find_package(OpenCV REQUIRED)
target_include_directories(${ProjectName} PUBLIC ${OpenCV_INCLUDE_DIRS})
target_link_libraries(${ProjectName} ${OpenCV_LIBS})
c_cpp_properties.json
- 先ほど出力した
compile_commands.json
を読み込む。必要に応じてjsonファイルのパスは変更する - この状態で、ターミナルからcmakeを実行すると、
compile_commands.json
が生成され、インテリセンスが正しく設定される
c_cpp_properties.json
{
"configurations": [
{
"name": "Ubuntu",
"includePath": [
"${workspaceFolder}/**"
],
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
}
],
"version": 4
}
おまけ: launch.json
- 本題とは関係ないが、gdbデバッグするための設定
-
cmake .. -DCMAKE_BUILD_TYPE=Debug
,make
, F5
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/main",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}