Linux下Makefile的编写

发布: 2007-06-05 16:49

Makefile是什么东西?
有哪些步骤?
每步都有什么目的?

序。  Makefile 是什么?
  Makefile是用于自动编译和链接的,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是所有的文件都需要重新编译,Makefile中纪录有文件的信息,在make时会决定在链接的时候需要重新编译哪些文件。

  Makefile的宗旨就是:让编译器知道要编译一个文件需要依赖其他的哪些文件。当那些依赖文件有了改变,编译器会自动的发现最终的生成文件已经过时,而重新编译相应的模块。

  Makefile的基本结构不是很复杂,但当一个程序开发人员开始写Makefile时,经常会怀疑自己写的是否符合惯例,而且自己写的Makefile经常和自己的开发环境相关联,当系统环境变量或路径发生了变化后,Makefile可能还要跟着修改。这样就造成了手工书写Makefile的诸多问题,automake恰好能很好地帮助我们解决这些问题。

  使用automake,程序开发人员只需要写一些简单的含有预定义宏的文件,由autoconf根据一个宏文件生成configure,由automake根据另一个宏文件生成Makefile.in,再使用configure依据Makefile.in来生成一个符合惯例的Makefile。下面我们将详细介绍Makefile的automake生成方法。

一。Makefile 编写工具链介绍

  automake,autoconf,autoscan,aclocal
 
  autoconf(2.13)中文手册
  GNU Automake(1.3, 3)中文手册


