学习glib源码包

来源:Linuxeden 作者:c-aries
  
0. Raymond的前言


在<<学习GNU Emacs(第二版)>>的前言中,Eric Raymond写道:

我有很多知识都是通过阅读别人的程序代码而掌握的,这些"前辈"包括: Olin Shivers, Jamie Zawinski, Kyle Jones, Barry Warsaw, Roland McGrath, Richard Stallman本人(当然得有他)和许多其他程序员。

1. glib?

glib是什么?
GLIB - Library of useful routines for C programming
学习glib源码包
2. 下载源代码


$ pwd
/home/c-aries/source/glib
$ cat url
http://ftp.gnome.org/pub/gnome/sources/glib/2.16/glib-2.16.6.tar.bz2
http://ftp.gnome.org/pub/gnome/sources/glib/2.16/glib-2.16.6.md5sum
$ wget -c -i url

3. 编译源代码,解决依赖关系,安装

$ tar xvf glib-2.16.6.tar.bz2
$ cd glib-2.16.6

在 ./mybuild 文件夹下进行编译
程序安装的目标目录为 ./mybuild/work

编译和安装的命令如下:

$ mkdir mybuild
$ cd mybuild
$ ../configure --prefix=`pwd`/work
$ make
$ make install

4. 学习源代码

这里以glib源代码中宏定义G_GNUC_EXTENSION的学习笔记为例:
G_GNUC_EXTENSION定义于 glib/gmacros.h

4.1 G_GNUC_EXTENSION的实现

#if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
#  define G_GNUC_EXTENSION __extension__
#else
#  define G_GNUC_EXTENSION
#endif

4.2 为何出现G_GNUC_EXTENSION?


比如在C语言中使用long long数据类型时,如果使用__extension__修饰,此时gcc使用'-ansi -pedantic'选项则不会报错。
'-ansi -pedantic'选项的含义如下:

-ansi
    Specify the standard to which the code should conform. Currently CPP knows
    about C and C++ standards; others may be added in the future.
-pedantic
    Issue all the mandatory diagnostics listed in the C standard. Some of them
    are left out by default, since they trigger frequently on harmless code.

4.3 G_GNUC_EXTENSION使用实例

G_GNUC_EXTENSION typedef unsigned long long guint64;

5 修改源代码,编程调试


为glib修改源代码,添加功能,找bug的趣事就留给大家慢慢玩了
这里介绍如何使用自己修改和编译得来的glib函数库进行编程调试

5.1 查看cflags编译选项

$ pkg-config --cflags mybuild/work/lib/pkgconfig/glib-2.0.pc
-I/home/c-aries/source/glib/glib-2.16.6/mybuild/work/include/glib-2.0 -I/home/c-aries/source/glib/glib-2.16.6/mybuild/work/lib/glib-2.0/include 

5.2 查看libs链接选项

$ pkg-config --libs mybuild/work/lib/pkgconfig/glib-2.0.pc
-L/home/c-aries/source/glib/glib-2.16.6/mybuild/work/lib -lglib-2.0 
 
5.3 编程实例


使用自己修改和编译得来的glib函数库进行编程调试
在笔者的cvs本地仓库checkout出test-glib项目,程序运行后,打印出64位无符号整数的最大值

$ pwd
/home/c-aries/develop
$ cvs co test-glib
$ cd test-glib/
$ make
$ ./main
The Largest Number Of 64 Bits: 18446744073709551615

test-glib项目的源代码如下:

$ cvs co -p test-glib
cvs checkout: Updating test-glib
===================================================================
Checking out test-glib/Makefile
RCS:  /home/c-aries/cvs/test-glib/Makefile,v
VERS: 1.1.1.1
***************
CC = gcc
CFLAGS = -Wall -Werror -Wcast-align -g
LDFLAGS =

MAINOBJECT = main.o opt.o
TESTOBJECT = test.o

GLIBHOME = /home/c-aries/source/glib/glib-2.16.6/mybuild/work
GLIBPC = $(GLIBHOME)/lib/pkgconfig/glib-2.0.pc
GLIBCFLAGS = `pkg-config --cflags $(GLIBPC)`
GLIBLIBS = `pkg-config --libs $(GLIBPC)`

all: main

main: $(MAINOBJECT)
    $(CC) $(LDFLAGS) $(GLIBLIBS) $(MAINOBJECT) -o $@

test: $(TESTOBJECT)
    $(CC) $(LDFLAGS) $(TESTOBJECT) -o $@

main.o: main.c
    $(CC) $(CFLAGS) $(GLIBCFLAGS) -c $<

opt.o: opt.c
    $(CC) $(CFLAGS) -c $<

test.o: test.c
    $(CC) $(CFLAGS) -c $<

clean:
    rm -f *.o *~ *.log a.out main test

.PHONY: all clean
===================================================================
Checking out test-glib/main.c
RCS:  /home/c-aries/cvs/test-glib/main.c,v
VERS: 1.2
***************
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include "opt.h"

int
main(int argc, char *argv[])
{
  options_init();
  options_deal(argc, argv);
  g_print("The Largest Number Of 64 Bits: %" G_GUINT64_FORMAT "\n",\
      G_MAXUINT64);
  exit(EXIT_SUCCESS);
}
===================================================================
Checking out test-glib/opt.c
RCS:  /home/c-aries/cvs/test-glib/opt.c,v
VERS: 1.1.1.1
***************
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "opt.h"

struct options opt;

static void show_usage();

static void
show_usage()
{
  printf("usage: main [options]\n\
-h 打印该帮助信息\n\
-v 显示程序内部提示\n");
}

void
options_init()
{
  opt.verbose = 0;
}

void
options_deal(int argc, char *argv[])
{
  int my_opt;

  while ((my_opt = getopt(argc, argv, "hv")) != -1) {
    switch(my_opt) {
    case 'h':
      show_usage();
      exit(EXIT_SUCCESS);
    case 'v':
      opt.verbose = 1;
      break;
    default:
      show_usage();
      exit(EXIT_FAILURE);
    }
  }
}
===================================================================
Checking out test-glib/opt.h
RCS:  /home/c-aries/cvs/test-glib/opt.h,v
VERS: 1.1.1.1
***************
#ifndef OPT_H
#define OPT_H

struct options {
  int verbose;
};

void options_init();
void options_deal(int argc, char *argv[]);

#endif
$

时间:2010-06-02 08:01 来源:Linuxeden 作者:c-aries 原文链接

好文,顶一下
(19)
95%
文章真差,踩一下
(1)
5%
------分隔线----------------------------


把开源带在你的身边-精美linux小纪念品
无觅相关文章插件,快速提升流量