标签 Makefile 下的文章

关于Makefile.am中与Build相关的变量设置

今天尝试使用autoconf和automake重新构建一个遗留库的Build环境。之前改造的lcut的目录结构还是相对简单,改造时并未遇到什么难题,不过今天就没那么幸运了,我在头文件目录包含设置这个看似简单的环节上遇到了一些小麻烦。

这个库结构其实也没那么复杂,只是源文件和头文件不在一个目录下罢了:
testproj/
    – Makefile.am
    – configure.in
    – include/
        – xx.h
        – yy.h
    – module1
        – xx.c
        – Makefile.am
    – moudle2
        – yy.c
        – Makefile.am
   
开始也没多想,参照以前的经验一步一步生成configure脚本。执行configure脚本生成Makefile文件,敲入make。在进入module1目录后,提示编译xx.c文件失败,无法找到xx.h!看了一下gcc的编译选项,的确没有-I上层的include目录,只有"-I."和"-I.."。翻看了一下automake的manual,发现automake默认情况下是将config.h所在的目录当作-I的参数。我的configure.in中是这样设置的:AC_CONFIG_HEADERS([config.h]),怪不得无法正确设置目录呢!将该句改为AC_CONFIG_HEADERS([include/config.h])后,重新生成Makefile并执行make,这回gcc命令行上出现了"-I../include"的字样,编译也很是顺利。

不过就这样算了,似乎总觉不妥,config.h只有一个,但如果有多个include目录的情况下该如何设置头文件包含目录呢?带着这个问题我再次翻看了automake的手册。老天不负有心人^_^,手册里确有这方面的说明。

原来automake从autoconf里继承了很多编译时需要的变量,诸如CC, CFLAGS, CPPFLAGS, DEFS, LDFLAGS,LIBS等等。但automake也可自己设置一些编译时用到的变量,automake与Build相关的一些变量名字也都以AM_开头,诸如AM_CPPFLAGS(与CPPFLAGS对应)。在Makefile.am中设置头文件包含的方式至少有以下两种:

* 在顶层Makefile.am中设置全局变量
AM_CPPFLAGS = -I $(top_srcdir)/include1
export AM_CPPFLAGS
这样在编译子目录(如module1)时,该全局设置也会起作用,在gcc编译命令行中你会看到-I ../include1。

* 在子目录层Makefile.am中设置局部变量
AM_CPPFLAGS = -I $(top_srcdir)/include2
这里的设置仅仅影响该目录下源文件的编译,对于其他同级目录下的源文件不起作用。另外如果此时顶层的Makefile.am中依然有AM_CPPFLAGS的设置,那么子目录下的Makefile.am中的这些设置会覆盖掉顶层的定义,在gcc编译命令行中也只会看到-I include2而无-I include1。

除了在Makefile.am中手工显式设置外,也可在执行configure脚本的时候通过传入CPPFLAGS参数来设定包含头文件位置,如configure CPPFLAGS=-I./include3。注意"CPPFLAGS"、"="和后面的值之间不能有空格。在automake manual中也有这方面的说明:在命令行中这里的CPPFLAGS将被放到AM_CPPFLAGS后面并一起传给gcc。

对于automake中的其他Build相关的AM_XXFLAGS变量,其道理也是相同的,这里就不赘述了。

发布一款轻量级C语言单元测试框架

基于各种xUnit框架的单元测试早已不是什么新鲜玩意儿,不过在"古老"的C语言领域,还尚未有哪种框架可以成为“寡头”。

记得2005年末的时候,初出茅庐的我吸取xUnit的设计思想在业余时间编写了一个轻量级的C单元测试框架lcut(Lightweight C Unit Test framework),当时还写了一篇文章《C单元测试包设计与实现》记录了最初的设计和实现思路。本打算将这个小工具在部门内至少是项目内推广,可无奈当时部门内部尚未认识到使用框架工具进行单元测试的好处,或者尚未形成此种技术风气,当时的我也是“人轻言微”,因此这个小工具也没能吸引足够的眼球。这么长时间以来,都是我自己一直在使用,
其间,lcut做了两次小规模修改。特别是最后一次修改,通过增加测试用例执行的返回状态(增加LCUT_TEST_RESULT()宏),让lcut可以与一些持续集成工具(如cruisecontrol.rb)结合在一起使用。

随着部门同事对单元测试认识度的提升,基于框架的单元测试也逐渐在组内执行开来,有人使用cmockery,有人使用CuTest,也有一些新同事参考以前我编写的代码开始使用lcut。中秋假期在家读完《The Passionate Programmer》(中文版名为:《我编程,我快乐-程序员职业规划之道》)后,颇有感触。这几天突然就有了把lcut发布出去的想法(咱不能总享用,不付出吧^_^)。

发布出去前的准备工作还是蛮多的:
* 挑选一个合适的开源项目托管平台
以前是sourceforge一家独大,现在则有许多选择,主流的平台包括Google code、githublaunchpad等,最终我选择了Google Code,其实也没有什么具体理由,只是因为一直都使用Google的产品,惯性使然。如果你之前已经拥有了Google的account,那么使用Google code就更加方便了。具体如何操作,Google Code有详细的官方manual供你查阅。

* "美化"和包装代码
发布出去之前,需要先对lcut代码进行一下"美化",毕竟在家里显摆和在大庭广众下展示是有不同的。代码的格式最好能适应大多数人(或者是编辑器)的口味(比如将TAB换成空格),可利用类似astyle这样的代码格式化工具按照配置号的规则对代码做一次全量格式化。另外由于要应对不同平台、不同OS,我们还要考虑代码的可移植问题,这方面我采用autoconf和automake重新编写了lcut的构建脚本。

* 测试
为了保证发布出去的包可用且是正确的,当然需要做测试了。构建测试、安装测试以及包本身的功能测试,这个还是很耗费精力的。lcut在Ubuntu 10.04(x86 32bit)和Solaris 10(x86 and Sparc)平台下都测试通过。

* 文档
头疼!lcut本身就没什么文档,另外考虑到一般对外发布都使用English编写文档,我就更纠结了。在目前发布的lcut-0.1.0版本中,文档确是欠缺的。要知lcut是如何使用的,可参考我上面提到的《C单元测试包设计与实现》或看src/example下的例子。

* Roadmap
lcut尽可能做到不是“发布后不管”,所以还要有Roadmap或是TODO计划。这里想到两点:一是补文档; 二是打算为lcut增加mock功能。

明天就是国庆了,这里将lcut(http://code.google.com/p/lcut/)发布出来权当国庆献礼了,欢迎大家试用并提出宝贵意见和建议。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言进阶课 AI原生开发工作流实战 Go语言精进之路1 Go语言精进之路2 Go语言第一课 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats