编译一个软件要花多长时间?

不知道现在世界上有多少人正坐在电脑前,等待着编译结束。如果把所有的软件按照规模来排名的话,编译器至少应该在最大那一批的角落里,想想自己动手编译 GNU 工具链需要的时间吧!难怪有人抗议说 gcc 应该附带音乐以便编译时候打发时间 ^_^

但是还有比 gcc 更变态的,就比如 Open64(原为 SGIPro64,开源后叫 Open64,Intel 和中科院改的叫 ORC,Pathscale 改的叫 EkoPath,特拉华大学改的叫 KylinC),Open64 前端使用的是修改后的 gcc,然后对生成的 WHIRL 文件进行处理,生成 .s 文件再让 as 去汇编。在编译 Open64 时什么稀奇古怪的问题都可能出来,最主要的原因可能是 gcc, binutils 源代码版本不对应,或者只能使用某个版本的 gcc 去编译,某个版本的 ld 去连接。看看 Open64 中的源代码就可以发现,什么风格的代码都有,gcc 的代码可能是 K&R 的,也可能是 ANSI 的,有 C 风格的 C++,还有数不清的 csh,代码的混乱程度比 gcc 有过之而无不及,warning 一大堆,我每次都奇怪它是如何编译过去的。

我没有具体计算过 Open64 的编译时间,但是从感觉上来看,如果全部编译的话,Open64 至少需要一个小时(双核3.4G,2G内存)。平常我改编译器的源代码,最多的就是改 Dwarf 相关的调试信息输出。GNU make 会增量构建,改个 c/cxx 问题还不大,顶多重编一下模块,我最怕的就是改动哪个头文件。因为如果动了头文件,尤其是那种比较关键的头文件,就意味这下面一个小时就等编译结果吧。

一般情况下 make 的逻辑是:如果源文件被更新,只需要重编这个文件生成目标文件,然后用其重新构建可执行文件;如果头文件被更新,那么所有依赖此头文件的源文件都要被重新编译。这个依赖关系是写在 Makefile 中的,为了避免无谓的重编译,一定要在 Makefile 中确定正确的依赖关系。而这个依赖关系的依据是程序中头文件的包含关系和模块之间的联系,所以在写程序时一定要谨慎地选择包含头文件。多 include 一个头文件,错误地声明一个全局变量,都会造成程序的臃肿。

其实在这一点上 GNU 的东西做得就比较不错,头文件的包含,文件的依赖关系都很清楚,而且本身做为 Linux 下的程序员来说,了解依赖关系就是理解 Makefile 的第一步。相比而言 Windows 程序员就差很多,Win 程序员太依赖 IDE(集成开发环境) 了,没有 IDE 什么都干不了。经常有人问 Linux 下没有 VC,那怎么写程序?天那,比 VC 优秀的编译器有很多,而且没有图形界面不意味着写不出图形界面的程序,VC 编译程序也是调用命令行的。VC 的编译器叫做 CL, 连接器叫做 LINK,VC 也有 make,叫做 NMAKE。不相信的人可以尝试一下:如果你安装了 VC 并且选择了将 VC 可执行文件路径加入到环境变量里,那么就可以用 CL hello.cpp 来编译你的 hello world 程序,根本没有必要为了一个单文件的命令行程序创建一个工程。

Linux 并不拒绝 IDE,从 Eclipse 的流行可以看到这一点,但是不要让 IDE 把程序员变傻。如果不了解程序编译的整个过程和逻辑,那么写程序就成了一件盲目的事情。很多 VC 的程序员都不能区分什么是 assembly file, object file, executable file,什么是 preprocess,一个程序的源文件是怎么组织起来的,最终的二进制文件是怎样生成的。他们所知道的就是把一个文件往工程里一拉,乱七八糟的头文件一包含,就希望程序能编译过去。一旦遇到问题,马上抱怨怎么报那么多错误,就算很明显的错误也要到论坛上叽叽歪歪一番,怎么能期望得到一个可靠又高效的程序呢?

从 VC 自动生成的源程序来看,本身就有很多问题,就拿 VC 自动生成的类来说,鲜有 private 类型的成员变量和方法,大多数都是 public 或者 protect 了事,因为这样它不容易出错。但是这样一来 C++ 面向对象的特性又去哪儿了?MFC 里一堆一堆的宏,又如何了解真正的 API?

IDE 仅仅是一个加强版的文本编辑器,它提供的功能是高效写代码,但需要程序员自己保证写高效的代码!

细节很重要!

《编译一个软件要花多长时间?》上有5条评论

  1. 程序员一开始用太高级的IDE,很多细节都被隐藏了,换了一个IDE就不行了。所以,裸写,还是很能锻炼人的:)VI + GCC

  2. 呵呵,你说的很对呦!IDE本来就是给初中级程序员用的,因为这世上本来就是不会编程的人多。IDE就是靠这些人赚钱的。
    如果你是编底层,当然不需要IDE,可你什么时候做过AJAX网站,做过商务开发RoR?你会不用Dearmweaver或WebDeveloper?
    C++以前的问题大多出在编译器上。
    Python是google的三大主要编程语言之一,目前google用的最多的编程语言是C++,它要求运行非常快的应用,其次是Java,它在内存分配的控制力度上相对小,但还是高性能的语言。这些都是面向对象的。google还是python软件基金会(PSF)的成员之一。(以上出自《程序员》2007-7,真假与我无关)
    Linux源代码里的宏好像不必MFC里的少,因此现在微软也不再更新MFC。

  3. 现在典型的工业开发的方法是:
     
    在程序员的client端用VC作为IDE, 但是编译可以在服务器上做(make)。本地一般只做增量编译。差点的话就弄什么联机编译。
     
    关于文件间的decouple, 也不是什么新鲜的话题,一般大的框架基本上能够尽量避免这种情况(针对目前的主要的手机平台)。如果实在要改某个牵一发动全身的冬冬,为什么不出去喝杯咖啡,聊聊刚进公司的前台MM呢。
     
     

  4. 我做过 AJAX 的东西,使用过 prototype,而且我也会使用 dreamweaver(至少高级功能我应该都懂)我说过不是拒绝 IDE,但是使用 IDE 的时候要注意代码质量Linux 源代码中使用的宏和 MFC 的宏,其逻辑是不一样的~~~

回复 Bin 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注