Reload Original PagePrint PageEmail Page

云风的 BLOG: IDE 不是程序员的唯一选择(终)

对于这个系列,我已经意兴阑珊了。时间拖的太长也不好。从一开始我就没打算写一个某某工具(GNU Make)的入门教程。本来是想给那些微软 IDE 深度中毒者展现一些不同的东西,顺便打破 Make 等 CUI 工具的神秘感。工具是为人服务的,不应该是用来给人增添麻烦的。IDE 是这样,RAD 工具是这样,那些 CUI 工具也是如此。如果你能熟悉工具背后的使用哲学,工具就能给你便捷。不同的工作需要不同的工具去做,不要拿着锤子,就想把一切都变成钉子。

既然每一类工具都拥有特别多的用户,而且这个用户群还不都是脑残,去看看不同领域总是好的。对于开发环境来说是这样,选择编程语言来说也是如此,又或者说到开发方式等等。

今天不打算写长篇,简单点把这个系列完结。只谈一下前面欠下的一些问题。

对于大工程,在 VS 里,我通常是以虚拟文件夹和子工程的方式来管理的。不知道其他同学跟我是不是一个习惯。从 VC 6.0 以后,我几乎就没碰过 VS 了。不太清楚现在微软的 IDE 目前的发展趋势。我想可能有更好的组织方式吧。

但如果离开 VS ,我们用 GNU Make ,或是别的类似的工具(例如我用过的 Boost Jam ,或是前面有朋友推荐的 CMake 等)按惯例,通常按 OS 的文件目录结构来管理大的项目。即,一个子项目放在一个子目录中。对于一个大模块,即使它可能是一个子项目中不可分割的一部分,通常也以静态库的形式被分离出来。哪怕这个静态库只被一个地方引用。

把源代码拆分成适当的规模,并分类组织在不同的文件目录下,是一个好的习惯。

那么你在编写 Makefile 的时候,就可以为每个源代码的子目录编写一个 Makefile 。那么怎么让若干处于不同子目录下,甚至多层深度下的 Makefile 协同工作?Make 的惯例是利用 Shell 递归调用自己。

比如你的 src 目录下有两个子项目,foo1 和 foo2 。你在 src 根下的 Makefile 一般会这样写:

all : 
    cd foo1 && $(MAKE) all
    cd foo2 && $(MAKE) all
clean:
    cd foo1 && $(MAKE) clean
    cd foo2 && $(MAKE) clean

$(MAKE) 是一个预定义的变量,里面保存的就是调用 Make 自己的 Shell 指令。

看起来比较繁琐,所以我的习惯是,把 foo1 foo2 这些子目录提取出来。

DIRS= foo1 foo2

all : $(DIRS:=.all)
clean : $(DIRS:=.clean)

%.all :
    cd $* && $(MAKE) all
%.clean:
    cd $* && $(MAKE) clean

这个版本依然有许多重新的东西,也是可以去掉的,但那势必引出更多的“高级”用法,暂时就不展开了。其中用到的知识前面我们都介绍过了。除了 $* ,这个是表示目标中除掉 .ext 后缀的部分字符串。


按前几篇的流程走下来,你会发现,在 build 工程的时候,往往在源代码目录留下许多中间文件。我们在前面的例子中都写上了 clean 这个目标,用来清除中间文件。但事实上,在 GNU Make 的手册里,并不建议我们如此的污染源代码目录。一般来说,我们会定义一个中间文件的输出目录。这需要少许的技巧,但是不难办到,这里就不举例了。


因为早年使用 VS 的缘故,我喜欢同时维护至少两个版本的中间文件。一个 Debug 版,一个 Release 版,分放在不同的中间文件目录中,重新 build debug 版,不会影响到 Release 版的重构建。对于这个需求 Boost Jam 做的相当不错。甚至弄的更华丽,你可以轻易的拥有 "关闭 RTTI 设置的 Release 版“ 、”打开 C++ 异常的 Debug 版“ 等等。不过 boost jam 也为这华丽的功能付出了一点点小小的代价……

我们说回 Make ,最简单的方法是,再编译不同的版本的时候,选用不同的变量取值,例如:不同的优化开关、不同的输出目录。GNU Make 支持类似 C 语言中 #if 的条件语句,但是不能完全解决这个问题。还需要动用的一个特性是,GNU Make 支持定义目标相关的变量:

release : CFLAGS=/O2

debug : CFLAGS=/Zi

::...

免责声明:
当前网页内容, 由 大妈 ZoomQuiet 使用工具: ScrapBook :: Firefox Extension 人工从互联网中收集并分享;
内容版权归原作者所有;
本人对内容的有效性/合法性不承担任何强制性责任.
若有不妥, 欢迎评注提醒:

或是邮件反馈可也:
askdama[AT]googlegroups.com


点击注册~> 获得 100$ 体验券: DigitalOcean Referral Badge

订阅 substack 体验古早写作:


关注公众号, 持续获得相关各种嗯哼:
zoomquiet


自怼圈/年度番新

DU22.4
关于 ~ DebugUself with DAMA ;-)
粤ICP备18025058号-1
公安备案号: 44049002000656 ...::