Web Analytics

C语言项目构建管理辅助工具 – buildc

这几年我一直从事C语言项目的开发。这些项目的规模都不算小,少则十几万代码,多则几十万行代码,至少也都算得上是中型项目吧。项目构建工具使用的是传统的Make工具,构建脚本都是自行编写的,构建时直接在顶层目录下敲入make即可。 这种传统的构建方式其实是很耗时费力的。比如执行make之前你需要根据项目代码的实际路径重新设定一些环境变量或修改Makefile中的某些标识路径的变量;你还要将项目依赖的各种内部公共库、第三方开源库悉数找到,并安装在指定目录下,修改Makefile中这些第三方库的路径配置。只有做完这些后,你才能顺利地执行Make。以后每当你更换一个环境,你就要将上面的步骤重复执行一遍。有的项目第三方依赖较多,要完整地搭建一个项目构建环境所耗费的时间也是很惊人的,特别是对一些不熟悉项目构建的新人更是如此。另外随着产品被要求具备在多个平台上运行的能力,你的构建脚本还要支持在多个平台上的构建,你要为项目所依赖的第三方库准备多个平台的版本;当某个依赖库版本进行了升级,你还要手工在多个环境下进行更新。 ...

December 8, 2011 · 10 min · Tony Bai

C程序员驯服Common Lisp – 函数

Common Lisp是函数式编程语言,其基本组成单元自然是函数。对Common Lisp函数的理解也是学习Common Lisp语言的关键。另外与C语言以内存单元修改为主要编程方法不同,Common Lisp的主要编程方法是将函数应用于参数。这里我们分别用两种范式风格实现同一个函数,该函数用于取得第n个fibonacci数(n从0开始): ...

September 23, 2011 · 11 min · Tony Bai

C程序员驯服Common Lisp – 变量

变量是C语言中最常用的、不可或缺的语言元素。C语言是命令式编程语言(imperative programming language),其基本编程方法是基于对内存单元的修改,而变量又恰是对内存单元的抽象表示,比如:“int a = 0xff"这行语句告诉我们在内存中有一块大小为4个字节的区域,该区域可以通过a这个变量直接访问,该区域初始时存储的值为0xff。由此看来C语言的主要操作就是变量操作。 ...

September 20, 2011 · 9 min · Tony Bai

C程序员驯服Common Lisp – 控制结构

光有表达式,我们依旧无法写出实用的程序,我们还缺少控制结构(Control Structures)。 C语言主要有三种控制结构:顺序结构、条件分支结构和循环结构。Common Lisp 也实现了类似的控制结构,我们逐一来看。 一、顺序结构 顾名思义,顺序结构中的语句或表达式是按其位置的先后顺序依次执行的,这也是最简单也最容易理解的一种结构。在C语言中,绝大多数代码块(code block)中的代码都是顺序结构的。Common Lisp程序由S-expressions组成,其本质上的执行过程为自左向右的求值过程。不过Common Lisp的代码编排风格会让给大家一种错觉:Common Lisp似乎也是顺序执行的,例如: ...

September 14, 2011 · 7 min · Tony Bai

C程序员驯服Common Lisp – 表达式

Common Lisp程序由一组表达式构成。在"入门“一文中我提到过:Common Lisp使用S-expressions作为表达式(Expressions)的基本语法格式。S-expressions由原子(atoms)和S-expressions列表组成,或者说原子和列表(List)是组成S-expression的基本元素。复杂的源程序都是由简单的表达式组成的,我们在学习编写实用的Common Lisp程序之前,首先要清楚简单表达式的结构和求值方法。 每个Lisp表达式都可以提交给Common Lisp解释器进行求值,并得到一个求值结果。这里我们从简单的原子说起。 ...

September 2, 2011 · 5 min · Tony Bai

使用autoconf解决可移植性问题

昨天在编译项目代码时遇到了这样一个错误: xx_base.h:72:2: 错误:#error “One of _BIG_ENDIAN or _LITTLE_ENDIAN must be defined.” 这是预编译器的错误输出。原因很明显:预编译器在处理xx_base.h时没有发现_BIG_ENDIAN或_LITTLE_ENDIAN的定义,#error预处理宏输出了如上错误。下面是出现错误位置的源码片断: ...

August 23, 2011 · 5 min · Tony Bai

CBehave – 一个C语言行为驱动开发框架

Behaviour-Driven Development,即行为驱动开发在业界早已不是什么新鲜玩意了。我之前也略有了解,不过一直没有"深入钻研"。直到今年年初InfoQ的几篇有关BDD的文章才让我对BDD有了更多的认识。与TDD一样,C语言在BDD领域依旧是一个"后进分子",在多数主流语言(Java,C#,Ruby等)都已经拥有比较成熟的BDD框架(如JBehave、SpecFlow和Cucumber)的今天,C语言却似乎仅有一款BDD框架-CSpec可用。于是年初的时候我就把设计和实现一个用于C语言的行为驱动开发框架加入到我今年的ToDoList中了。 ...

August 15, 2011 · 7 min · Tony Bai

偿还N年前的一笔技术债

记得刚来公司时曾参与过一个项目,项目中用到了部门基础库中的一个B+树接口。不过在程序调试过程中我们发现可执行程序总是dump core(在sparc solaris上),经初步分析,断定问题就出在B+树接口处,但一时又找不到问题原因。还好这个B+树的实现者就坐在我的旁边。他分析后告诉我:这个B+树接口要求用户自定义的索引结构体的size应该为4的整数倍。按照他的说法,我为结构体打了padding,以满足结构体size为4的整数倍的要求。修改后果然不再dump core了。当时项目进度紧,我也没有求甚解,这件事也就过去了。 ...

July 21, 2011 · 6 min · Tony Bai

为函数添加enter和exit级trace

日常开发中,我们为了辅助程序调试常常在每个函数的出入口(entry/exit)增加Trace,一般我们多用宏来实现这些Trace语句,例如: #ifdef XX_DEBUG_ #define TRACE_ENTER() printf(“Enter %s\n”, __FUNCTION__) #define TRACE_EXIT() printf(“Exit %s\n”, __FUNCTION__) #else #define TRACE_ENTER() #define TRACE_EXIT() #endif ...

July 13, 2011 · 4 min · Tony Bai

也谈共享库2

我之前写过一篇名为"也谈共享库“的博文,对共享库的查找和符号解析机制做了还算比较详细的说明,不过百密一疏,总有一些意想不到的情况发生。这不今天我又遇到了一个有关共享库的新问题,这里将这个问题及其解决过程记录下来,也算是对上一篇文章中未涉及内容的一个补充吧。 N年前我曾参与过部门的一个可复用系统的设计开发,当时我们设计了一种插件式的系统结构,其中所谓的"插件"是以共享库的形式提供。主程序通过读取配置,获取插件的位置,并在运行期利用dlopen动态加载插件(.so文件),用dlsym查找、绑定并执行.so中的特定业务函数。 ...

July 7, 2011 · 6 min · Tony Bai