2013年4月

生成desktop文件方法很多,有使用.desktop.in.in方式的,也有直接放一个.desktop文件方式的

其实两者差别不大,因为对于我们来说,一个工程的.desktop基本上确定的。

比如使用.desktop.in.in方式,我们在根目录下面创建一个data目录,将.desktop.in.in文件及Makefile.am文件放入其中

[Desktop Entry]
_Name
=Lunar Calendar
_Name[zh_CN]
=中国农历
_GenericName
=Lunar Calendar
TryExec
=@PACKAGE@Exec=@PACKAGE@Icon=pixmaps/@PACKAGE@.png
Terminal
=falseType=Application
Categories
=Application;GTK;utiliy;
StartupNotify
=trueEncoding=UTF-8
@INTLTOOL_DESKTOP_RULE@SUBDIRS=desktop_in_in_files= lunarcalendar.desktop.in.indesktop_in_files= $(desktop_in_in_files:.desktop.in.in=.desktop.in)

desktopdir
= $(datadir)/applications
desktop_DATA
= $(desktop_in_files:.desktop.in=.desktop)

gtk_update_icon_cache
= gtk-update-icon-cache -f -t $(datadir)/icons/hicolor

install
-data-hook: update-icon-cache
uninstall
-hook: update-icon-cache
update
-icon-cache:if test -z "$(DESTDIR)"; then \
echo
"Updating Gtk icon cache."; \$(gtk_update_icon_cache); \else\
echo
"*** Icon cache not updated. After (un)install, run this:"; \
echo
"*** $(gtk_update_icon_cache)"; \
fi

EXTRA_DIST
=\$(desktop_DATA)

DISTCLEANFILES
=\$(desktop_in_files) \$(desktop_DATA)

对于这种方式,关键在于在Makefile.am中增加一个INTLTOOL_DESKTOP_RULE项

另外,由于使用的是.desktop.in.in方式,会使用到intltool工具,因此,我们在configure.ac中增加测试IT_PROG_INTLTOOL(0.35.6)

我们现在根目录下的Makefile.am中的SUBDIRS中增加data目录,重新使用autogen.sh/configure/make/make install,就可以自动将.desktop生成并安装在对应的application目录下了

此时打包的源代码文件:lunarcalendar.0.0.5.zip

直接放一个.desktop那就更简单了,写一个.desktop文件及Makefile.am,依然放在data目录

[Desktop Entry]
Name
=Lunar Calendar
Name[zh_CN]
=中国农历
GenericName
=Lunar Calendar
GenericName[zh_CN]
=中国农历
TryExec
=lunarcalendar
Exec
=lunarcalendar
Icon
=pixmaps/lunarcalendar.png
Terminal
=falseType=Application
Categories
=Application;GTK;utiliy;
StartupNotify
=trueEncoding=UTF-8
appdir = $(datadir)/applications

app_DATA
= *.desktop

EXTRA_DIST
= *.desktop

重新使用autogen.sh/configure/make/make install,就可以自动将.desktop生成并安装在对应的application目录下了

此时的源代码打包:lunarcalendar.0.0.6.zip

记住,无论哪种方式,configure.ac都需要增加AC_CONFIG_FILES的内容:

AC_CONFIG_FILES([Makefile po/Makefile.insrc/Makefile
data
/Makefile
data
/lunarcalendar.desktop.in])

AC_CONFIG_FILES([Makefile po/Makefile.insrc/Makefile
data
/Makefile])

第二种方式不依赖于intltool,反倒更简单

处理gettext与多国语言,我们先需要在configure.ac中增加一个AM_GNU_GETTEXT宏,如下

#Checks for programs.
AC_PROG_CXX
AC_PROG_CC
AC_PROG_MAKE_SET

AM_GNU_GETTEXT([external])

定义了external就不需要在当前目录下面有intl目录了,当然intl目录也是可以通过AM_GNU_GETTEXT_INTL_SUBDIR来指定另外名称的

