首页 > 代码库 > 项目框架设计模式(转)

项目框架设计模式(转)

转自 http://my.huhoo.net/archives/2009/08/post_39.html

项目框架设计模式

目的

  1. 解决多人开发过程中协作的问题;
  2. 解决配置文件规范;
  3. 解决项目源码包和二进制打包的问题;
  4. 解决文档规范;

目录

  • 1 目的
  • 2 框架
  • 3 常约定
    • 3.1 配置文件
    • 3.2 库公约
  • 4 样例



目的

 

  1. 解决多人开发过程中协作的问题;
  2. 解决配置文件规范;
  3. 解决项目源码包和二进制打包的问题;
  4. 解决文档规范;


框架

 

  • 结合git和autoconf,可以达到多人的协作开发模式;


Autoconf框架图.png

  • 上图中利用autoconf的开发模式,能有效的达到各项的“产出”,具体介绍可浏览autoconf介绍,如果多个人进行开发,可以选择svn或者git,这里有一个大概介绍git的开发模式图:


Git图.png

常约定


  • 在了解大概的模式之后,我们还要了解经常在一些开发和项目中的约定(常约定)。


配置文件


  • 在实际的工程项目中,我们一般使用以下几种类型的配置文件:
    1. unixconfig常用于在unix环境中读取配置信息的一种格式,这种格式被众多开源程序所用,是最广泛的一种配置文件类型;
    2. libconfig是基于自定义的一套数据结构格式,数据结构可以很复杂,也是开源程序经常使用一种方式,最近cnangel做了针对perl读写的模块,这样可以兼容perl语言、C/C++语言;
    3. xml格式是一种常见的数据结构,但也常用于作配置文件,一般在java工程中经常使用,c/c++并不常见;
    4. yaml是一种包含xml等子集的数据格式,在yaml官方网站有yaml的标准规范,且yaml支持多种语言,但是c/c++库提供的库并不是很适合做配置文件,所以此配置类型往往用于脚本;

  • 详细格式见下图:


常用的配置样例.png

库公约


  • 针对c/c++开发的项目,我们针对各种平台一般最终需要提供动态链接库和静态链接库;
  • 对于静态库文件,我们常见的Windows平台中一般是.lib为扩展名,类Unix平台中以.a为扩展名,里面相同的都是由一些C或者其他语言生成的object(.o为扩展名)文件打包而成;
  • 对于动态链接库文件,一般在Windows平台中是以.dll作为扩展名,类Unix平台中以.so作为扩展名,里面都是一些符号连接和函数的声明、构造信息等等,一般可以使用工具nm等查看到相关信息,ldd来查看符号连接、依赖等信息;
  • 静态库文件一般比动态连接库大得多,静态库可以解出多个.o结尾的object文件,通过这个方法,我们可以合并很多小的静态库,并合并相应的头文件。静态库的信息相对比较全,主要用来作开发等;
  • 动态库相对来说只有一些符号连接等信息,往往用来支配程序(可执行文件)的运行,而且比静态库会获取到更小的内存空间,从而节省了程序的运行空间;
  • 类Unix动态链接库标准命名规则(soname):


  lib + 链接库名字 + .so + .版本号

 

每当链接库接口改变时都递增版本号。soname 文件其实只是一个符号链接而已,指向他的real name 文件,更为详细的命令方式如下(real name):


  lib + 链接库名字 + .so + .版本号.次版本号.发行号

 

  • 实际上,我们连接库时,使用的是如下动态链接库(linker name):


  lib + 链接库名字 + .so

 

编译器以这个名字来请求指定的链接库。


  • 当程序在内部列出所需要的链接库时,仅仅使用链接库名字。当你创建一个链接库时,使用 real
    name。安装一个新的链接库时,把它复制到一个DLL文件夹里,然后运行程序 ldconfig。ldconfig 检查存在的 real name
    文件,并且创建指向它的符号链接 soname 文件。ldconfig 并重新建立 cache 文件 /etc/ld.so.cache。
  • ldconfig 不会创建 linker name 文件,但是一般性 linker name
    文件在安装链接库的时候创建。linker name 文件也只是一个符号链接,指向最新的 soname 文件或 real name
    文件。建议指向 soname 文件,因为当你更新库以后,在编译器链接的时候,一般总是想使用新的库。
  • 一般而言,链接库必须放置在文件系统的指定位置。
    1. 多数开源软件遵守 GNU 标准:当分发源代码的时候,库默认安装在 /usr/local/lib,命令安装在 /usr/local/bin。该标准还定义了如何重写这些默认标准以及如何调用安装程序。
    2. Filesystem Hierarchy Standard(FHS) 规定:多数库应安装在 /usr/lib,启动时需要的库安装在 /lib,非系统库应安装在 /usr/local/lib

  • GNU 标准是针对开发人员的,FHS 是针对发行者的。
  • 在基于 GNU glibc 的系统上,包括所有 linux 系统,ELF
    可执行二进制文件的运行自动导致程序加载器被加载并且运行。在 linux 下,加载器是
    /lib/ld-linux.so.X(X是版本号)。然后加载器搜索、加载程序所要使用的动态链接库,被搜索的文件夹列表保存在文件
    /etc/ld.so.conf 里。
  • 使用环境变量LD_LIBRARY_PATH, 该变量所指定的文件夹将会首先被搜索,然后才会搜索默认的链接库文件夹。该变量对开发和测试比较有用,但不应该为了给普通用户使用而设置。
  • 在Linux下你可以直接调用程序加载器,比如,你可以传递PATH参数给加载器代替该变量来运行程序:




/lib/ld-linux.so.2 --library-path PATH EXECUTABLE


不带参数执行加载器,可以得到更多帮助。但是,不要这样执行程序,仅供调试时使用。


  • 另外环境变量LD_DEBUG供调试使用的。该变量是dl*函数的开关,用来显示正在做的事情的详细信息。可以取值为:














参数
解释
files
显示so文件的加载顺序
bindings
显示关于符号帮定的信息
libs
显示库搜索路径的信息
versions
显示版本依赖的信息
help
使用该值运行程序将会显示可用的选项


  • 在GNU的编译器中(gcc),很多的编译选项能够很好的辅助我们来创建动态连接库;
    • 用 -fpic 或 -fPIC 选项创建要放入动态链接库中的目标文件。使用该选项生成的代码是位置无关的代码(动态链接库的必要条件)。使用 gcc 的 -Wl 选项传递 soname 参数给链接器。-Wl 选项里不能有未转义的 whitespace。
    • -g 选项使代码包含调试信息,-Wall 选项用来产生警告,两者并不是创建动态链接库必须的,但是建议加上。
    • 不要 strip 所生成的动态链接库,或使用编译器参数 -fomit-frame-pointer,这样做将会无法使用调试器。
    • -fPIC 选项总是可以使用,但生成的代码比使用 -fpic 的要大。-fpic 选项生成的代码比较小、快,但是有平台相关的限制,当创建 DLL 时,链接器将会告诉你是否符合限制。
    • 链接器还有一个有用的选项 -rpath,可以用来指定程序在运行时搜索DLL时的路径,使用 gcc 时可以这样传递参数给链接器:


  -Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)

 

若使用了这个选项,就可以考虑不用LD_LIBRARY_PATH这个环境变量了。


样例


  • 这里用了一个工程uc作为用例来说明该框架的强大以及灵活多变的可扩展性(目前版本是0.0.2-2版本):


  http://github.com/cnangel/UC/tree/master

项目框架设计模式(转)