C++ 开发手册C++

CHAPTER 07生产层 · BUILD

构建与 CMake

编译链接模型、头文件、Makefile、CMake 与库管理。把分散的源码可靠、可复现地编译成可执行与库。

开始阅读难度中级先修第一、二章约2小时
07.1

编译链接模型

C++ 构建分两步:编译(每个 .cpp → 目标文件 .o)、链接(合并目标文件与库,解析外部符号成可执行)。声明与定义分离即为此服务。

g++ -c main.cpp -o main.o        # 编译
g++ -c math.cpp -o math.o        # 编译
g++ main.o math.o -o app         # 链接
为什么分两步

分离编译让只改一个文件时只需重编它;链接阶段才把跨文件引用(函数/全局变量)绑定到一起。

07.2

头文件与守卫

头文件放声明(接口),.cpp 放定义(实现)。用 #pragma once 防止同一头文件被多次包含导致的重定义。

// math.h
#pragma once
int add(int a, int b);            // 声明
// math.cpp
#include "math.h"
int add(int a, int b) { return a + b; }  // 定义
ODR 规则

同一变量/函数(非 inline)在整个程序只能有一份定义(One Definition Rule)。实现放 .cpp 即避免多翻译单元重复定义。

07.3

Makefile 基础

Makefile 用规则描述"目标:依赖→命令",仅重制变更部分的文件,是自动化构建的传统方式。

app: main.o math.o
	g++ main.o math.o -o app
main.o: main.cpp math.h
	g++ -c main.cpp
math.o: math.cpp math.h
	g++ -c math.cpp
clean:
	rm -f *.o app
07.4

CMake 入门

CMake 是跨平台构建生成器,输出 Makefile 或 Ninja/IDE 工程。核心是 CMakeLists.txt。

cmake_minimum_required(VERSION 3.16)
project(demo)
add_executable(app main.cpp math.cpp)
cmake -S . -B build      # 生成构建系统
cmake --build build      # 编译
07.5

Target 化写法

现代 CMake 以 target 为中心:用 target_include_directories/target_link_libraries 把属性绑定到目标,而非全局变量。

add_library(math math.cpp)
target_include_directories(math PUBLIC include)
add_executable(app main.cpp)
target_link_libraries(app PRIVATE math)
PUBLIC/PRIVATE

PUBLIC 表示"我自己用、依赖我也用";PRIVATE 仅自己用;INTERFACE 仅传递。精确声明可避免泄漏依赖。

07.6

静态库

静态库(.a/.lib)在链接时把代码复制进可执行,运行期无外部依赖,体积大但部署简单。

# 用 CMake add_library(math STATIC ...)
ar rcs libmath.a math.o   # 或手动归档
07.7

动态库与链接

动态库(.so/.dll)在运行期加载,多程序共享、体积小、可热更新,但需保证运行环境能找到它。

# CMake: add_library(math SHARED ...)
g++ -shared -fPIC math.cpp -o libmath.so
# 运行时通过 LD_LIBRARY_PATH 或 rpath 找到
ABI 稳定性动态库升级需保持 ABI 兼容,否则依赖它的程序需在接口变更后重新编译。静态库则无此顾虑。

07.8

常见陷阱与 FAQ

链接报 undefined reference?

通常是"声明了但没链接对应实现/库",或 .cpp 没加入构建。检查是否把源文件加入 target、库顺序是否满足链接器需求。

头文件放定义会怎样?
被多个翻译单元包含会产生多份定义,违反 ODR,链接期报错。模板与 inline 例外(允许多份等价定义)。

静态库还是动态库?

追求零部署依赖、简单分发用静态;追求体积小、多程序共享、热更新用动态。库很大且不常变时动态库更划算。

07.9

实战练习与资源

延伸资源