在 Ubuntu 上写 C++,很多问题并不出在语法本身,而是出在编译参数怎么配:标准版本选哪个、警告要不要全开、优化和调试能不能同时保留、项目一变大又该不该换构建工具。本文按常见开发路径把命令行、Makefile、CMake 和 IDE 配置串起来,既给出可直接使用的示例,也说明每种方案分别适合什么项目规模,方便你快速做选择。
命令行下,先把最常用的编译选项配明白
如果只是单文件程序、练习代码,或者想快速验证一段逻辑,直接用 g++ 编译最省事。在 Ubuntu 上,这也是最直接、最容易排错的方式。

实际使用时,最常见的编译选项主要有这几类:
- 标准版本:
-std=c++11、-std=c++17、-std=c++20,用于指定代码遵循的 C++ 标准,决定你能使用哪些语言特性; - 警告开关:
-Wall和-Wextra,前者启用常见警告,后者补充更多额外警告,很多隐藏问题往往就是靠这两项提前发现; - 调试信息:
-g,生成调试符号,后续配合gdb调试时会用到; - 优化等级:
-O2和-O3最常见。-O2通常更均衡,适合作为默认选择;-O3优化更激进,但编译时间通常更长; - 链接库:比如
-lm链接数学库,-lpthread或-pthread用于线程支持。
一个常见示例是,把 main.cpp 编译成 myapp,同时启用 C++17、常见警告、优化和调试信息:
g++ -std=c++17 -Wall -Wextra -O2 -g main.cpp -o myapp
如果程序里用到了数学函数,例如 sqrt,还要显式链接数学库:
g++ -std=c++17 main.cpp -o myapp -lm
这类命令的优点是足够透明:每个参数都能直接看到作用,出了问题也容易快速定位。缺点也很明显,一旦源文件变多,手动维护命令就会变得麻烦。
源文件一多,用 Makefile 管住重复编译
当项目不再只有一个 .cpp 文件,继续手写长命令就容易出错。这时更合适的做法,是把编译规则写进 Makefile,让构建过程固定下来。
一个典型的 Makefile 可以这样写:
# 编译器
CXX = g++
# 编译选项(可包含警告、标准、优化等)
CXXFLAGS = -std=c++17 -Wall -Wextra -O2 -g
# 目标可执行文件名
TARGET = myapp
# 源文件列表(支持通配符)
SRCS = main.cpp utils.cpp
# 目标文件列表(自动将.cpp替换为.o)
OBJS = $(SRCS:.cpp=.o)
# 默认目标:生成可执行文件
all: $(TARGET)
# 链接目标文件生成可执行文件
$(TARGET): $(OBJS)
$(CXX) $(CXXFLAGS) -o $@ $^
# 编译单个源文件为目标文件
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
# 清理生成的文件
clean:
rm -f $(OBJS) $(TARGET)
这份配置里,几个关键变量已经把常用信息集中起来了:
CXX指定编译器,这里是g++;CXXFLAGS统一放编译选项,后面要加标准、警告、优化时只改这一处;SRCS管理源文件列表;OBJS自动把源文件映射成目标文件,省去手动维护。
日常使用时也很直接:
- 运行
make,默认执行all目标并完成编译; - 运行
make clean,清理.o文件和最终可执行文件。
Makefile 适合中小型项目,尤其适合“文件数已经不少,但还没复杂到要上完整跨平台构建系统”的阶段。它的核心价值,不只是少敲几次命令,而是让团队成员在同一套规则下编译,减少“我这边能过、你那边不过”的情况。
项目再扩大,CMake 更适合做统一构建入口
当项目需要跨平台、依赖更多第三方库,或者团队里有人在 Ubuntu 之外的环境开发时,单纯维护 Makefile 往往不够灵活。CMake 的定位,就是生成构建系统,并把工程配置从具体平台里抽离出来。

