原文链接:http://www.cnblogs.com/crazyhack/archive/2011/12/17/2291410.html

為了駕馭GNU Autotools這頭猛獸,我們先來驗明它的真身:

圖中橢圓形狀的就是gnu autotools里的主要工具了,包括1autoscanaclocal3autoheader4automake5autoconf等.而方形形狀只有Makefile.amconfigure.ac是需要我們寫的,别的方框里除了Makefile是最終的配置文件,其它都是中間文件。(Makefile文件是由6configure生成的)

整體流程紀錄如下:

    0.添加src目錄,將項目源碼放入該目錄中1.進入項目根目錄執行命令,以生成configure.scan文件:

autoscan
2.修改configure.scan文件為configure.ac文件,編輯configure.ac文件:mvconfigure.scan configure.ac

vim configure.ac
3.編輯根目錄下的Makefile.am文件

vim Makefile.am
4.建立autogen.sh文件,將aclocal、autoheader、automake、autoconf等命令添加到腳本中。5.在根目錄執行

.
/autogen.sh 6.用[./configure](執行後生成Makefile文件 )、[make]、[sudo make install]安裝並運行執行檔.

PS:其中0
~5為開發人員執行的步驟,6為測試人員和用戶執行的步驟。

0.在項目根目錄建立src文件夾,內容如下:

1.在項目根目錄運行autoscan命令:

可以看到生成了autoscan.log,autom4te.cache目錄以及我們需要的configure.scan文件

2.修改configure.scan文件為configure.ac,執行:

mv configure.scan configure.ac

vim configure.ac

為了方便,我已經事先寫好了configure.ac文件,使用vimdiff命令對比一下修改的部分:

修改的部分一目了然:)

3.在根目錄添加Makefile.am文件:

vim Makefile.am

其中,bin_PROGRAMS後面是需要生成的執行文件,如有多個,可以用空格隔開,而xxx_SOURCES後面的就是編譯時需要的源文件了,直接指 定源碼在src目錄中,這樣configure.ac的AC_CONFIG_FILES參數就可以寫成 AC_CONFIG_FILES([Makefile])了,而不需要在參數中添加更多目錄下的Makefile。否則就要寫成:

4.建立autogen.sh文件,添加我們需要後續執行的命令aclocal、autoheader、automake、autocon:

vim autogen.sh

 

下面解釋一下各命令:

1)aclocal:根據configure.ac的定義,將需要使用的m4宏定義複製到aclocal.m4裡面。缺省時,搜索m4宏是從autoconf的安裝目錄和系統的aclocal目錄。

2)autoheader:負責生成config.h.in文件,這裡面的C語言宏定義通過解析configure.ac生成。

3)automake:處理Makefile.am,從而生成Makefile.in。automake提供了三個軟件等級:foreign、gnu和gnits。默認等級是gnu,這裡我們使用foreign等級,它只檢測必須的文件。在執行時使用—add-missing選項可以讓automake自動添加(默認採用符號連結),如加上—copy選項可以使用複製方式,本例中,automake的命令如下:

automake –foreign –add-missing –copy

4)autoconf:生成configure文件,configure是一個shell script,可以自動設定原始程式以符合不同平台上Unix系統的特性,並且根據系統參數及環境產生合適的Makefile文件或C的頭文件,讓源代碼可以在這些不同的平台上被編譯出來。 

5.退回根目錄,在終端執行

./autogen.sh

PS:如果看到下面的提示是正常的,因為我們的項目只是用於測試,所以不要求按照GNU的標準來添加所有需要的文件

Makefile.am: required file `./NEWS' not found
Makefile.am: required file `./README' not found
Makefile.am: required file `./AUTHORS' not found
Makefile.am: required file `./ChangeLog' not found

6.用三部曲生成需要的執行檔:

1)./configure:

看到Makefile文件就說明配置項目成功了

2)make:

出現很多錯誤不要管它,因為我只在testgenfilemap.c中輸入了打印hello world!的源碼,再用tree命令可以看到生成了testgenfilemap.o文件和二進制文件testgenfilemap

再輸入./testgenfilemap呢?

哈哈,恭喜你,成功了!

3)如果需要安裝到系統目錄,請運行sudo make install

 

这个程序就是使用lunar-calendar控件,然后显示出农历来。

先用glade-2画出一个日历窗口,设置窗口的销毁事件为调用gtk_main_quit函数,设置一下窗口图标,然后生成代码

设计后的glade-2的界面代码

<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">

<glade-interface>

<widgetclass="GtkWindow"id="lunarcalendar">
  <propertyname="visible">True</property>
  <propertyname="title"translatable="yes">Lunar Calendar</property>
  <propertyname="type">GTK_WINDOW_TOPLEVEL</property>
  <propertyname="window_position">GTK_WIN_POS_NONE</property>
  <propertyname="modal">False</property>
  <propertyname="resizable">True</property>
  <propertyname="destroy_with_parent">False</property>
  <propertyname="icon">lunarcalendar.png</property>
  <propertyname="decorated">True</property>
  <propertyname="skip_taskbar_hint">False</property>
  <propertyname="skip_pager_hint">False</property>
  <propertyname="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
  <propertyname="gravity">GDK_GRAVITY_NORTH_WEST</property>
  <propertyname="focus_on_map">True</property>
  <propertyname="urgency_hint">False</property>
  <signalname="destroy"handler="gtk_main_quit"last_modification_time="Sat, 20 Apr 2013 11:12:31 GMT"/>

  <child>
    <widgetclass="GtkCalendar"id="calendar1">
      <propertyname="visible">True</property>
      <propertyname="can_focus">True</property>
      <propertyname="display_options">GTK_CALENDAR_SHOW_HEADING|GTK_CALENDAR_SHOW_DAY_NAMES|GTK_CALENDAR_NO_MONTH_CHANGE|GTK_CALENDAR_SHOW_WEEK_NUMBERS|GTK_CALENDAR_SHOW_DETAILS</property>
    </widget>
  </child>
