分布式编译 -- distcc+ccache

本文分享了作者使用distcc和ccache进行分布式编译的经验。详细介绍了如何解决在ARM平台上大型项目编译耗时过长的问题,并通过修改源码适配特定编译器,最终实现了有效的分布式编译流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天写netsurf的一篇blog,顺便把之前做的的一个东西给写了,写blog真的是蛮辛苦的一件事。。。就都今天苦了吧,呵呵

用distcc,ccache是两年前,项目结束的空隙,自己拿来玩的。当时是在arm上做的一个很大的工程,当时的PC,只编UI部分就需要3个小时,这也是为什么后来我用分布式编译的原因。那个项目是c++加adobe的flash,仿iphone做一款很炫的手机,其中UI全部用flash做,效果很炫,速度就比较差了。后来,我也试过在arm9261(200MHz)上用gnash播放flash,效果确实比较一般。言归正传,还是来说下分布式编译,其实它的原理很简单,把c文件在本机预编译,然后发到其他主机进行编译,编译的后的o文件再传回本机,最后在本机进行链接。没有看过代码,猜测对于每个编译的c文件对应产生一个编译任务,下发到其他机器或本机,最终完成编译。

我们的环境是ADS1.2+cygwin,用tcc,tcpp进行编译。distcc,ccache本来是在cygwin上直接装的的,但后来在使用时发现会碰到一些问题。所以从源码编译了。distcc产生的中间文件是.i的格式,tcc无法识别该文件类型,需要修改源码。就一句话,网上可以搜到的。if(dcc_getenv_bool("DISTCC_KEEP_FILETYPE", 1)).然后,./configure; make; make install。ccache问题是一样的,无法识别.i文件,修改ccache.c,把中间文件i/ii改为c/cpp,一样的方式安装。

然后要对安装的东西进行配置,我当时的配置如下,10.19.5.0网段的主机都可以做协同编译的主机,当然ads的licence只有20个啦。此处目录设置至关重要,tcc无法识别cygwin环境,tcc -c /cygdriver/c/a.c,  tcc无法读取文件,错误码为C3052E。利用了cygwin既可以win32的路径,又可以识别posix路径。
export DISTCC_LOG='/var/log/distcc.log'
export DISTCC_HOSTS='localhost 10.19.5.0/24'
export DISTCC_VERBOSE=1
export DISTCC_SAVE_TEMPS=1
export TMPDIR=' e:/test '
export CCACHE_DIR=e:/test
export CCACHE_PREFIX=distcc
export CCACHE_LOGFILE=e:/test/ccache.log


distccd在没有设置DISTCCD_PATH时,使用系统的PATH作为搜索,和makefile里指定的不一致。设置了DISTCCD_PATH,很莫名其妙,当时是为什么。然后distccd --daemon --allow0.0.0.0/0,任何ip都可以接入,比较简单。

修改makefile,在CC,ARMCC,ARMCPP,TCPP原来的设置前,添加ccache。需要说明的是,distcc仅为编译器前端,编译器的指定需要distcc <compiler>。distcc支持的编译器必须可以预编译,也就是常用的gcc -E这样的选项。

最后的测试很简单,自己写makefile,只做".c.o:" ,然后把.o文件链接到工程中就可以了。在手机上还是可以很好的run起来的。当然验证的工作不是那么简单了,看了下反汇编的代码。一台主机编译的和分布式编译的,没有什么太大的差别,汇编稍有不同,但功能一致。

项目结束后自己玩的东西,虽然没有用于实际来提高效率,但还是学到了一些东西。

<think>嗯,用户想通过使用make -j8来加速编译过程。首先,我需要确认自己对make命令的理解是否正确。make是一个构建工具,用于自动化编译程序。-j选项后面跟的数字表示并行任务的数量,比如-j8就是同时运行8个任务。 接下来,用户可能不太清楚如何具体使用这个命令。我应该先解释基本用法,比如直接在make命令后加上-j8。然后,可能需要说明如何根据CPU核心数来调整这个数字,比如使用nproc获取核心数,再设置为两倍,这样能更高效地利用资源。 另外,用户可能不知道如何确定合适的并行任务数。这时候需要给出一些建议,比如不要超过CPU逻辑核心数的两倍,或者根据系统负载调整。可能还需要提醒他们,过多的任务可能导致内存不足,反而影响性能。 然后,考虑到用户可能在使用不同的构建系统,比如CMake,这时候需要说明如何在CMakeLists.txt中设置,或者在使用cmake命令时传递参数。这样用户在不同的项目环境中也能应用这个方法。 还有,用户可能会遇到并行编译中的问题,比如依赖关系错误导致编译失败。这时候需要建议他们在确认代码无误的情况下,先尝试单线程编译,排除并行带来的问题。同时,提到distccccache这样的工具,可以进一步帮助优化编译速度,尤其是大型项目。 最后,应该附上相关问题,帮助用户扩展知识,比如如何分析编译瓶颈、处理依赖问题、优化编译缓存等。这样用户如果有进一步的问题,也能找到方向。 需要确保回答符合之前的系统指令,使用正确的中文,数学公式用$...$,独立公式用$$...$$,但这里可能用不上数学公式。同时,引用提供的参考资料。例如,引用[1]提到开启并行编译通常足够,但可能需要使用其他工具分析每个文件的编译时间,所以可以在回答中提及使用time命令或者构建系统自带的性能分析工具。 检查是否有遗漏的要点,比如基本命令、调整任务数的方法、不同构建系统的配置、常见问题解决和相关工具。确保结构清晰,步骤明确,用户能一步步跟着操作。</think>### 如何通过`make -j8`实现并行编译加速? #### 1. **基础使用** - 在终端中直接运行以下命令,将编译任务分配到8个线程并行执行: ```bash make -j8 ``` 此命令适用于大多数基于Makefile的项目[^1]。 #### 2. **根据CPU核心数动态调整** - 若需动态适配当前CPU核心数,可使用: ```bash make -j$(nproc) ``` `nproc`命令会返回系统可用的逻辑CPU核心数(例如8核CPU返回8)。 - 经验法则:设置线程数为逻辑核心数的1.5-2倍(如8核CPU用`-j12`或`-j16`),但需注意内存限制。 #### 3. **在CMake项目中启用** - 若项目使用CMake生成Makefile,需在配置时指定: ```bash cmake -DCMAKE_BUILD_PARALLEL_LEVEL=8 .. ``` 或直接通过`-j`参数调用: ```bash cmake --build . -j8 ``` #### 4. **注意事项** - **依赖问题**:若项目存在未正确声明的依赖关系,并行编译可能导致失败。可先用`make -j1`验证单线程编译是否成功。 - **资源监控**:高并发可能引发内存不足,可通过`htop`或`free -h`监控资源使用。 - **增量编译**:首次完整编译后,后续增量编译速度提升更显著。 #### 5. **进阶工具** - **`distcc`**:分布式编译工具,跨多台机器分配编译任务。 - **`ccache`**:缓存编译结果,减少重复编译时间。 #### 示例代码(性能对比) ```bash # 单线程编译基准测试 time make -j1 # 并行编译对比 time make -j8 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值