如何自动生成makefile

来源:互联网 发布:网络用语uc是什么意思 编辑:程序博客网 时间:2024/05/06 15:43
GNU make允许将一个软件项目的代码分开放在不同的源文件里,有改动的时候可以只对改动的文件重新编译,然后重新连接,这种编译管理方法提高了生成目标的效率。make要调用一个makefile文件来实现。
Makefile的编写是使用make的关键问题。当工程里面包含的很多源文件,库,文件放在不同的子目录时,手动书写makefile文件不方便且容易出错。一般情况下我们用autoconf和automake自动生成makefile文件。
自动生成makefile流程
如图所示为automake,autoconf生成makefile的过程(简化)。
                                    程序源码
                                           |
                                     autoscan*
                                           |
                                configure.scan
                                           |
                                    编译修改*
                                            |
             makefile.am   configure.in --aclocal*--> aclocal.m4
                           \  ____  /           \  __________  /
                                 \ /                           \ /
                         automake*             autoconf*
                               |                              |
                            makefile.in       configure
                                          \  ____  /
                                               \  /
                                        ./configure*
                                                |
                                          makefile
为一个项目源文件生成makefile并make的步骤如下:
操作在包含源文件的项目目录下进行。
(1). 运行autoscan,生成文件configure.scan。
(2). 修改configure.scan,改名为configure.in。
(3).运行autoheader,生成文件configure.h.in(现在一般改为configure.ac)。configure.in里有宏AC_CONFIG_HEADER()时用。
(4).运行libtoolize,生成一些支持文件,ltmain.sh。需要用libtool生成共享库用。
(5).运行allocal,生成aclocal.m4。
(6). 运行autoconf,生成configure。
(7).为源文件编写makefie.am,每一个包含源文件的目录和子目录都有一个makefile.am。
(8).运行automake,生成makefile.in,每个包含makefile.am的子目录都生成makefile.in。
automake -a选项可以补齐文件config.guess,config.sub,install-sh,missing,depcomp。
(9).运行./configure,生成config.status,config.h,makefile。
(10).运行make,生成中间文件对象文件,库文件,最后生成可执行文件。
(11).运行make install,相应的可执行文件,库文件,头文件拷贝到系统相应位置。

自动生成makefile例子
这个例子共有三个C文件,main.c,add/add.c和sub/sub.c。源代码如下:
/*main.c*/
#include<stdio.h>
int main(void)
{
printf("%d\n",add(sub(100,5),1));
return 0;
}
/* add/add.c */
int add(int x,int y)
{
return x+y;
}
/* sub/sub.c */
int sub(int x,int y)
{
return x-y;
}
这个例子中add.c和sub.c被编译成动态连接库,然后main.c与这两个库连接生成可执行文件。
1.手动输入configure.in和makefile.am
Q:自动生成makefile需要手动输入什么文件,作用是什么?
按照上面的步骤执行,需要手动输入的文件只有两类configure.in和makefile.am。
(1).手动修改configure.in
autoscan运行后configure.scan文件为(系统不一样可能略有会不同)
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.63])
AC_INIT([FULL-PACKAGE-NAME],[VERSION],[BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([main.c])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT
手动修改为configure.in:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.63])
AC_INIT(hellobb,1.0,[])
AM_INIT_AUTOMAKE(hellobb,1.0)
AC_CONFIG_SRCDIR([main.c])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CC
AC_PROG_LIBTOOL
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT(Makefile add/Makefile sub/Makefile)

其中宏AC_INIT和AC_OUTPUT是必需的,AC_INIT放在开头,AC_OUTPUT放在结尾。
AC_INIT:说明软件包的名字,版本等。
AC_OUTPUT:说明生成的shell脚本文件configure运行后输出的文件。
AM_INIT_AUTOMAKE:用automake需要的宏。
AC_PROG_CC:决定要使用的C编译器。如果环境变量CC没有值,检查gcc和cc,别的C编译器。设置变量CC的值为找到的编译器名称。
AC_PROG_LIBTOOL:检查LIBTOOL。
AC_CONFIG_SRCDIR([main.c]):./configure检查在给它的目录里是否有main.c文件。
AC_CONFIG_HEADER([config.h]):./configure从config.h.in中生成config.h文件,config.h文件是包含了很多#define宏的c头文件。当编译文件的时候,用一个宏-DHAVE_CONFIG_H代替原来需要用-Dmacro传递的所有预处理宏集合。
例如屏蔽掉这句#AC_CONFIG_HEADER([config.h]),make时编译main.c的命令是
gcc -DPACKAGE_NAME=\"hellobb\" -DPACKAGE_TARNAME=\"hellobb\" -DPACKAGE-VERSION=\"1.0\" -DPACKAGE_STRING=\"hellobb\ 1.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"hellobb\" -DVERSION=\"1.0\" -DSTDC_HEADERS=1 _DHAVE_SYS_TYPES_H=1 -DHAVE_UNISTDLIB_H=1 -DHAVE_STING_H=1 -DHAVE_MEMORY_H=1 -dHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\"./libs/\" -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.c main.c
如果启用AC_CONFIG_HEADER([config.h]),make时编译main.c的命令是
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
上面那些宏-Dmacro都包含在config.h里了,我们只需要给编译器传递-DHAVE_CONFIG_H就行了
0 0
原创粉丝点击