</widget>

</glade-interface>

生成的源代码文件有:

src/callbacks.c
callbacks.h
interface.c
interface.h
src/main.c
src/Makefile.am
support.c
support.h

support.c/.h文件中就是一些支撑函数,一般不用管

我们需要关注就是interface.c/.h,这个文件就是创建控件的函数。

按照lunar-calendar说明,将interface.c中调用gtk_calendar_new替换成lunar_calendar_new,同时增加lunar-calendar/lunar-calendar.h的包含

修改完后的源代码如下:

生成并修改后的interface.c文件

/** DO NOT EDIT THIS FILE - it is generated by Glade.*/#ifdef HAVE_CONFIG_H
# include
<config.h> #endif#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>#include<string.h>#include<stdio.h>#include<gdk/gdkkeysyms.h>#include<gtk/gtk.h>#include<lunar-calendar/lunar-calendar.h>#include"callbacks.h"#include"interface.h"#include"support.h" #define GLADE_HOOKUP_OBJECT(component,widget,name) \g_object_set_data_full (G_OBJECT (component), name, \
gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \g_object_set_data (G_OBJECT (component), name, widget)

GtkWidget
*create_lunarcalendar (void)
{
GtkWidget
*lunarcalendar;
GdkPixbuf
*lunarcalendar_icon_pixbuf;
GtkWidget
*calendar1;

lunarcalendar
=gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_name (lunarcalendar,
"lunarcalendar");
gtk_window_set_title (GTK_WINDOW (lunarcalendar), _(
"Lunar Calendar"));
lunarcalendar_icon_pixbuf
= create_pixbuf ("lunarcalendar.png");if(lunarcalendar_icon_pixbuf)
{
gtk_window_set_icon (GTK_WINDOW (lunarcalendar), lunarcalendar_icon_pixbuf);
gdk_pixbuf_unref (lunarcalendar_icon_pixbuf);
}

calendar1
=lunar_calendar_new ();
gtk_widget_set_name (calendar1,
"calendar1");
gtk_widget_show (calendar1);
gtk_container_add (GTK_CONTAINER (lunarcalendar), calendar1);
gtk_calendar_display_options (GTK_CALENDAR (calendar1),
GTK_CALENDAR_SHOW_HEADING
|GTK_CALENDAR_SHOW_DAY_NAMES|GTK_CALENDAR_NO_MONTH_CHANGE|GTK_CALENDAR_SHOW_WEEK_NUMBERS);

g_signal_connect ((gpointer) lunarcalendar,
"destroy",
G_CALLBACK (gtk_main_quit),
NULL);
/*Store pointers to all widgets, for use by lookup_widget().*/GLADE_HOOKUP_OBJECT_NO_REF (lunarcalendar, lunarcalendar,"lunarcalendar");
GLADE_HOOKUP_OBJECT (lunarcalendar, calendar1,
"calendar1");returnlunarcalendar;
}

到此,我们完成了第一步,生成代码

代码压缩为:lunarcalendar.0.0.1.zip

#coding=utf-8
from django importtemplate

register
=template.Library()#register.tag('source', do_source) @register.tag(name="source")defdo_source(parser, token):"""source can direct insert method return string into html
{% source myapp mymethod %}
or
{% source myapp mymethod arg0 arg1 arg2 %}
or
{% source myapp mymethod arg0,arg1,arg2 %}
""" try:#split_contents() knows not to split quoted strings. args =token.split_contents()exceptValueError:raise template.TemplateSyntaxError("%r tag requires at least two arguments" %token.contents.split()[0])if len(args) < 2:raise template.TemplateSyntaxError("%r tag requires at least two arguments" %token.contents.split()[0])
model_name
= args[1]
method_name
= args[2]
params
=[]if len(args) >=3:
params
+= args[3:]if len(params) == 1:if ',' inparams[0]:
params
= ['%s' % arg for arg in params[0].split(",")]#try to import this method try:
models
= __import__(model_name, fromlist =[method_name])
method
=getattr(models, method_name)except:raise template.TemplateSyntaxError("Can't import %s[%s]" %(model_name, method_name))returnSourceNode(method, params)classSourceNode(template.Node):def __init__(self, method, params):
self.method
=method
self.params
=paramsdefrender(self, context):try:
value
= self.method(context, (arg for arg inself.params))except:from django.conf importsettingsifsettings.DEBUG:importsys,traceback
str
= '<p> [%s] [%s] </p>' %(self.method, self.params)
str
+= '<p> [%s] </p>' % traceback.format_exception(*sys.exc_info())returnstrelse:returnstrreturn value