LoginSignup
8
8

More than 1 year has passed since last update.

c/cpp言語 + Visual Studio CodeのIntelliSense(include path)設定をcmakeから自動生成する

Last updated at Posted at 2022-04-15

解決したいこと

  • VSCodeでc/cpp言語の開発をしているとき、外部ライブラリやヘッダファイルの場所が正しく設定されていないと、関数定義へのジャンプなどが使えない
  • .vsode/c_cpp_properties.jsonincludePath にパス設定をすることで解決できるが、いちいち調べて設定するのが面倒くさい
  • 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コマンドを実行する必要がある
  • 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
                }
            ]
        }

    ]
}
8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8