二。编写步骤

  1。为各目录(包括根目录和所有子目录)编写Makefile.am文件
      一些说明的地方,即Makefile.am应该怎么写。

      ksou/Makefile.am模板:
          EXTRA_DIST = BUGS ChangeLog.O
          SUBDIRS =    src

      ksou/src/Makefile.am 模板:
            AUTOMAKE_OPTIONS = foreign
            bin_PROGRAMS = ksou
            ksou_SOURCES = main.cpp ksou.h
            ksou_LDADD = $(INTLLIBS) $(ALLOCA)
            localedir = $(datadir)/locale
            INCLUDES = -I../intl -DLOCALEDIR="$(localedir)"
  2。执行autoscan以生成Configure.in 的模板 Configure.scan
    假设目录结构如下所示
    ksou/  项目根目录
    ksou/src  源程序目录
    ksou/src/main.cpp  入口main 所在文件
    ksou/src/ksou.h    某个头文件
    要求:这两个源文件要能输出hello world 吧。:)
   
    sh> autoscan
    sh> ls
        autoscan-2.5x.log  configure.scan  src
    sh>mv configure.scan configure.in
    用你喜欢的编辑器编辑configure.in文件
    一些要说明的宏

    简单的configure.in模板:
        #                        -*- Autoconf -*-
        # Process this file with autoconf to produce a configure script.
       
        AC_PREREQ(2.59)
       
        AC_INIT(ksou, 0.1, jason@ksou.org)
        AM_INIT_AUTOMAKE(1.6.1)
       
        AC_CONFIG_SRCDIR([src/ksou.h])
        AC_CONFIG_HEADER([src/config.h])
       
       
       
        # Checks for programs.
        AC_PROG_CXX
        #AC_PROG_CC
       
        # Checks for libraries.
       
        # Checks for header files.
        AC_HEADER_STDC
        AC_CHECK_HEADERS([stdlib.h])
       
        # Checks for typedefs, structures, and compiler characteristics.
       
        # Checks for library functions.
       
        AC_CONFIG_FILES([Makefile src/Makefile])
        AC_OUTPUT

  3。执行aclocal以生成aclocal.m4
    sh> aclocal
    sh> ls
        aclocal.m4  autom4te.cache  autoscan-2.5x.log  configure.in            src

  4。执行autoconf 以生成Configure脚本
    sh> autoconf
    sh> ls
        aclocal.m4  autom4te.cache  autoscan-2.5x.log  configure
        configure.in  src



  5。在你指定的地方加上config.h.in模板,这个是在根目录的 configure.in中指定的。它将在automake的时候生成config.h,生成一个与程序相关的宏定义以供程序使用。

    config.h.in模板:
        /* src/config.h.in.  Generated from configure.in by autoheader.  */
       
        /* Define to 1 if you have the <inttypes.h> header file. */
        #undef HAVE_INTTYPES_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
       
        /* Name of package */
        #undef PACKAGE
       
        /* 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 version of this package. */
        #undef PACKAGE_VERSION
       
        /* Define to 1 if you have the ANSI C header files. */
        #undef STDC_HEADERS
       
        /* Version number of package */
        #undef VERSION




  6。执行automake生成Makefile
    sh> automake --add-missing
    有可能出现下面输出:
        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
    手工创建这些文件即可,即使为空文件也成。再次执行automake --add-missing看是否还会有什么错误。如果没有,则有如果结果:
    sh> ls
          total 221
          lrwxrwxrwx  1 jason None    31 Jul 23 17:28 COPYING -> /usr/share/automake-1.9/COPYING
          lrwxrwxrwx  1 jason None    31 Jul 23 17:28 INSTALL -> /usr/share/automake-1.9/INSTALL
          -rw-r--r--  1 jason None    13 Jul 23 17:26 Makefile.am
          -rw-r--r--  1 jason None      0 Jul 23 17:26 Makefile.am.bak
          -rw-r--r--  1 jason None  31120 Jul 23 17:22 aclocal.m4
          drwxr-xr-x  2 jason None      0 Jul 23 17:22 autom4te.cache
          -rw-r--r--  1 jason None      0 Jul 23 17:17 autoscan-2.5x.log
          -rwxr-xr-x  1 jason None 163385 Jul 23 17:23 configure
          -rw-r--r--  1 jason None    573 Jul 23 17:21 configure.in
          -rw-r--r--  1 jason None    546 Jul 23 17:21 configure.in.bak
          lrwxrwxrwx  1 jason None    31 Jul 23 17:28 depcomp -> /usr/share/automake-1.9/depcomp
          lrwxrwxrwx  1 jason None    34 Jul 23 17:28 install-sh -> /usr/share/automake-1.9/install-sh
          lrwxrwxrwx  1 jason None    31 Jul 23 17:28 missing -> /usr/share/automake-1.9/missing
          drwxr-xr-x  2 jason None      0 Jul 23 16:42 src
      是不是感觉到已经有经常使用的./configure ; make ; make install ; 的模样了呢?其实这就是了。下面就可以这套半自动化工具链的成果了。

  7。使用
    就和安装其他软件一样了、
    sh> ./configure
    sh> make
    sh> make install

  有没有生成你想要的东西呢?试试吧。下面是我的:
    sh> ls src
        Makefile      config.h    ksou.exe 
        main.cpp  stamp-h1 akefile.am  Makefile.in     
        config.h.in  ksou.h    main.o
    sh> src/ksou.exe
        HELLO WORLD
  我用的是windows下的cygwin环境下做的测试,所以生成的执行文件为ksou.exe,如果在linux下面,生成的程序一般不需要带后缀名exe(即为ksou),不过也是能执行的呀。

三。各步骤详解
 

四。处理新扩展名文件

  在C/C++项目中, 我们赏需要涉及其他扩展名的文件,如在proc*c/c++ 中,它使用的扩展名为.pc,还有时候需要处理java文件,这种情况automake 能处理的了吗?当然,答案是肯定的。

  首先,需要使用到automake的SUFFIXES变量,它是在automake 系统中表示能处理的文件的扩展名的。

  在Makefile.am文件中写入下面几行:
  SUFFIXES = .pc .cpp
  .pc.cpp:
          $(PROCPP) XXXXparamsXXXXX
  然后运行一下automake.看看结果怎么样。



原文: http://qtchina.tk/?q=node/51

Powered by zexport