admin 发布的文章

我们目前用的autogen.sh是很简陋的,没有测试系统中是否包含要用到的工具

正式的autogen.sh如下:

#! /bin/sh# Allow invocation from a separate build directory;in that case, we change
# to the source directory to run the auto
*, thenchange back before running configure
srcdir
=`dirname $0`
test
-z "$srcdir" && srcdir=.

ORIGDIR
=`pwd`
cd $srcdir

LIBTOOLIZE_FLAGS
="--force --automake"#ACLOCAL_FLAGS="-I autotools $ACLOCAL_FLAGS"AUTOMAKE_FLAGS="--foreign --add-missing"DIE=0(autoconf--version) < /dev/null > /dev/null 2>&1 ||{echo echo "You must have autoconf installed to compile $PROJECT." echo "Install the appropriate package for your distribution," echo "or get the source tarball at http://ftp.gnu.org/gnu/autoconf/"DIE=1}

(automake
--version) < /dev/null > /dev/null 2>&1 ||{echo echo "You must have automake installed to compile $PROJECT." echo "Install the appropriate package for your distribution," echo "or get the source tarball at http://ftp.gnu.org/gnu/automake/"DIE=1}

LIBTOOLIZE
=libtoolize
($LIBTOOLIZE
--version) < /dev/null > /dev/null 2>&1 ||{
LIBTOOLIZE
=glibtoolize
($LIBTOOLIZE
--version) < /dev/null > /dev/null 2>&1 ||{echo echo "You must have libtool installed to compile $PROJECT." echo "Install the appropriate package for your distribution," echo "or get the source tarball at http://ftp.gnu.org/gnu/libtool/"DIE=1}
}
if test "$DIE" -eq 1; thenexit1 fi rm -rf $top_srcdir/autom4te.cachetouchREADME INSTALL

aclocal $ACLOCAL_FLAGS
|| exit $?$LIBTOOLIZE $LIBTOOLIZE_FLAGS|| exit $?autoheader|| exit $?automake $AUTOMAKE_FLAGS|| exit $?autoconf|| exit $?cd $ORIGDIR|| exit 1$srcdir/configure $AUTOGEN_CONFIGURE_ARGS "$@" || exit $?

 

生成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,对于这个文件的修改,我们先到这儿