大概三年前,我在团队里推行 CLion 的时候,遇到阻力其实不小。用过 Visual Studio 和 Eclipse 的老同事问得最多的就是:“这玩意儿到底比 VS 强在哪?”说实话,当时我也答不出太多。真正把 CLion 用顺之后,我才慢慢明白,它和传统 C/C++ IDE 有一个很根本的区别:CLion 不是去“读取”你的工程,而是尝试“理解”你的工程。这话听起来有点玄,但理解了这一层,后面所有技巧基本都能串起来。
这篇文章主要讲我这两年真正用得上、也确实帮我省下不少时间的东西,覆盖环境配置、日常编辑、调试、嵌入式开发和几个高频问题场景。如果你正准备从 Visual Studio 或者 Keil 迁过来,或者已经用 CLion 但总觉得效率上不去,这篇应该能给你一些可以直接抄作业的内容。内容基于我个人项目的实际操作经验,参数和步骤都按常见实践来写,不会有那种“配置完反而更懵”的事。
1. 环境配置与工程模型:CLion 的地基
1.1 第一次启动:3 个配置决定了未来几年的使用体验
很多人装完 CLion 第一件事是写 Hello World,其实在此之前,有几个配置花两分钟弄好,后面会舒服很多。先说安装本身,我强烈建议用 JetBrains Toolbox 而不是单独下安装包。Toolbox 的好处不只是方便升级,更重要的是它能多版本共存,今天用 2024.1,明天想试 2024.2,随时切,遇到新版本 IDE 插件不兼容也有后悔药吃。
第一次启动后,建议先改三处。
第一处是键位方案。CLion 默认是 IntelliJ IDEA 的键位,用惯 VS 的人会觉得 Alt+Enter 之类很别扭。在 Settings -> Keymap 里直接选 Visual Studio 预设,大部分习惯能无缝迁移;从 Eclipse 转过来的就选 Eclipse 预设。很多人不知道这个设置,硬啃默认快捷键,其实没必要,工具是为人服务的。
第二处是编码。在 Settings -> Editor -> File Encodings 里,把 IDE Encoding 和 Project Encoding 都设成 UTF-8,底下的 Default encoding for properties files 也改成 UTF-8。这一步能避免掉后面一半的乱码问题,尤其是 Windows 上做跨平台项目的时候。
第三处是滚轮缩放。Settings -> Editor -> General 里勾上 Change font size with Ctrl+Mouse Wheel,演示代码或者接投影仪时不用临时去改字号,非常实用。这三个配置加在一起一分钟就搞定,但影响的是你未来几年天天面对的工具手感,值得一开始就弄好。
1.2 Toolchain 选型:MinGW、MSVC、WSL 到底怎么选
很多人第一次用 CLion 会懵,因为 CLion 不自带编译器,也不自带调试器。它更像一个“壳”,把 CMake、GCC/Clang/MSVC、GDB/LLDB 这些底层工具串起来给你一个可视化界面。所以 Toolchain 配置是第一个绕不过去的坎。
在 Windows 上,主流有三种 Toolchain。我用一张表来对比,方便你根据自己场景选:
| Toolchain | 适用场景 | 调试器 | 配置难度 |
|---|---|---|---|
| MinGW-w64 | 本地 Windows 小程序、跨平台项目 | GDB | 低,用 MSYS2 装最省事 |
| MSVC | 需要调 Windows API、对接 Visual Studio 生态 | CDB(CLion 集成) | 中,需要装 VS Build Tools |
| WSL | Linux 开发为主,目标部署在服务器/嵌入式 | GDB(远程/本地) | 中,依赖 WSL 环境 |
个人建议是:如果你做的东西最终要在 Linux 上跑,直接用 WSL Toolchain;如果只是 Windows 本地工具,MinGW 就够。MinGW 的安装我不建议去网上随便下个压缩包,正路是用 MSYS2。装好 MSYS2 后,在它的终端里执行:
pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-gdb mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-ninja装完后把 C:\msys64\ucrt64\bin 加进系统 PATH,回到 CLion 的 Settings -> Build, Execution, Deployment -> Toolchains,它一般会自动检测到 gcc/g++/gdb。检测不到就手动点文件夹图标记一下路径。这里有个小坑,装了 32 位和 64 位混用的话,CLion 可能识别到多个编译器,你最好在 Toolchain 里固定选 64 位那套,不然编译和调试器版本不一致,调试时经常出现“看不到局部变量”这种诡异问题。
1.3 工程模型:CMake 是 CLion 的灵魂
CLion 对 CMake 的支持是目前所有 IDE 里做得最深的,但这也意味着,如果你不懂 CMake,CLion 的很多高级功能你都用不上。反过来说,一旦你理解了 CMake,CLion 的索引、补全、跳转都会变得极度精准。
最基础的 CMakeLists.txt 长这样:
cmake_minimum_required(VERSION 3.20) project(my_app C CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_executable(my_app main.cpp utils.cpp)CLion 会读取这个文件,自动生成 compile_commands.json(等价结构内部使用),然后基于它做代码分析。这就是为什么别人给你一个没有 CMakeLists.txt 的源码目录,CLion 会提示“No CMakeLists.txt found”——它没法理解你的工程结构。这时候最常见的做法是自己新建一个根 CMakeLists.txt,把源文件通过 glob 或者逐个 add_executable 加进去,CLion 立刻就能识别。
还有两个概念必须搞清楚:Profile 和 Build Directory。CLion 右下角有个 CMake Profile 切换按钮,默认有 Debug 和 Release。Debug 开 -g 不带优化,Release 开 -O2 不带调试信息。很多人遇到“为什么 Release 下断点断不下来”的疑问,80% 是 Profile 没切对。Build Directory 则是构建产物目录,如果你在 CMakeLists 里硬编码了绝对路径,可能影响 CLion 自动生成的 build 目录,建议让它保持默认。
2. 日常开发效率:把 IDE 用到日常手感
2.1 导航与搜索:跳转要快,搜索要准
CLion 的日常效率核心就在导航。刚开始可能不习惯,但用熟之后,鼠标的使用频率会大幅降低。最常用的三个动作:Ctrl+点击跳转到定义,Alt+F7 查找所有引用,双击 Shift 弹出 Search Everywhere。
Search Everywhere 是很多人没有意识到的“瑞士军刀”。它能搜文件名、类名、函数名,还能搜 Action,也就是说你忘了某个设置项在哪,直接双击 Shift 输入设置名就能跳转。比如想找“File Encoding”,敲进去回车就到了,不用一层层点菜单。
再看几个容易被忽略的:Ctrl+F12 打开当前文件的符号列表,适合看一个几千行的类里有哪些成员函数;Ctrl+Shift+F 是全文搜索,带正则支持;F11 添加书签,Ctrl+F11 可以加带数字/字母的书签,按 Ctrl+数字直接跳过去。我经常在一个大项目里给关键函数打书签,比反复用搜索高效得多。
很多人不知道 CLion 支持多重剪贴板,Ctrl+Shift+V 可以弹出历史复制记录。当你连续复制了好几段代码、最后发现需要早先复制的那段时,这个功能能救命。
2.2 重构与实时模板:让 CLion 替你改代码
C/C++ 的重构在 VS 里其实比较弱,但 CLion 做得非常扎实。我日常用得最勤的是 Shift+F6 重命名。它不是简单的字符串替换,而是基于符号语义的重构:重命名一个类名,所有相关的构造、析构、文件名建议都会一起处理;重命名一个局部变量,只影响当前作用域,不会误伤同名变量。
抽取也是高频操作。选中一段代码,按 Ctrl+Alt+M 可以抽取成一个函数,Ctrl+Alt+V 抽取变量,Ctrl+Alt+C 抽取常量。这种重构对清理历史遗留代码特别有用。我接手过一个 2000 多行的函数,就是靠不断抽取,把大函数拆成十来个逻辑块,最后可读性完全不一样。CLion 的重构菜单里还有“Change Signature”和“Extract Interface/Class”,前者适合大规模改接口参数,后者适合做面向对象设计调整。
实时模板是另一个被低估的功能。Settings -> Editor -> Live Templates 里可以自定义,比如我常写头文件保护宏:
#ifndef ${NAME}_H #define ${NAME}_H #endif // ${NAME}_H定义一个缩写叫 vh,之后在代码里输入 vh 再按 Tab,直接展开。配合变量表达式,CLion 还能自动填充文件名为宏名。这个能力在写新模块时特别香,能省掉大量重复劳动。
2.3 运行配置:代码之外的“运行参数”管理
很多初学者点右上角的绿色三角直接 Run,跑起来是没问题,但一旦需要传命令行参数、设置工作目录、配环境变量,就不知道怎么操作了。其实这些都在 Edit Configurations 里。
打开 Run/Debug Configurations 窗口,每个 CMake target 都会自动生成一个默认配置。你可以点左上角的加号,针对同一个 target 创建多个配置,比如一个带 -v 详细日志,一个不带;一个用 test.conf,一个用 prod.conf。Work Directory 设置也很关键,如果你的程序要读相对路径下的配置文件,工作目录不对就会莫名其妙找不到文件。
这里分享一个经验:如果你同时调试服务端和客户端,或者同时跑多个程序,记得把配置里的 Allow parallel run 勾上。否则 CLion 每次会提醒你“已经有进程在运行”,打断调试节奏。同一份代码,不同配置对应不同启动参数,这是平时最实用的技巧之一。
3. 调试实践:从同一项目多目标到嵌入式板子
3.1 同一项目多目标调试:一个工程里跑多个程序
“CLion 调试同一项目多个目标程序”是我被问过很多次的问题。典型场景是:一个 CMake 工程里既有服务端又有客户端,或者有几个独立的小工具,你希望分别启动它们,然后在各自的进程里打断点、看变量。
先看 CMake 侧怎么做:
add_executable(server server.cpp common.cpp) add_executable(client client.cpp common.cpp)这样定义之后,CLion 会在 Run/Debug Configurations 里自动生成两个 target。接下来我在配置列表里分别选中 server 和 client,把 Allow parallel run 都勾上。启动时先 Debug server,再回到配置列表选 Debug client,CLion 会保持第一个调试会话,同时开启第二个。在 Debug 工具窗口的会话下拉框(左上角)里,可以在多个调试进程之间切换,每个进程有独立的断点、变量表和调用栈。
如果你需要调试的是同一个程序的多开场景,比如多个 worker 进程,那就在同一个 target 上新建多个配置,每个配置传不同参数,同样勾选并行运行。CLion 的调试器是多会话隔离的,断点默认只作用于当前会话,不会互相干扰。在服务端/客户端联调的时候,两个进程都能下断点,找线上问题比之前只用 printf 肉眼比对日志高效太多。
3.2 条件断点、数据断点与异常断点
调试不是只有 F8 和 F9。右键一个断点,你会看到一堆选项。
条件断点是最常用的。在断点右键弹窗里写 i == 100,只有当变量 i 等于 100 时才中断。写进循环里分析特定数据、或者排查第 N 次调用出错时,这个东西省时省力。条件里还能用函数调用,比如 strlen(name) > 10,不过注意 GDB 环境下条件表达式性能会受影响,循环体特别大时要谨慎。
日志断点我称它是“不需要打断点的 printf”。在断点设置里勾上 Log evaluated expression,输入某个变量,运行时不中断,但每次命中都会往 Console 输出一行。这样不用改代码加日志,也不用反复编译。逻辑复杂、又不想污染源码的场景,日志断点和条件断点组合使用,效果比传统调试好很多。
数据断点的英文叫 Data Breakpoint,在很多调试器里也叫 Watchpoint。它的作用是监控某个内存地址或者变量,当值被修改时触发中断。排查“谁动了我的全局变量”这种问题,数据断点是唯一的正解。在 Variables 面板里右键变量,选择 Add to Watch / Breakpoint,CLion 会记录当前地址,并在写入时停下来,调用栈直接告诉你凶手是谁。
异常断点在 CLion 的 Breakpoints 对话框里,可以针对 C++ exception 添加断点。这个在排查崩溃问题特别有用。比如一段代码抛了 std::bad_alloc 或者别的什么,普通断点很难定位到抛掷点,异常断点直接把程序停在异常抛出的地方,你自己再顺着调用栈找 root cause 就行。
3.3 嵌入式调试:CLion + STM32 + OpenOCD
CLion 做嵌入式开发,已经不只是“能用”的程度。如果你用 STM32CubeMX 生成工程,CubeMX 从 1.6 版本开始可以直接把工程生成成 CMake 格式。在 CubeMX 的 Project Manager -> Project -> Toolchain 下拉里选 CMake,然后生成。这样出来的目录里有完整的 CMakeLists.txt,Clion 直接打开文件夹即可。
接着配置工具链。在 Settings -> Toolchains 里新增一个,使用 arm-none-eabi-gcc 编译器,路径指向你安装 ARM 工具链的 bin 目录。这个工具链在很多发行版里可以直接装:Ubuntu 下 apt install gcc-arm-none-eabi,Windows 下用 xPack 或者 ARM 官方包。
调试配置选 OpenOCD。下载并安装 OpenOCD 后,Debug Configuration 里选择 Embedded GDB Server,再选 OpenOCD,设置 configuration file 路径。以 STM32F103 为例,配置文件一般指向:
interface/stlink.cfg target/stm32f1x.cfg连接 ST-Link 和开发板后,点 Debug,OpenOCD 会通过 GDB 和 arm-none-eabi-gdb 配合,CLion 里可以直接下断点、看外设寄存器。串口日志可以一边调试一边在串口助手里看。CLion 对嵌入式调试最大的优势是图形化地显示寄存器和外设状态,不用像命令行 GDB 那样敲命令。
我自己做 STM32 项目时还发现一个小技巧:把 OpenOCD 的启动命令直接写在 CMake 的 custom target 里,这样不需要额外开终端烧录,CLion 的 Run 面板里就能一键下载程序:
add_custom_target(flash COMMAND openocd -f interface/stlink.cfg -f target/stm32f1x.cfg -c "program build/my_app.elf verify reset exit" DEPENDS my_app )4. 高频问题排查:乱码、SLN 与 JNI
4.1 中文输出乱码的根治方案
CLion 在 Windows 上的中文乱码,基本是两个根源:一是源码文件编码和编译器/终端不一致,二是 Windows 控制台的代码页问题。
先说源码文件。如果你打开一个来自 Windows 老项目的 .c/.cpp 文件,发现中文注释全是乱码,那大概率文件本身是 GBK/GB2312 编码。这时候不要急着全局改编码,先右键文件 -> File Properties -> File Encoding,把单个文件临时切成 GBK 预览,确认能正常显示后,再用 Convert Encoding 转成 UTF-8。如果你希望以后默认都用 UTF-8,就回到 1.1 节提到的 File Encodings 三处设置统一改。
再说到运行时的中文输出。程序编译出来在 CLion 的 Run 窗口里显示 ??????,或者更常见的“烫烫烫”这类乱码,多半是因为 Windows 控制台默认代码页是 936(GBK),而你的源码和程序按 UTF-8 输出。几个修复手段可以组合使用:
- Windows 10/11 设置 -> 时间和语言 -> 语言和区域 -> 管理语言设置 -> 更改系统区域设置,勾选“Beta: 使用 Unicode UTF-8 提供全球语言支持”,重启。这个方案最彻底,缺点是某些老软件会受影响。
- 在 CLion 的 Run/Debug Configuration 里把 Console 设置里的 Default encoding 改成 UTF-8。
- 在 CMakeLists.txt 里给编译器加参数,比如 GCC 的
-finput-charset=UTF-8 -fexec-charset=UTF-8,这样即使源码是 GBK 也能编出 UTF-8 可执行文件,但注意这只保证程序内部字符串正确,终端还是得有 UTF-8 能力。不想改动全局,也可以把普通项目里加一行:
add_compile_options(-finput-charset=UTF-8 -fexec-charset=UTF-8)我个人的最终方案是:所有源码统一 UTF-8,系统开启 UTF-8 Beta,CLion 编码设置三处全 UTF-8。这样再也不出现中文相关的幺蛾子。
4.2 直接打开 .sln 工程要注意什么
如果你拿到一个 Visual Studio 的 .sln 工程,又不想那么快折腾迁移,CLion 从 2023.1 开始支持直接打开 .sln 文件。它内部会把 MSBuild 的结构通过 CMake 桥接转换成 CLion 能识别的工程模型,然后在你的磁盘上生成一个 CMakeLists.txt 附带文件。
直接在 File -> Open 选中 .sln 文件后,CLion 会先问你 Toolchain。此时 Windows 上建议选 MSVC 工具链,因为很多 .vcxproj 里依赖了 MSVC 特有的编译选项,用 MinGW 可能编译不过。项目打开后,不一定 100% 等价于 VS 里的构建行为,特别是那些涉及自定义 MSBuild Target、Pre/Post Build Step、或者用了 vcpkg 集成的复杂工程,在 CLion 里可能报“unknown compiler option”或者库找不到。
所以如果你的目标只是临时看看代码、做点跨平台小改动,用 CLion 打开 .sln 没问题;但如果要长期维护,我还是推荐把工程迁移成 CMake。迁移成本没有想象中那么高,核心就是列出源文件、加 include 目录、加链接库。遇到第三方库就用 find_package 或者直接写路径。迁移完你会发现 CMake 在 Linux、Windows、macOS 上都能用,团队协作也方便。
4.3 在 CLion 中搭建 JNI 环境
JNI 场景我是在做一个音频处理工具时遇到:算法部分用 C 写,UI 用 Java 调。CLion 配置 JNI 其实不难,核心是两步:让编译器找到 JNI 头文件,然后把你实现的动态库输出到 Java 能加载的位置。
JNI 的头文件路径取决于你的 JDK 安装。典型的路径是:
${JAVA_HOME}/include/jni.h ${JAVA_HOME}/include/linux/jni_md.h // Linux ${JAVA_HOME}/include/win32/jni_md.h // Windows在 CMakeLists.txt 里用一个变量指到 JDK 根目录,然后:
set(JAVA_HOME "C:/Program Files/Java/jdk-17") include_directories( ${JAVA_HOME}/include ${JAVA_HOME}/include/win32 ) add_library(native_audio SHARED native_audio.c)Java 侧的流程是写一个声明了 native 方法的类,然后用 javac 的 -h 参数生成头文件:
javac -h . com/example/AudioProcessor.java它会生成一个 com_example_AudioProcessor.h,里面声明了对应的 JNIEXPORT 函数。把这个函数实现填好,编译出 native_audio.dll(Windows)或 libnative_audio.so(Linux),最后在 Java 代码里:
System.loadLibrary("native_audio");JNI 调试在 CLion 里也能做:Java 侧跑起来后,CLion 里用 Attach to Process 附加到 Java 进程,然后在 C 代码里下断点,IDE 一样能停下来看局部变量。这一套配好后,JNI 开发的效率比用 javac 编译、再用 System.out.println 排查高很多。
5. 插件市场与工程扩展
5.1 插件商店搜不到 Continue?手动安装
最近总有朋友问,在 CLion 的插件商店里搜不到 Continue 插件。这不一定是你网络的问题,更多时候是插件市场在不同地区、不同 IDE 版本下的可见性不一致,或者插件自身还没适配你的 CLion 版本。
遇到这种情况,最靠谱的办法是手动安装。到 Continue 的 GitHub Releases 页面下载对应 CLion 版本的插件 zip 包,然后在 CLion 的设置里打开 Plugins,点右上角的齿轮图标,选择 Install Plugin from Disk,选中 zip 文件,重启 IDE 即可。手动安装的插件会在已安装列表里出现,后续也可以像普通插件一样卸载。
这个思路其实适用于所有商店搜不到的插件:Rainbow Brackets、GitToolBox 这类知名插件一般商店都有,但一些小众插件或者测试版,商店没有时,手动安装是唯一路径。装插件前先看它支持哪些 IDEs 和版本号,装上之后如果发现 IDE 卡顿明显,考虑禁用而不是死扛。
5.2 值得保留的几个插件与取舍
插件不是越多越好。我实际体验过装了十几个插件的状态,CLion 启动直接慢了半分钟,索引也变慢。最后留下的核心组合是:
- Rainbow Brackets:括号配对率提高很多,特别适合表达式复杂的 C++ 代码,不同层级括号颜色不同,眼睛不累了。
- Native Terminal:在 IDE 里直接开系统终端,做交互式命令比内置终端顺滑一点,尤其 macOS 上习惯 iTerm 的人会喜欢。
- GitToolBox:状态栏显示当前分支、提交时间、文件修改状态,对日常 Git 工作流很有帮助。
- SonarLint(可选):能提示潜在的代码问题,适合质量要求高的项目,不过它会在大型代码库上增加 CPU 占用,看需求取舍。
这里我多提醒一句:CLion 内置的 Git、反编译查看器、数据库插件其实已经很能打了,先熟悉内置功能,再决定装不装插件。否则很容易陷入“装了不用,卸载又怕错过”的怪圈。
5.3 代码规范与团队协作:clang-format / clang-tidy
如果你的团队对代码风格有要求,CLion 内置的 clang-format 支持是加分项。Settings -> Tools -> ClangFormat 里可以选在保存时自动格式化,配合 .clang-format 配置文件,团队所有人统一风格,diff 干净很多。对大规模 C/C++ 项目来说,这一条配合 CI 的格式检查,能省掉无数代码评审里的“这行缩进不对”问题。
clang-tidy 则是比编译器警告更深一层的静态检查。CLion 的 Inspections 里内置了大量 clang-tidy 规则,比如某些可能越界访问的模式、未定义行为、异常安全问题等,开了之后写代码时会有实时提示。我一般在项目目录放一个 .clang-tidy 文件,设定团队相关的检查项,避免默认规则太多导致噪音过大。在较老的代码库上启用时,建议先跑一遍并看警告密度,再决定纠不纠,避免一次改动范围爆炸。
最后再分享一点个人体会
我经常跟人说,CLion 最大的学习成本其实不是快捷键,而是理解它背后的“构建即索引”思路。CLion 的代码补全和跳转依赖 CMake 生成的信息,所以你真正要懂的是 CMake、是 GDB、是你项目本身的构建方式,IDE 只是把这些底层工具变成可视化的交互层。这个观念转过来之后,CLion 大部分功能几乎不用学就通了。
另一个体会是,不要追求一次把所有设置都配好。你可以在项目进展中慢慢调整 Toolchain、编码、Format 模板,CLion 绝大多数设置都是热生效的。工具是给人用的,别让配置本身变成负担。
如果你按照上面几节把基础打好,再逐步把多目标调试、JNI、嵌入式流程串起来,你会发现 CLion 能覆盖的场景比你最初想象的宽得多。如果这篇文章里有哪些地方你实际跑下来和我不一样,欢迎按你自己的环境再调,毕竟每个人的项目都不一样。