系统程序员成长计划-工程管理(四)
转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog
作者联系方式:李先静 <xianjimli at hotmail dot com>
应用程序
前面我们创建的helloworld是一个应用程序工程,它很简单,只使用了标准C的函数。现在我们要建立一个应用程序工程,它将使用前面所写的libbase函数库。
o目录结构
最顶层目录名用模块名称,这里用appdemo。
源文件放在模块下的src子目录里,即appdemo/src。
o 创建源文件
在src下创建源文件main.c,内容只是简单的调用一下libbase里的函数。
#include <dlist.h>
int main(int argc, char* argv[])
{
DList* dlist = dlist_create(NULL, NULL);
dlist_destroy(dlist);
return 0;
}
o 创建Makefile模板
创建helloworld/Makefile.am,内容为:
SUBDIRS=src
这里只有简单的一行代码,表示其下有一个src的子目录,如果有多个子目录,用空格分开就行了。
创建helloworld/src/Makefile.am,内容为:
bin_PROGRAMS=appdemo
appdemo_SOURCES=main.c
appdemo_CFLAGS=@BASE_CFLAGS@
appdemo_LDFLAGS=@BASE_LIBS@
appdemo_CFLAGS指定了编译appdemo时需要的参数,@BASE_CFLAGS@ 将替换成实际configure时所得到的参数。
appdemo_LDFLAGS是链接appdemo时需要的参数。@BASE_LIBS@ 将替换成实际configure时所得到的参数。
至于@BASE_CFLAGS@和@BASE_LIBS@是怎么得到的,后面我们再讲。
o 创建autoconf的模板。
在appdemo下运行autoscan,生成文件configure.scan,把它改名为configure.in。这是autoconf的模板文件,它的内容大概为:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile
src/Makefile])
AC_OUTPUT
按照前面介绍的方法,把configure.in的内容修改为:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
AC_INIT(appdemo, 0.1, xianjimli@hotmail.com)
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_HEADER([config.h])
AM_INIT_AUTOMAKE(appdemo, 0.1)
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile
src/Makefile])
AC_OUTPUT
与前面不同的是,我们还需要在# Checks for libraries. 之后加检查libbase参数的宏:
PKG_CHECK_MODULES(BASE, ["base"])
AC_SUBST(BASE_CFLAGS)
AC_SUBST(BASE_LIBS)
PKG_CHECK_MODULES(BASE, ["base"]) 的功能是检查软件包base,通过调用前面所讲的pkg-config,生成 BASE_CFLAGS和 BASE_LIBS两个变量。
AC_SUBST(BASE_CFLAGS) 的功能是把所有对 BASE_CFLAGS的引用替换成实际的参数。
o 拷贝所用到宏。
运行:aclocal
o 产生配置头文件的模板。
运行:autoheader
o 创建几个必要的文件。
README:描述模块的功能、用法和注意事项等。
NEWS:描述模块最新的动态。
AUTHORS:模块的作者及联系方式。
ChangeLog:记录模块的修改历史,它有固定的格式:
o 生成Makefile.in和所需要的脚本。
运行:automake -a
o 产生configure脚本。
运行:autoconf
o 产生最终的Makefile。
运行:./configure –prefix=$HOME/usr
这时会出现错误:
No package 'base' found
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
在默认情况下,pkg-config只是在/usr/lib/pkgconfig下查找相关的pc文件。如果pc文件安装在其它目录,需要设置环境变量 PKG_CONFIG_PATH。
export PKG_CONFIG_PATH=$HOME/usr/lib/pkgconfig
重新configure,一切正常了。
o 编译
运行:make
o 安装
运行:make install
o 发布软件包
运行:make dist或者make distcheck
本章所讲的内容中可应付90%的情况了,如果需要使用更高级的特性,可以阅读相应的手册。