歡迎您光臨本站 註冊首頁

學習glib源碼包

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  
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

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
$

glib


[火星人 ] 學習glib源碼包已經有316次圍觀

http://coctec.com/docs/program/show-post-71578.html