最近接手的一个 Linux C++ 项目,编译速度把我折腾得怀疑人生。
—— 源码编译经过优化,全编译时间硬是从 半个小时 缩短到 3 分钟
!!!(OMG,此处省略一万字…)
划重点,三板斧:
1. 优化手段
手段 | 描述 |
---|---|
并行编译 | make -j N 是 make 工具中用来并行编译的一个选项,-j 参数后面跟的是并行任务的数量 N,这表示你希望 make 在编译过程中启动多少个并行的编译进程。 |
ccache | 编译缓存工具,通过缓存编译过程中的中间结果和元数据,避免对相同代码的重复编译。第一次编译时,由于没有缓存,可能会稍慢;而从第二次编译开始,利用之前的缓存,编译速度大幅提升。 |
distcc | 分布式编译工具,通过将编译任务分发到多台计算机上并行处理,从而加速编译过程。其主要目的是充分利用其他机器的计算资源,提高编译效率。 |
部分文字来源:ChatGPT
2. distcc 配置
搭建 distcc 编译环境并不复杂,详细请参考: 官网,以及 官方部署文档。
distcc 是 C/S 工作模式,须要服务端和客户端进行安装配置。
以下是我的工作设备:
- 客户端 - 开发机器 - 192.168.1.122 - 12 核(逻辑核心)
- 服务端 - 远程机器 - 192.168.1.36 - 48 核(逻辑核心)
- 编译是 IO + CPU 密集型工作,最后还是得拼硬件啊 ^_^!!!
- 涉及到远程编译,得保证带宽噢!
- 客户端机器编译过程。
- 远程服务端机器编译效果。
2.1 服务端配置
- 后台启动 distcc。
1
2
3
4
5
distccd --daemon --allow 192.168.1.122 --verbose --log-file=/tmp/distcc.log
# 如果你在 192.168.1.0/24 网络中运行 distcc,
# 并希望允许该网络中的所有机器使用 distcc 编译,也可以这样运行
# distccd --daemon --allow 192.168.1.0/24 --verbose --log-file=/tmp/distcc.log
服务端默认监听 3632 端口,防火墙要支持该端口的访问。
使用过程中出现什么问题,可以通过
--log-file
对应的日志跟踪问题。
2.2 客户端配置
- 写入
~/.bashrc
配置文件。
1
2
3
4
5
6
# 配置远程主机,指定 192.168.1.36 编译,localhost 本地也参与编译。
export DISTCC_HOSTS="192.168.1.36 localhost"
# 配置输出日志路径(方便调试)
export DISTCC_LOG='/tmp/distcc.log'
# 输出详细日志 1/2/3
export DISTCC_VERBOSE=1
- 观察编译任务分布情况。
1
2
# 每秒输出一次
distccmon-text 1
- 测试。环境部署好后,写个 demo 结合
distccmon-text
命令测试一下。
1
distcc g++ -c test.cpp -o test.o
3. cmake 构建脚本
我的 C++ 项目源码通过 cmake 构建,接下来结合编译工具优化编译脚本。
-
查找工具脚本:distcc_ccache_compiler.cmake。
脚本目的是编译器编译过程中查找 ccache/distcc 工具,便于项目引入工具脚本进行编译。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 查找 ccache 和 distcc
find_program(CCACHE_PROGRAM ccache)
find_program(DISTCC_PROGRAM distcc)
# 初始化 launcher 列表
set(COMPILER_LAUNCHERS "")
# 如果找到 ccache,添加到 launcher 列表
if(CCACHE_PROGRAM)
message(STATUS "Found ccache: ${CCACHE_PROGRAM}")
list(APPEND COMPILER_LAUNCHERS "${CCACHE_PROGRAM}")
endif()
# 如果找到 distcc,添加到 launcher 列表
if(DISTCC_PROGRAM)
message(STATUS "Found distcc: ${DISTCC_PROGRAM}")
list(APPEND COMPILER_LAUNCHERS "${DISTCC_PROGRAM}")
endif()
# 如果 launcher 列表不为空,设置 CMake 的 launcher
if(COMPILER_LAUNCHERS)
message(STATUS "Using compiler launchers: ${COMPILER_LAUNCHERS}")
set(CMAKE_C_COMPILER_LAUNCHER ${COMPILER_LAUNCHERS})
set(CMAKE_CXX_COMPILER_LAUNCHER ${COMPILER_LAUNCHERS})
else()
message(WARNING "Neither ccache nor distcc found, using default compiler settings")
endif()
-
CMakeLists.txt。
在项目的编译脚本(CMakeLists.txt)中引入前面的工具脚本。
1
include(../distcc_ccache_compiler.cmake)