然后我们执行gettextize生成config.rpath以及po/m4目录下面的文件。同时会往configure.ac的AC_CONFIG_FILES中增加一个输出po/Makefile.in

执行此命令时,带参数--symlink就是链接到系统中而不是拷贝到本地

当前版本的gettextize会提示下一步需要做些什么事情,最关键的是在po目录下面将一个Makevars.template拷贝为Makevars,内容是不需要修改的

由于glade-2中使用的gettext宏是GET_PACKAGE,因此,我们在configure.ac中增加定义

GETTEXT_PACKAGE=lunarcalendar
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], [
"$GETTEXT_PACKAGE"],
[GETTEXT lunarcalendar])

做完这些操作之后,我们需要再执行autogen.sh脚本,然后再执行configure,再调用make程序

此时的全部代码打包:lunarcalendar.0.0.3.zip

这时候,编译后会在po目录下生成lunarcalendar.pot文件,基于此文件,我们可以对源代码的字符串进行翻译

比如,我们翻译出一个zh_CN.po文件

#SOME DESCRIPTIVE TITLE.#Copyright (C) YEAR Free Software Foundation, Inc.#This file is distributed under the same license as the PACKAGE package.#FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.#msgid ""msgstr""
"Project-Id-Version: lunarcalendar 0.1\n"
"Report-Msgid-Bugs-To: eagle_xmw@yahoo.com.cn\n"
"POT-Creation-Date: 2013-04-21 03:02+0800\n"
"PO-Revision-Date: 2013-04-21 03:07+0800\n"
"Last-Translator: \n"
"Language-Team: LANGUAGE <eagle_xmw@yahoo.com.cn>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"


#: src/interface.c:39
msgid "Lunar Calendar"msgstr"中国农历"

#: src/support.c:90#: src/support.c:114#, c-format
msgid "Couldn't find pixmap file: %s"msgstr"无法打开图片文件: %s"

然后,我们还要再在po目录下创建一个LINGUAS文件,文件的内容只有一行"zh_CN"

再调用autogen.sh重新生成Makefile等之后,再调用configure及make,就可以将刚才增加的zh_CN.po自动编译为zh_CN.gmo了

此时的全部代码打包:lunarcalendar.0.0.4.zip

至此,我们的工程是可以编译、链接,也可以安装了,下一步是生成.desktop文件

 

下面我们开始修改Makefile.am文件,这个文件提供给automake程序,扫描产生Makefile.in文件用的

当前根目录下面,glade-2生成的Makefile.am内容如下:

## Process this file with automake to produce Makefile.in
SUBDIRS=src po

EXTRA_DIST
=\
autogen.sh \
lunarcalendar.glade \
lunarcalendar.gladep