创建 CMakeLists.txt
一个常见的 CMake 配置如下:
# 最低CMake版本要求
cmake_minimum_required(VERSION 3.10)
# 项目名称
project(MyProject)
# 设置C++标准(C++17及以上需开启此选项)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 添加可执行文件(指定源文件)
add_executable(myapp main.cpp utils.cpp)
# 添加编译选项(可选,更推荐在target_compile_options中设置)
target_compile_options(myapp PRIVATE -Wall -Wextra -O2 -g)
# 链接库(如需链接第三方库,如m)
target_link_libraries(myapp PRIVATE m)
这里需要重点看几项:
cmake_minimum_required(VERSION 3.10)指定最低 CMake 版本;set(CMAKE_CXX_STANDARD 17)和set(CMAKE_CXX_STANDARD_REQUIRED ON)用来固定 C++ 标准;target_compile_options(myapp PRIVATE -Wall -Wextra -O2 -g)把警告、优化、调试选项绑定到 конкрет目标;target_link_libraries(myapp PRIVATE m)负责链接所需库,这里是数学库m。
生成构建目录并编译
为了避免把中间文件直接写进源码目录,通常会单独建一个构建目录:
# 创建构建目录(避免污染源码目录)
mkdir build
cd build
# 生成Makefile(根据系统选择生成器,Ubuntu默认为Unix Makefiles)
cmake ..
# 编译项目
make
这种“源码目录 + build 目录”分离的方式,在实际工程里很重要。它能让工程结构更干净,也更方便清理、切换构建配置或重新生成。
CMake 的优势主要体现在三点:
- 支持多平台,不必针对不同系统手动维护不同构建脚本;
- 扩展性更强,后续接入第三方库、自定义规则时更顺手;
- 更适合团队协作,工程配置更集中,也更容易被 IDE 识别。
如果项目已经进入多模块、多人协作、需要长期维护的阶段,直接把 CMake 当成统一入口,通常比继续扩展 Makefile 更省心。
习惯图形界面时,IDE 里要配对编译器和构建方式
有些开发者更依赖 IDE 的补全、跳转和调试体验,这没有问题。但 IDE 里的配置本质上仍然是在组织编译器、标准版本和构建系统,所以关键不是“点哪里”,而是要确保它和命令行配置保持一致。
CLion
- 打开项目,进入
File -> Settings -> Build, Execution, Deployment -> Toolchains,确认使用正确的编译器,比如 GCC; - 进入
CMake Settings,在CMake options中加入自定义参数,例如-DCMAKE_CXX_FLAGS="-Wall -Wextra -std=c++17"。
CLion 的核心依赖仍然是 CMake,因此只要工程的 CMakeLists.txt 维护得比较规范,IDE 里的配置通常不会太零散。
Visual Studio Code
- 安装 C++ 扩展,例如 Microsoft 的 C/C++ 扩展;
- 创建或编辑
.vscode/settings.json,补充默认编译器路径、标准版本和编译参数。
{
"C_Cpp.default.compilerPath": "/usr/bin/g++",
"C_Cpp.default.cppStandard": "c++17",
"C_Cpp.default.compilerArgs": [
"-Wall",
"-Wextra",
"-O2",
"-g"
]
}
如果项目本身是 CMake 工程,还需要配合 CMake Tools 扩展使用,IDE 才能更完整地识别和构建项目。否则,VS Code 里能看到的很多配置,只是编辑器层面的默认参数,不一定等同于真实构建过程。
换句话说,IDE 更像是编译配置的展示层。真正需要统一的,仍然是底层的 g++ 选项、Makefile 或 CMake 工程文件。
常用编译选项速查与场景选择
最后可以把常见编译参数集中看一遍,方便日后查阅:
| 选项 | 作用 |
|---|---|
-std=c++XX | 指定 C++ 标准,如 c++11、c++17、c++20 |
-Wall | 启用所有常见警告 |
-Wextra | 启用额外警告 |
-g | 生成调试信息,通常配合 gdb 使用 |
-O2 | 优化代码,兼顾性能与编译时间 |
-O3 | 更高等级优化,但可能增加编译时间 |
-I/path/to/include | 添加头文件搜索路径 |
-L/path/to/lib | 添加库文件搜索路径 |
-lname | 链接名为 libname 的库,例如 -lm |
-pthread | 添加线程支持,适用于多线程程序 |
如果只看结论,可以按项目规模做判断:
- 小型代码或临时验证:直接用命令行,最快;
- 中小型多文件项目:用 Makefile,把重复构建流程固定下来;
- 大型项目或跨平台工程:优先考虑 CMake;
- 依赖 IDE 工作流:让 IDE 配置跟随 Makefile 或 CMake,而不是单独维护一套彼此脱节的参数。
Ubuntu 下配置 C++ 编译选项,并没有唯一标准答案。更实际的思路是先把标准版本、警告、调试和优化这几类核心参数稳定下来,再根据项目规模选择命令行、Makefile 或 CMake。只要底层规则一致,后续无论切到终端还是 IDE,构建行为都更容易保持一致。







