C++自动生成Makefile的详细过程
时间:2011-01-05 来源:自语的骆驼
在Linux下编写大型的程序离不开Makefiel文件,摸索了两天终于搞明白了利用autoconf和automake自动生成Makefile的过程,在此做个笔记,以免忘记。下面开始自动生成Makefile的详细过程
第一步:用终端切换到到编译的文件夹目录下面:
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn$ cd rainol_client/
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ls
main.cpp rainol_client.cpp rainol_client.h
------------------------------------------------
有三个源文件,如上。
第二步:运行 autoscan , 自动创建两个文件: autoscan.log configure.scan
------------------------------------------------
此时状态如下:
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ autoscan
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ls
autoscan.log configure.scan main.cpp rainol_client.cpp rainol_client.h
------------------------------------------------
第三步:把文件名config.scan修改为config.in,查看其内容为
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ mv configure.scan configure.in
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ cat configure.in
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.64])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([rainol_client.cpp])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
# Checks for library functions.
AC_CHECK_FUNCS([bzero socket])
AC_OUTPUT
------------------------------------------------
解读以上的文件:
------------------------------------------------
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
# AC_PREREQ:
# 确保使用的是足够新的Autoconf版本。如果用于创建configure的Autoconf的版
# 本比version 要早,就在标准错误输出打印一条错误消息并不会创建configure。
AC_PREREQ(2.61)
#
# 初始化,定义软件的基本信息,包括设置包的全称,版本号以及报告BUG时需要用的邮箱地址
#
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
#
# 用来侦测所指定的源码文件是否存在,来确定源码目录的有效性
#
AC_CONFIG_SRCDIR([main.c])
#
# 用于生成config.h文件,以便autoheader使用
#
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.
#
# 创建输出文件。在`configure.in'的末尾调用本宏一次。
#
AC_OUTPUT
------------------------------------------------
修改动作:
1.修改AC_INIT里面的参数: AC_INIT(main,1.0, [email protected])
2.添加宏AM_INIT_AUTOMAKE, 它是automake所必备的宏,也同前面一样,PACKAGE是所要产生软件套件的名称,VERSION是版本编号。
3.在AC_OUTPUT后添加输出文件Makefile
修改后的结果:
------------------------------------------------
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.64])
AC_INIT(rainol_client,1.0,[email protected])
AC_CONFIG_SRCDIR([rainol_client.cpp])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE(rainol_client,1.0)
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
# Checks for library functions.
AC_CHECK_FUNCS([bzero socket])
AC_OUTPUT([Makefile])
------------------------------------------------
第四步:运行aclocal, 生成一个“aclocal.m4”文件和一个缓冲文件夹autom4te.cache,该文件主要处理本地的宏定义。
此时的状态是:
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ aclocal
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ls
aclocal.m4 autom4te.cache autoscan.log configure.in main.cpp rainol_client.cpp rainol_client.h
------------------------------------------------
第五步:运行 autoconf, 目的是生成 configure
此时的状态是:
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ autoconf
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ls
aclocal.m4 autom4te.cache autoscan.log configure configure.in main.cpp rainol_client.cpp rainol_client.h
------------------------------------------------
第六步:
运行 autoheader,它负责生成config.h.in文件。该工具通常会从“acconfig.h”文件中复制用户附加的符号定义,因此此处没有附加符号定义,所以不需要创建“acconfig.h”文件。
此时的状态是:
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ autoheader
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ls
aclocal.m4 autom4te.cache autoscan.log config.h.in configure configure.in main.cpp rainol_client.cpp rainol_client.h
------------------------------------------------
第七步:
下面即将运行 automake, 但在此之前应该做一下准备工作!
首先
创建一个 Makefile.am.这一步是创建Makefile很重要的一步,automake要用的脚本配置文件是Makefile.am,用户需要自己创建相应的文件。之后,automake工具转换成Makefile.in。
这个Makefile.am的内容如下:
------------------------------------------------
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=rainol_client
rainol_client_SOURCES=rainol_client.cpp main.cpp rainol_client.h
------------------------------------------------
下面对该脚本文件的对应项进行解释。
其中的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。
其次
使用automake对其生成“configure.in”文件,在这里使用选项“—adding-missing”可以让automake自动添加有一些必需的脚本文件。
运行后的状态是:
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ automake --add-missing
configure.in:8: installing `./install-sh'
configure.in:8: installing `./missing'
Makefile.am: installing `./depcomp'
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ls
aclocal.m4 autoscan.log configure depcomp main.cpp Makefile.in rainol_client.cpp
autom4te.cache config.h.in configure.in install-sh Makefile.am missing rainol_client.h
rychao@ubuntu:~/workspace/linux_learn/rainol_client$
------------------------------------------------
第八步
运行configure,在这一步中,通过运行自动配置设置文件configure,把Makefile.in变成了最终的Makefile。
运行的结果如下:
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ./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... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking for g++... g++
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 g++ accepts -g... yes
checking for style of include used by make... GNU
checking dependency style of g++... gcc3
checking for gcc... gcc
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 dependency style of gcc... gcc3
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking arpa/inet.h usability... yes
checking arpa/inet.h presence... yes
checking for arpa/inet.h... yes
checking netdb.h usability... yes
checking netdb.h presence... yes
checking for netdb.h... yes
checking netinet/in.h usability... yes
checking netinet/in.h presence... yes
checking for netinet/in.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking sys/socket.h usability... yes
checking sys/socket.h presence... yes
checking for sys/socket.h... yes
checking for unistd.h... (cached) yes
checking for stdbool.h that conforms to C99... yes
checking for _Bool... yes
checking for bzero... yes
checking for socket... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
rychao@ubuntu:~/workspace/linux_learn/rainol_client$
第九步
运行 make,对配置文件Makefile进行测试一下,这样就可以编译程序了。
第一步:用终端切换到到编译的文件夹目录下面:
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn$ cd rainol_client/
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ls
main.cpp rainol_client.cpp rainol_client.h
------------------------------------------------
有三个源文件,如上。
第二步:运行 autoscan , 自动创建两个文件: autoscan.log configure.scan
------------------------------------------------
此时状态如下:
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ autoscan
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ls
autoscan.log configure.scan main.cpp rainol_client.cpp rainol_client.h
------------------------------------------------
第三步:把文件名config.scan修改为config.in,查看其内容为
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ mv configure.scan configure.in
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ cat configure.in
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.64])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([rainol_client.cpp])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
# Checks for library functions.
AC_CHECK_FUNCS([bzero socket])
AC_OUTPUT
------------------------------------------------
解读以上的文件:
------------------------------------------------
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
# AC_PREREQ:
# 确保使用的是足够新的Autoconf版本。如果用于创建configure的Autoconf的版
# 本比version 要早,就在标准错误输出打印一条错误消息并不会创建configure。
AC_PREREQ(2.61)
#
# 初始化,定义软件的基本信息,包括设置包的全称,版本号以及报告BUG时需要用的邮箱地址
#
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
#
# 用来侦测所指定的源码文件是否存在,来确定源码目录的有效性
#
AC_CONFIG_SRCDIR([main.c])
#
# 用于生成config.h文件,以便autoheader使用
#
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.
#
# 创建输出文件。在`configure.in'的末尾调用本宏一次。
#
AC_OUTPUT
------------------------------------------------
修改动作:
1.修改AC_INIT里面的参数: AC_INIT(main,1.0, [email protected])
2.添加宏AM_INIT_AUTOMAKE, 它是automake所必备的宏,也同前面一样,PACKAGE是所要产生软件套件的名称,VERSION是版本编号。
3.在AC_OUTPUT后添加输出文件Makefile
修改后的结果:
------------------------------------------------
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.64])
AC_INIT(rainol_client,1.0,[email protected])
AC_CONFIG_SRCDIR([rainol_client.cpp])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE(rainol_client,1.0)
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
# Checks for library functions.
AC_CHECK_FUNCS([bzero socket])
AC_OUTPUT([Makefile])
------------------------------------------------
第四步:运行aclocal, 生成一个“aclocal.m4”文件和一个缓冲文件夹autom4te.cache,该文件主要处理本地的宏定义。
此时的状态是:
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ aclocal
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ls
aclocal.m4 autom4te.cache autoscan.log configure.in main.cpp rainol_client.cpp rainol_client.h
------------------------------------------------
第五步:运行 autoconf, 目的是生成 configure
此时的状态是:
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ autoconf
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ls
aclocal.m4 autom4te.cache autoscan.log configure configure.in main.cpp rainol_client.cpp rainol_client.h
------------------------------------------------
第六步:
运行 autoheader,它负责生成config.h.in文件。该工具通常会从“acconfig.h”文件中复制用户附加的符号定义,因此此处没有附加符号定义,所以不需要创建“acconfig.h”文件。
此时的状态是:
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ autoheader
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ls
aclocal.m4 autom4te.cache autoscan.log config.h.in configure configure.in main.cpp rainol_client.cpp rainol_client.h
------------------------------------------------
第七步:
下面即将运行 automake, 但在此之前应该做一下准备工作!
首先
创建一个 Makefile.am.这一步是创建Makefile很重要的一步,automake要用的脚本配置文件是Makefile.am,用户需要自己创建相应的文件。之后,automake工具转换成Makefile.in。
这个Makefile.am的内容如下:
------------------------------------------------
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=rainol_client
rainol_client_SOURCES=rainol_client.cpp main.cpp rainol_client.h
------------------------------------------------
下面对该脚本文件的对应项进行解释。
其中的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。
其次
使用automake对其生成“configure.in”文件,在这里使用选项“—adding-missing”可以让automake自动添加有一些必需的脚本文件。
运行后的状态是:
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ automake --add-missing
configure.in:8: installing `./install-sh'
configure.in:8: installing `./missing'
Makefile.am: installing `./depcomp'
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ls
aclocal.m4 autoscan.log configure depcomp main.cpp Makefile.in rainol_client.cpp
autom4te.cache config.h.in configure.in install-sh Makefile.am missing rainol_client.h
rychao@ubuntu:~/workspace/linux_learn/rainol_client$
------------------------------------------------
第八步
运行configure,在这一步中,通过运行自动配置设置文件configure,把Makefile.in变成了最终的Makefile。
运行的结果如下:
------------------------------------------------
rychao@ubuntu:~/workspace/linux_learn/rainol_client$ ./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... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking for g++... g++
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 g++ accepts -g... yes
checking for style of include used by make... GNU
checking dependency style of g++... gcc3
checking for gcc... gcc
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 dependency style of gcc... gcc3
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking arpa/inet.h usability... yes
checking arpa/inet.h presence... yes
checking for arpa/inet.h... yes
checking netdb.h usability... yes
checking netdb.h presence... yes
checking for netdb.h... yes
checking netinet/in.h usability... yes
checking netinet/in.h presence... yes
checking for netinet/in.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking sys/socket.h usability... yes
checking sys/socket.h presence... yes
checking for sys/socket.h... yes
checking for unistd.h... (cached) yes
checking for stdbool.h that conforms to C99... yes
checking for _Bool... yes
checking for bzero... yes
checking for socket... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
rychao@ubuntu:~/workspace/linux_learn/rainol_client$
第九步
运行 make,对配置文件Makefile进行测试一下,这样就可以编译程序了。
相关阅读 更多 +