随笔 - 137  文章 - 1  trackbacks - 0
<2018年9月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

常用链接

留言簿

随笔分类

随笔档案

收藏夹

调试技巧

搜索

  •  

最新评论

阅读排行榜

评论排行榜

1.下载并安装python-dev
    sudo apt-get install python-dev
2.下载并解压distcc:
    tar xvf distcc-3.2rc1.tar.bz2
3.配置
    cd distcc-3.2rc1/
    ./configure --prefix=/home/you/distcc-install --disable-Werror
4.安装
    make install
5.运行
    服务端运行 
        export PATH=$PATH:服务端distcc程序路径:服务器编译工具路径
        distcc --deamon --allow 192.168.0.0/16  --job 8 --user nobody
    客户端运行 :
        export PATH=$PATH:客户端distcc程序路径:客户端编译工具路径
        export DISTCC_HOSTS="server_ip1 server_ip2 ..."
        make -j8 CC=distcc
6、cmake
cd build/
CC="distcc cc" CXX="distcc g++" cmake ../cmake/





Other:
一个大型的C/C++项目的编译非常耗时。distcc和ccache这两个工具能够非常有效地压缩编译时间。它们并不是独立的编译器,而是配合 GNU GCC使用(它们的资料明确说明并不关注其他编译器)。distcc介绍中说,有人完整编译KDE项目只花费6分钟。可见其厉害!此外,它们都非常易用,保证几分钟就能上手!

这两个项目的主页:
distcc            http://distcc.samba.org/
ccache            http://ccache.samba.org/
这两个软件的安装没什么好说的,都是标准的"./configure;make;make install"。在Ubuntu上安装更简单:sudo apt-get install distcc ccache。

distcc工作原理:

GCC 编译C/C++构建一个execualble分为三个阶段:(1)C/C++预处理(gcc -E);(2)编译(gcc -c);(3)链接(ld)。其中第二阶段是效率瓶颈,尤其在指定“-O2”等优化选项时。distcc是一个编译器驱动器。它在"gcc -c"阶段把预处理输出分发到指定的服务器阵列(各服务器监听TCP端口3632)并收集结果。GNU Make和SCons的"-j"并行编译可以利用distcc来加速编译。

distcc用法:
(1)服务器端以普通用户执行“distccd --daemon --allow 10.0.0.0/16”。这使得distccd接受来自10.0网段的所有TCP连接。
注意:distcc文档中说"--allow 0.0.0.0"是接受所有连接--这已经过时,实际效果是拒绝所有连接!
(2)如果工程使用automake机制。
设置DISTCC_HOSTS环境变量。
在configure阶段执行"CC=distcc ./configure"。然后执行"make -j XX"。XX是并发任务数目上限。
(3)如果工程由GNU make管理。
设置DISTCC_HOSTS环境变量。
修改Makefile使得在原来C/C++编译器名称前加上"distcc ",例如设置CC="distcc arm-linux-gcc"。然后执行"make -j XX"。XX是并发任务数目上限。
(4)如果工程由SCons管理。
修改SConstruct使得在原来C/C++编译器名称前加上"distcc "。导出环境变量HOME和DISTCC_HOSTS到构建环境(注意SCons不会自动把系统环境变量导出到builder子进程):
 Environment(ENV={'HOME': os.environ['HOME'],'DISTCC_HOSTS': ‘localhost 10.0.0.2’},...)
然后执行"scons -j XX"。XX是并发任务数目上限。


distcc故障处理:
运行distccmon-gnome。如果在编译期间某个distcc服务器一直不活跃,可能的原因比较多。
distcc服务器的问题可能有
(1) IP地址不可达。
(2) distccd进程没有启动。
(3) distcc客户端IP不在--allow指定的范围内。
(4) distccd监听的3632端口被防火墙屏蔽。
distccd的日志记录在/var/log/messages。必要时查看一下。

客户端的问题可能有:
(1) 一些环境变量没有设置
distcc依赖的环境变量有HOME和DISTCC_HOSTS。
distcc 日志在解决问题时尤其有用。默认的错误信息输出在console。还可以设置DISTCC_VERBOSE和DISTCC_LOG环境变量以记录详细的调试信息到一日志文件(这对理解distcc工作过程也非常有用)。参考distcc和distccd联机帮助。

ccache工作原理:
ccache也是一个编译器驱动器。第一趟编译时ccache缓存了GCC的“-E”输出、编译选项以及.o文件到$HOME/.ccache。第二次编译时尽量利用缓存,必要时更新缓存。所以即使"make clean; make"也能从中获得好处。ccache是经过仔细编写的,确保了与直接使用GCC获得完全相同的输出。


ccache用法:
很简单,就像上面distcc用法提到的那样,给所有C/C++编译器名称前加上"ccache "即可。
ccache还可以把distcc作为后台的编译器。编译器设置为"ccache distcc "+原编译器即可。

从我经历的两个项目来看,单独使用ccache或distcc(除localhost外只用1台distcc服务器)效果比较显著。但是联合使用distcc和ccache的效果就和仅使用distcc差不多。个人倾向于只使用distcc,多加几台distcc服务器。


用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 。distcc支持的编译器必须可以预编译,也就是常用的gcc -E这样的选项。

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

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



posted on 2018-09-08 20:56 长戟十三千 阅读(4260) 评论(0)  编辑 收藏 引用 所属分类: 编程技巧随笔

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理