网络资源:http://www.worldhello.net/2010/04/07/954.html
MakeFile文件简介
Makefile是用于自动编译和链接的,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是所有的文件都需要重新编译,Makefile中纪录有文件的信息,在make时会决定在链接的时候需要重新编译哪些文件。
Makefile的宗旨就是:让编译器知道要编译一个文件需要依赖其他的哪些文件。当那些依赖文件有了改变,编译器会自动的发现最终的生成文件已经过时,而重新编译相应的模块。
Makefile的基本结构不是很复杂,但当一个程序开发人员开始写Makefile时,经常会怀疑自己写的是否符合惯例,而且自己写的Makefile经常和自己的开发环境相关联,当系统环境变量或路径发生了变化后,Makefile可能还要跟着修改。这样就造成了手工书写Makefile的诸多问题,automake恰好能很好地帮助我们解决这些问题。
使用automake,程序开发人员只需要写一些简单的含有预定义宏的文件,由autoconf根据一个宏文件生成configure,由automake根据另一个宏文件生成Makefile.in,再使用configure依据Makefile.in来生成一个符合惯例的Makefile。下面我们将详细介绍Makefile的automake生成方法。
-使用环境
本文所提到的程序是基于Linux发行版本:Ubuntu10.04,它包含了我们要用到的autoconf,automake。
-具体步骤
对于一个较大的项目而言,完全手动建立Makefile是一件费力而又容易出错的工作。autotools系列工具只需用户输入简单的目标文件、依赖文件、文件目录等就可以比较轻松地生成Makefile了。现在Linux上的软件开发一般都是用autotools来制作Makefile。
具体实例:
----------
在/root/project/main目录下创建一个文件main.c,其内容如下:
------------------------------------------------
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Hello, Auto Makefile!\n");
return 0;
}
------------------------------------------------
具体步骤如下:
(1)autoscan
使用autoscan在给定目录及其子目录树中检查源文件,如果没有给出目录,就在当前目录及其子目录树中进行检查。最终生成两个文件:configure.scan、autoscan.log
(2)修改configure.scan的文件名为configure.in
命令:mv configure.scan configure.in
(3)修改configure.in的内容:
configure.in的内容说明:
configure.in文件内容如下:
# -*- 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([main.cpp])
AC_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CXX
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
说明:
1、以“#”号开始的是行为注释。
2、AC_PREREQ宏声明本文件要求的autoconf版本。
3、AC_INIT宏用来定义软件的名称和版本等信息,这里的BUG-REPORT- ADDRESS可以省略。
4、AC_CONFIG_SRCDIR宏用来侦测所指定的源码文件是否存在,
来确定源码目录的有效性。这个参数一般不需要修改。
5、AC_CONFIG_HEADER宏用于生成config.h文件,以便autoheader使用。
修改时需要增加一个宏AM_INIT_AUTOMAKE(PACKAGE,VERSION)
具体如下:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
AC_INIT(main, 1.0, wyylling@126.com)
AM_INIT_AUTOMAKE(main,1.0)
AC_CONFIG_SRCDIR([main.cpp])
#AC_CONFIG_HEADER([config.h])
AM_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CXX
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
我的configure.in下面的真实内容:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.65])
AC_INIT(lda, 1.0, 1527zhaobin@163.com)
AM_INIT_AUTOMAKE(lda,1.0)
AC_CONFIG_SRCDIR([lda.h])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h])
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([memset])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
(4)运行aclocal,生成一个“aclocal.m4”文件和一个缓冲文件夹autom4te.cache,该文件主要处理本地的宏定义。
此时的状态是:
[root@localhost main]# aclocal
[root@localhost main]# ls
aclocal.m4 autom4te.cache autoscan.log configure.in configure.in~ main.c
[root@localhost main]#
(5)运行 autoconf, 目的是生成 configure
此时的状态是:
[root@localhost main]# autoconf
[root@localhost main]# ls
aclocal.m4 autoscan.log configure.in main.c
autom4te.cache configure configure.in~
[root@localhost main]#
(6)运行 autoheader,它负责生成config.h.in文件。该工具通常会从“acconfig.h”文件中复制用户附加的符号定义,因此此处没有附加符号定义,所以不需要创建“acconfig.h”文件。
此时的状态是:
[root@localhost main]# autoheader
[root@localhost main]# ls
aclocal.m4 autoscan.log configure configure.in~
autom4te.cache config.h.in configure.in main.c
[root@localhost main]#
(7)配置脚本文件Makefile.am
新建Makefile.am文件,命令:
$ vi Makefile.am
内容如下:
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=helloworld
helloworld_SOURCES=helloworld.c
automake会根据你写的Makefile.am来自动生成Makefile.in。
下面对该脚本文件的对应项进行解释。
其中的AUTOMAKE_OPTIONS为设置automake的选项。由于GNU(在第1章中已经有所介绍)对自己发布的软件有严格的规范,比如必须附 带许可证声明文件COPYING等,否则automake执行时会报错。automake提供了三种软件等级:foreign、gnu和gnits,让用 户选择采用,默认等级为gnu。在本例使用foreign等级,它只检测必须的文件。
bin_PROGRAMS定义要产生的执行文件名。如果要产生多个执行文件,每个文件名用空格隔开。
main_SOURCES定义“main”这个执行程序所需要的原始文件。如果”main”这个程序是由多个原始文件所产生的,则必须把它所用到的所有原 始文件都列出来,并用空格隔开。例如:若目标体“main”需要“main.c”、“sunq.c”、“main.h”三个依赖文件,则定义 main_SOURCES=main.c sunq.c main.h。要注意的是,如果要定义多个执行文件,则对每个执行程序都要定义相应的file_SOURCES。例如,某个Makefile文件内容如下(编译生成三个文件:hello,pthread,tty):
AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = hello pthread tty
hello_SOURCES = hello.c
pthread_SOURCES = pthread.c
tty_SOURCES = tty.c
我的Makefile.am文件内容:
AUTO_OPTIONS=foreign
bin_PROGRAMS= lda
lda_SOURCES= lda.cc file_access.cc document.cc lda.h file_access.h document.h
(8)将运行 automake
[root@localhost main]# automake --add-missing
使用automake对其生成“configure.in”文件,在这里使用选项“—adding-missing”可以让automake自动添加有一些必需的脚本文件。
运行后的状态是:
configure.in:8: installing `./missing'
configure.in:8: installing `./install-sh'
Makefile.am: installing `./depcomp'
[root@localhost main]# ls
aclocal.m4 config.h.in configure.in~ main.c Makefile.in
autom4te.cache configure depcomp Makefile.am missing
autoscan.log configure.in install-sh Makefile.am~
[root@localhost main]#
在这一步中往往会产生一种错误如下:
configure.in: required file `./install-sh' not found
configure.in: required file `./mkinstalldirs' not found
configure.in: required file `./missing' not found
Makefile.am: required file `./COPYING' not found
Makefile.am: required file `./INSTALL' not found
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
Makefile.am: required file `./depcomp' not found
我们将进行如下处理:
Additionally, the INSTALL, NEWS, README, COPYING, AUTHORS and ./ChangeLog files need to be created:
touch INSTALL NEWS README AUTHORS ChangeLog
(9)运行configure,在这一步中,通过运行自动配置设置文件configure,把Makefile.in变成了最终的Makefile。
运行的结果如下:
------------------------------------------------
[root@localhost main]# ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
[root@localhost main]# ls
aclocal.m4 config.h.in configure.in main.c Makefile.in
autom4te.cache config.log configure.in~ Makefile missing
autoscan.log config.status depcomp Makefile.am stamp-h1
config.h configure install-sh Makefile.am~
[root@localhost main]#
(10)运行 make,对配置文件Makefile进行测试一下
此时的状态如下:
------------------------------------------------
[root@localhost main]# make
cd . && /bin/sh /root/project/main/missing --run aclocal-1.10
cd . && /bin/sh /root/project/main/missing --run automake-1.10 --foreign
cd . && /bin/sh /root/project/main/missing --run autoconf
/bin/sh ./config.status --recheck
running CONFIG_SHELL=/bin/sh /bin/sh ./configure --no-create --no-recursion
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
/bin/sh ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing depfiles commands
cd . && /bin/sh /root/project/main/missing --run autoheader
rm -f stamp-h1
touch config.h.in
make all-am
make[1]: Entering directory `/root/project/main'
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc -g -O2 -o main main.o
cd . && /bin/sh ./config.status config.h
config.status: creating config.h
config.status: config.h is unchanged
make[1]: Leaving directory `/root/project/main'
[root@localhost main]# ls
aclocal.m4 autoscan.log config.h.in config.status configure.in depcomp main main.o Makefile.am Makefile.in stamp-h1
autom4te.cache config.h config.log configure configure.in~ install-sh main.c Makefile Makefile.am~ missing
[root@localhost main]#
------------------------------------------------
(11)运行生成的文件 main:
------------------------------------------------
[root@localhost main]# ./main
Hello, Auto Makefile!
[root@localhost main]#
补充:
Makefile
在符合GNU Makefiel惯例的Makefile中,包含了一些基本的预先定义的操作:
make
根据Makefile编译源代码,连接,生成目标文件,可执行文件。
make clean
清除上次的make命令所产生的object文件(后缀为“.o”的文件)及可执行文件。
make install
将编译成功的可执行文件安装到系统目录中,一般为/usr/local/bin目录。
make dist
产生发布软件包文件(即distribution package)。这个命令将会将可执行文件及相关文件打包成一个tar.gz压缩的文件用来作为发布软件的软件包。
它会在当前目录下生成一个名字类似“PACKAGE-VERSION.tar.gz”的文件。PACKAGE和VERSION,是我们在configure.in中定义的AM_INIT_AUTOMAKE(PACKAGE, VERSION)。
make distcheck
生成发布软件包并对其进行测试检查,以确定发布包的正确性。这个操作将自动把压缩包文件解开,然后执行configure命令,并且执行make,来确认编译不出现错误,最后提示你软件包已经准备好,可以发布了。
===============================================
helloworld-1.0.tar.gz is ready for distribution
===============================================
make distclean
类似make clean,但同时也将configure生成的文件全部删除掉,包括Makefile。
posted on 2012-04-24 20:33
愤怒的考拉 阅读(691)
评论(0) 编辑 收藏