install
-data-local:@$(NORMAL_INSTALL)if test -d $(srcdir)/pixmaps; then \$(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/pixmaps; \for pixmap in $(srcdir)/pixmaps/*; do\if test -f $$pixmap; then \$(INSTALL_DATA) $$pixmap $(DESTDIR)$(pkgdatadir)/pixmaps; \
fi \
done \
fi

dist
-hook:if test -d pixmaps; then \
mkdir
$(distdir)/pixmaps; \for pixmap in pixmaps/*; do\if test -f $$pixmap; then \
cp
-p $$pixmap $(distdir)/pixmaps; \
fi \
done \
fi

SUBDIRS
定义了自动搜索的两个子目录。目前不需要修改
EXTRA_DIST定义的是当前目录下额外被安装、打包的文件,我们这里不需要打包这些文件,因此删除
另外几个定义的是安装数据文件时的操作,不需要修改。修改后的Makefile.am如下

## Process this file with automake to produce Makefile.in
SUBDIRS=src po

install
-data-local:@$(NORMAL_INSTALL)if test -d $(srcdir)/pixmaps; then \$(mkinstalldirs) $(DESTDIR)$(pkgdatadir)/pixmaps; \for pixmap in $(srcdir)/pixmaps/*; do\if test -f $$pixmap; then \$(INSTALL_DATA) $$pixmap $(DESTDIR)$(pkgdatadir)/pixmaps; \
fi \
done \
fi

dist
-hook:if test -d pixmaps; then \
mkdir
$(distdir)/pixmaps; \for pixmap in pixmaps/*; do\if test -f $$pixmap; then \
cp
-p $$pixmap $(distdir)/pixmaps; \
fi \
done \
fi
然后,我们再打开src目录下的Makefile.am文件
## Process this file with automake to produce Makefile.in
INCLUDES=\-DPACKAGE_DATA_DIR=\""$(datadir)"\"\-DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\"\@PACKAGE_CFLAGS@bin_PROGRAMS=lunarcalendar

lunarcalendar_SOURCES
=\
main.c \
support.c support.h \
interface.c interface.h \
callbacks.c callbacks.h

lunarcalendar_LDADD
= @PACKAGE_LIBS@ $(INTLLIBS)

这里面通过bin_PROGRAMS的方式,定义了一个可执行文件为lunarcalendar,然后其源代码为lunarcalendar_SOURCES所定义

lunarcalendar_LDADD定义的是链接lunarcalendar时,额外链接的库文件或链接选项。INCLUDES定义的是编译时的一些编译宏定义

在现在的automake版本中,已经认为这种方式是古老的方式了(估计还是因为这个定义就等于是全局性的了)。

替代的宏定义是如下:

lunarcalendar_CFLAGS =\-DPACKAGE_DATA_DIR=\""$(datadir)"\"\-DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\"\@GTKLUNARCALENDAR_CFLAGS@
lunarcalendar_LDFLAGS = @GTKLUNARCALENDAR_LIBS@ 

对于lunarcalendar_LDADD,我们删除其中的@PACKAGE_LIBS@,其他暂时保留

修改后的Makefile.am如下:

## Process this file with automake to produce Makefile.in
bin_PROGRAMS=lunarcalendar

lunarcalendar_SOURCES
=\
main.c \
support.c support.h \
interface.c interface.h \
callbacks.c callbacks.h

lunarcalendar_CFLAGS
=\-DPACKAGE_DATA_DIR=\""$(datadir)"\"\-DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\"\@GTKLUNARCALENDAR_CFLAGS@lunarcalendar_LDFLAGS= @GTKLUNARCALENDAR_LIBS@lunarcalendar_LDADD= $(INTLLIBS)

然后,我们在configure.ac中增加一个autoconf调用automake的接口,在AC_INIT之后增加一行AM_INIT_AUTOMAKE

AC_INIT(lunarcalendar, 0.1, eagle_xmw@yahoo.com.cn)
AM_INIT_AUTOMAKE

这时候,我们需要开始准备config.h.in文件了,在根目录下通过执行autoheader生成。

执行完后,会自动config.h.in文件,并自动修改configure.ac中的AC_CONFIG_SRCDIR为config.h.in

生成的config.h.in内容如下:

生成的config.h.in内容

/*config.h.in.  Generated from configure.ac by autoheader.*/

/*Define to 1 if you have the <inttypes.h> header file.*/
#undef HAVE_INTTYPES_H

/*Define to 1 if you have the <libintl.h> header file.*/
#undef HAVE_LIBINTL_H

/*Define to 1 if you have the <memory.h> header file.*/
#undef HAVE_MEMORY_H

/*Define to 1 if you have the <stdint.h> header file.*/
#undef HAVE_STDINT_H

/*Define to 1 if you have the <stdlib.h> header file.*/
#undef HAVE_STDLIB_H

/*Define to 1 if you have the <strings.h> header file.*/
#undef HAVE_STRINGS_H

/*Define to 1 if you have the <string.h> header file.*/
#undef HAVE_STRING_H

/*Define to 1 if you have the <sys/stat.h> header file.*/
#undef HAVE_SYS_STAT_H

/*Define to 1 if you have the <sys/types.h> header file.*/
#undef HAVE_SYS_TYPES_H

/*Define to 1 if you have the <unistd.h> header file.*/
#undef HAVE_UNISTD_H

/*Define to the address where bug reports for this package should be sent.*/
#undef PACKAGE_BUGREPORT

/*Define to the full name of this package.*/
#undef PACKAGE_NAME

/*Define to the full name and version of this package.*/
#undef PACKAGE_STRING

/*Define to the one symbol short name of this package.*/
#undef PACKAGE_TARNAME

/*Define to the home page for this package.*/
#undef PACKAGE_URL

/*Define to the version of this package.*/
#undef PACKAGE_VERSION

/*Define to 1 if you have the ANSI C header files.*/
#undef STDC_HEADERS

生成config.h.in文件之后,我们就可以开始准备生成configure文件及其配套脚本了。

第一步,根目录下执行aclocal,以生成aclocal.m4

第二步,根目录下执行autoconf,以生成configure

第三步,根目录下执行automake,以生成Makefile.in,这一步会检测当前目录下缺少哪些脚本,通常是缺少install-sh/missing/INSTALL/COPYING/depcomp

automake可以自动拷贝一份过来,只需要带参数-a或者--add-missing即可

这几步的动作,我们可以写到一个脚本自动化执行一下,比如autogen.sh

#! /bin/sh
aclocal|| exit $?autoheader|| exit $?automake-a || exit $?autoconf|| exit $?

到这一步,我们的程序应该可以编译、链接起来了

编译链接后,可执行文件是可以生成了,但会在最后报错,原因是po目录下面没有相应的Makefile文件

这个目录的编译处理就涉及到gettext及多国语言了。

此时的源代码:lunarcalendar.0.0.2.zip

在完成代码之后,我们开始尝试准备编译环境

glade-2在生成代码时,为我们考虑好了,自动生成了configure.in及autogen.sh。

依道理来说,只要稍做修改,我们就可以编译/链接再运行了。

但由于glade-2早在2007年就停止开发了,所以还得我们自己来动手。

这里面要用到的就是一系列工具:autoconf/automake/intltool等等。

现在的autoconf认的是configure.ac文件了。这个文件需要通过扫描代码重新生成,运行autoscan即可。生成的autoscan.log是日志信息,删除即可

生成的configure.scan就是我们要的东西,基于这个文件基础之上进行修改

configure.scan最初的内容

#-*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([FULL
-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([src
/callbacks.h])
AC_CONFIG_HEADERS([config
.h])#Checks for programs. AC_PROG_CXX
AC_PROG_CC
AC_PROG_MAKE_SET
#Checks for libraries.

# Checks for header files.
AC_CHECK_HEADERS([libintl.h string.h unistd.h])#Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.
AC_CONFIG_FILES([Makefile
src
/Makefile])
AC_OUTPUT

configure.scan进行修改之后就可以改名为configure.ac,替换glade-2生成的configure.in。这个文件使用的m4语法。

首先,我们要修改的是包名:

AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])

修改为:

AC_INIT(lunarcalendar, 0.1, eagle_xmw@yahoo.com.cn)

对比configure.in,我们还需要增加检测系统是否包含gtk+-2.0及lunar-calendar-2.0这两个包

即在“# Checks for libraries.”增加下面增加如下内容

# Checks for libraries.
pkg_modules="gtk+-2.0 >= 2.10.0 lunar-calendar-2.0 >= 2.4"PKG_CHECK_MODULES(PACKAGE, [$pkg_modules])
AC_SUBST(PACKAGE_CFLAGS)
AC_SUBST(PACKAGE_LIBS)

上面是简单拷贝,再增加模块检查,其实,我们应该将其中的PACKAGE修改成合适的名字,比如,修改为:

#Checks for libraries.
pkg_modules="gtk+-2.0 >= 2.10.0 lunar-calendar-2.0 >= 2.4"PKG_CHECK_MODULES(GTKLUNARCALENDAR, [$pkg_modules])
AC_SUBST(GTKLUNARCALENDAR_CFLAGS)
AC_SUBST(GTKLUNARCALENDAR_LIBS)

修改完之后,改名为configure.ac,对于这个文件的修改,我们先到这儿

 

原文链接: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