--- title: "C 与 C++" description: "基于 clangd 的代码智能,CMake 与 Makefile 运行配置,单文件运行,以及通过 lldb-dap、CodeLLDB 或 GDB 进行原生调试。" --- OpenIDEA 通过 [clangd](https://clangd.llvm.org) 支持 C、C++、Objective-C 和 Objective-C++。语法高亮、折叠和结构视图无需任何配置即可使用;补全、导航、诊断和重构由 clangd 提供,效果取决于 clangd 能否拿到正确的编译参数。其他语言见[语言支持总览](/zh/languages/index)。 | 语言 | 扩展名 | 语言服务器 | 默认调试器 | | ------------- | ----------------------------------------------------------------------------------------------------- | ---------- | ---------- | | C | `.c`、`.h` | clangd | lldb-dap | | C++ | `.cpp`、`.cc`、`.cxx`、`.c++`、`.hpp`、`.hh`、`.hxx`、`.h++`、`.ipp`、`.tpp`、`.inl`、`.ixx`、`.cppm` | clangd | lldb-dap | | Objective-C | `.m` | clangd | lldb-dap | | Objective-C++ | `.mm` | clangd | lldb-dap | `.h` 文件默认按 C 打开。如果希望头文件按 C++ 处理,在 **设置 › 编辑器 › 文件类型** 中修改关联。 ## 语言服务器 C 和 C++ 的 clangd 以 `--background-index --header-insertion=never` 启动:在后台为整个项目建立索引,并且不会自行插入 `#include`。 clangd 从当前文件向上查找以下文件来确定工作区根目录:`compile_commands.json`、`compile_flags.txt`、`.clangd`、`CMakeLists.txt`、`meson.build`、`Makefile`。Objective-C 和 Objective-C++ 只认 `compile_commands.json`、`compile_flags.txt` 和 `.clangd`。 ### 编译参数 clangd 需要知道每个文件的编译参数,否则只能猜测,常见的表现是误报找不到头文件或宏未定义。可以提供以下任一文件: - **`compile_commands.json`**:编译数据库。打开 `CMAKE_EXPORT_COMPILE_COMMANDS` 后 CMake 会把它写到构建目录中,OpenIDEA 生成的 CMake 配置总是带上 `-DCMAKE_EXPORT_COMPILE_COMMANDS=ON`(见下文“CMake”一节)。基于 Make 的项目可以用 Bear 等工具生成。 - **`compile_flags.txt`**:每行一个参数,对所有文件生效,适合小项目。 - **`.clangd`**:clangd 自己的配置文件,例如用 `CompilationDatabase` 指向某个构建目录。 clangd 会在文件的各级父目录以及这些目录下的 `build/` 子目录里查找 `compile_commands.json`。如果构建目录叫别的名字(例如 CMake 配置生成的 `cmake-build-debug`),在项目根目录添加一个 `.clangd`,写上 `CompileFlags: { CompilationDatabase: cmake-build-debug }`,或者把该文件复制或链接到项目根目录。 ### Apple 自带的 clangd Xcode 和 Command Line Tools 自带的 `clangd` 不运行 clang-tidy。如果项目里有 `.clang-tidy`,而 IDE 正在使用 Apple 的 clangd,会弹出提示并提供 **安装** 按钮,改装 LLVM 版本的 clangd。 ## 环境配置 缺少 clangd 时,打开 C/C++ 文件会弹出“clangd 未安装”的通知,点 **安装** 即可。也可以在 **设置 › 语言和框架 › 语言服务器** 中安装。 | 工具 | 安装方式 | 说明 | | -------- | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | | clangd | 从 `clangd/clangd` 的 GitHub Release 下载到 IDE 自己的工具目录 | 提供 macOS、Linux x64 和 Windows x64 的预编译包。其他平台请自行安装(例如 `apt install clangd`)。 | | CodeLLDB | 从 `vadimcn/codelldb` 的 GitHub Release 下载 | 可选,见下文“调试”一节。 | | lldb-dap | IDE 不负责安装 | 随 LLVM 提供(`brew install llvm`)。在 macOS 上 IDE 还会通过 `xcrun -f lldb-dap` 找到 Xcode 自带的版本。 | | GDB | IDE 不负责安装 | 需要 GDB 14 或更高版本。 | `PATH` 上已有的 clangd 或调试器会直接使用。如需指定某个可执行文件,在 **设置 › 语言和框架 › 语言服务器** 中该工具的页面里选择。 编译器不由 IDE 管理。单文件运行时,C 依次在 `PATH` 上查找 `clang`、`gcc`、`cc`,C++ 查找 `clang++`、`g++`、`c++`。 ## 构建、运行与测试 ### CMake 对每个包含 `CMakeLists.txt` 的项目,OpenIDEA 会生成以下运行配置: - **CMake Configure**:`cmake -S . -B <构建目录> -DCMAKE_EXPORT_COMPILE_COMMANDS=ON`(新构建目录还会加上 `-DCMAKE_BUILD_TYPE=Debug`)。 - **CMake Build**:`cmake --build <构建目录>`,构建目录尚未配置时会先执行配置步骤。 - **CTest**:先构建,再执行 `ctest --test-dir <构建目录> --output-on-failure`。 - **Build <目标>**,以及每个可执行目标各一个运行配置。运行目标前会先构建它。 可执行目标来自 CMake 的 File API,因此要在第一次配置之后才会出现。嵌套的 CMake 项目(例如一个文件夹里放了多个仓库)各自生成一套配置。 没有配置 CMake 配置文件时,IDE 使用项目中所有含 `CMakeCache.txt` 的子目录;一个都没有时使用 `build/`。 #### CMake 配置 如果想自己控制构建目录,在 **设置 › 构建、执行、部署 › CMake** 中添加配置(界面上叫“CMake 配置”)。每个配置包含: | 字段 | 含义 | | ---------- | --------------------------------------------------------------------------------------------------------------------------------- | | 名称 | 显示在运行配置名称后面。 | | 构建类型 | `Debug`、`Release`、`RelWithDebInfo` 或 `MinSizeRel`(作为 `CMAKE_BUILD_TYPE` 传入)。 | | 生成器 | 可选的 `-G` 参数,例如 `Ninja`、`Unix Makefiles`、`Ninja Multi-Config`、`Visual Studio 17 2022`、`Xcode`。留空使用 CMake 默认值。 | | CMake 参数 | 配置步骤的额外参数。 | | 构建目录 | 留空表示 `cmake-build-<构建类型>`,例如 `cmake-build-debug`。 | | 构建参数 | `cmake --build` 的额外参数。 | | 环境变量 | 配置、构建、测试和运行时都会设置。 | 一旦添加了配置,就只使用这些配置。修改已有构建目录的生成器后,下次配置时会清掉它的 CMake 缓存。 ### Makefile `Makefile`、`makefile` 或 `GNUmakefile` 中的每个目标都会生成一个 `make <目标>` 配置,其中 `test` 和 `check` 目标标记为测试。 ### 单个文件 带 `main` 函数的 C/C++ 文件不需要构建系统也能运行:使用 **运行上下文配置**(`⌃⇧R` / `Ctrl+Shift+F10`)或 **调试上下文配置**(macOS 上为 `⌃⇧D`)。IDE 会带调试信息(`-g`,C++ 另加 `-std=c++17`)把文件编译到临时目录再运行。 通用用法见[运行配置](/zh/guide/run)和[测试](/zh/guide/testing)。 ## 调试 调试通过 DAP 适配器完成。C 和 C++ 配置默认使用 **lldb-dap**,如需更换,打开运行配置修改 **调试适配器**: - **lldb-dap (C, C++, Swift)**:LLVM 提供的适配器,默认选项。IDE 不负责安装。 - **CodeLLDB (Rust, C, C++)**:IDE 可以安装;开始调试时如果缺失,会弹出通知提供安装。 - **GDB(C、C++)**:GDB 自带的 DAP 模式(`gdb -i dap`),需要 GDB 14 或更高版本,版本过低会提示并拒绝启动。 **附加到进程…** 也会列出原生进程。已安装 CodeLLDB 时用它附加,否则用 lldb-dap。 断点、单步和变量视图等内容见[调试](/zh/guide/debugging)。 ## Arduino `.ino` 草图使用 Arduino Language Server,它为 clangd 提供 Arduino 生成的编译上下文。IDE 不负责安装:请安装 Arduino IDE 2(其中包含 Arduino Language Server、Arduino CLI 和 clangd)以及对应开发板的核心。OpenIDEA 会在 `PATH` 或 Arduino IDE 2 的安装目录中查找这些工具。 如需覆盖路径,可以在 **设置 › 语言和框架 › 语言服务器** 中设置,或在 `settings.toml` 中设置 `languages.arduino.cli`、`languages.arduino.clangd`、`languages.arduino.languageServer` 和 `languages.arduino.cliConfig`。开发板 FQBN 写在 `sketch.yaml` 或 `languages.arduino.fqbn` 中。草图旁边的普通 `.cpp` 文件仍由 clangd 处理。 目前没有 Arduino 的上传或串口监视器功能。 ## 已知限制 - C/C++ 代码智能的质量取决于 clangd 拿到的编译参数。没有 `compile_commands.json` 或 `compile_flags.txt` 时会有误报。 - IDE 不会为 Make、Meson 等构建系统生成编译数据库。 - CTest 作为一个整体配置运行,只显示控制台输出,不会在测试树中列出单个测试。 - 没有针对 C/C++ 测试框架(GoogleTest、Catch2 等)的行号栏运行图标。 - lldb-dap 和 GDB 不由 IDE 安装。