跳转到内容

GNU make/附录/一个复杂的Makefile实例

维基教科书,自由的教学读本

C 一个复杂的Makefile实例

[编辑]

下面是一段为GNU tar程序设计的Makefile代码,相当复杂。

由于all是第一个目标,所以它也是默认目标。下面这个程序段有一个非常有趣的特色,这个特色就是源代码程序中的“testpad.h文件是一个由名叫testpad程序自动生成的,而这个testpad又是又是由testpad.c这个程序经过编译产生的。

如果您输入make或者make all,则 make 会让名为tar的目标运行从而开始编译指令,会让名为rmt的目标运行从而生成一个远程磁带数据存取的守护程序,会让名为tar.info的目标运行从而生成INFO文档。

如果您输入make install,那么make就执行的就不仅仅只是“tar”、“rmt”和“tar.info”这三个目标了,还会执行相应的安装操作。

如果您输入make clean,那么make会清除所有的.o文件,以及“tar”、“rmt”、“testpad”、“testpad.h”和“core”这些文件。

如果您输入make distclean,那么make除了会清除“make clean”会清除的文件外,还会清除“TAGS”、“Makefile”和“config.status”这些文件(虽然不明显,但下面这个makefileconfig.status都是用户通过tar发行版中的configure文件生成的,这个“configure”文件这里没有列出)。

如果您输入make realclean,那么make除了清除make distclean会清除的文件外,还会清除由tar.info生成的INFO文档。

# Generated automatically from Makefile.in by configure.
     # Un*x Makefile for GNU tar program.
     # Copyright (C) 1991 Free Software Foundation, Inc.
     
     # This program is free software; you can redistribute
     # it and/or modify it under the terms of the GNU
     # General Public License ...
     ...
     ...
     
     SHELL = /bin/sh
     
     #### Start of system configuration section. ####
     
     srcdir = .
     
     # If you use gcc, you should either run the
     # fixincludes script that comes with it or else use
     # gcc with the -traditional option.  Otherwise ioctl
     # calls will be compiled incorrectly on some systems.
     CC = gcc -O
     YACC = bison -y
     INSTALL = /usr/local/bin/install -c
     INSTALLDATA = /usr/local/bin/install -c -m 644
     
     # Things you might add to DEFS:
     # -DSTDC_HEADERS        If you have ANSI C headers and
     #                       libraries.
     # -DPOSIX               If you have POSIX.1 headers and
     #                       libraries.
     # -DBSD42               If you have sys/dir.h (unless
     #                       you use -DPOSIX), sys/file.h,
     #                       and st_blocks in `struct stat'.
     # -DUSG                 If you have System V/ANSI C
     #                       string and memory functions
     #                       and headers, sys/sysmacros.h,
     #                       fcntl.h, getcwd, no valloc,
     #                       and ndir.h (unless
     #                       you use -DDIRENT).
     # -DNO_MEMORY_H         If USG or STDC_HEADERS but do not
     #                       include memory.h.
     # -DDIRENT              If USG and you have dirent.h
     #                       instead of ndir.h.
     # -DSIGTYPE=int         If your signal handlers
     #                       return int, not void.
     # -DNO_MTIO             If you lack sys/mtio.h
     #                       (magtape ioctls).
     # -DNO_REMOTE           If you do not have a remote shell
     #                       or rexec.
     # -DUSE_REXEC           To use rexec for remote tape
     #                       operations instead of
     #                       forking rsh or remsh.
     # -DVPRINTF_MISSING     If you lack vprintf function
     #                       (but have _doprnt).
     # -DDOPRNT_MISSING      If you lack _doprnt function.
     #                       Also need to define
     #                       -DVPRINTF_MISSING.
     # -DFTIME_MISSING       If you lack ftime system call.
     # -DSTRSTR_MISSING      If you lack strstr function.
     # -DVALLOC_MISSING      If you lack valloc function.
     # -DMKDIR_MISSING       If you lack mkdir and
     #                       rmdir system calls.
     # -DRENAME_MISSING      If you lack rename system call.
     # -DFTRUNCATE_MISSING   If you lack ftruncate
     #                       system call.
     # -DV7                  On Version 7 Unix (not
     #                       tested in a long time).
     # -DEMUL_OPEN3          If you lack a 3-argument version
     #                       of open, and want to emulate it
     #                       with system calls you do have.
     # -DNO_OPEN3            If you lack the 3-argument open
     #                       and want to disable the tar -k
     #                       option instead of emulating open.
     # -DXENIX               If you have sys/inode.h
     #                       and need it 94 to be included.
     
     DEFS =  -DSIGTYPE=int -DDIRENT -DSTRSTR_MISSING \
             -DVPRINTF_MISSING -DBSD42
     # Set this to rtapelib.o unless you defined NO_REMOTE,
     # in which case make it empty.
     RTAPELIB = rtapelib.o
     LIBS =
     DEF_AR_FILE = /dev/rmt8
     DEFBLOCKING = 20
     
     CDEBUG = -g
     CFLAGS = $(CDEBUG) -I. -I$(srcdir) $(DEFS) \
             -DDEF_AR_FILE=\"$(DEF_AR_FILE)\" \
             -DDEFBLOCKING=$(DEFBLOCKING)
     LDFLAGS = -g
     
     prefix = /usr/local
     # Prefix for each installed program,
     # normally empty or `g'.
     binprefix =
     
     # The directory to install tar in.
     bindir = $(prefix)/bin
     
     # The directory to install the info files in.
     infodir = $(prefix)/info
     
     #### End of system configuration section. ####
     
     SRC1 =  tar.c create.c extract.c buffer.c \
             getoldopt.c update.c gnu.c mangle.c
     SRC2 =  version.c list.c names.c diffarch.c \
             port.c wildmat.c getopt.c
     SRC3 =  getopt1.c regex.c getdate.y
     SRCS =  $(SRC1) $(SRC2) $(SRC3)
     OBJ1 =  tar.o create.o extract.o buffer.o \
             getoldopt.o update.o gnu.o mangle.o
     OBJ2 =  version.o list.o names.o diffarch.o \
             port.o wildmat.o getopt.o
     OBJ3 =  getopt1.o regex.o getdate.o $(RTAPELIB)
     OBJS =  $(OBJ1) $(OBJ2) $(OBJ3)
     AUX =   README COPYING ChangeLog Makefile.in  \
             makefile.pc configure configure.in \
             tar.texinfo tar.info* texinfo.tex \
             tar.h port.h open3.h getopt.h regex.h \
             rmt.h rmt.c rtapelib.c alloca.c \
             msd_dir.h msd_dir.c tcexparg.c \
             level-0 level-1 backup-specs testpad.c
     
     .PHONY: all
     all:    tar rmt tar.info
     
     .PHONY: tar
     tar:    $(OBJS)
             $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
     
     rmt:    rmt.c
             $(CC) $(CFLAGS) $(LDFLAGS) -o $@ rmt.c
     
     tar.info: tar.texinfo
             makeinfo tar.texinfo
     
     .PHONY: install
     install: all
             $(INSTALL) tar $(bindir)/$(binprefix)tar
             -test ! -f rmt || $(INSTALL) rmt /etc/rmt
             $(INSTALLDATA) $(srcdir)/tar.info* $(infodir)
     
     $(OBJS): tar.h port.h testpad.h
     regex.o buffer.o tar.o: regex.h
     # getdate.y has 8 shift/reduce conflicts.
     
     testpad.h: testpad
             ./testpad
     
     testpad: testpad.o
             $(CC) -o $@ testpad.o
     
     TAGS:   $(SRCS)
             etags $(SRCS)
     
     .PHONY: clean
     clean:
             rm -f *.o tar rmt testpad testpad.h core
     
     .PHONY: distclean
     distclean: clean
             rm -f TAGS Makefile config.status
     
     .PHONY: realclean
     realclean: distclean
             rm -f tar.info*
     
     .PHONY: shar
     shar: $(SRCS) $(AUX)
             shar $(SRCS) $(AUX) | compress \
               > tar-`sed -e '/version_string/!d' \
                          -e 's/[^0-9.]*\([0-9.]*\).*/\1/' \
                          -e q
                          version.c`.shar.Z
     
     .PHONY: dist
     dist: $(SRCS) $(AUX)
             echo tar-`sed \
                  -e '/version_string/!d' \
                  -e 's/[^0-9.]*\([0-9.]*\).*/\1/' \
                  -e q
                  version.c` > .fname
             -rm -rf `cat .fname`
             mkdir `cat .fname`
             ln $(SRCS) $(AUX) `cat .fname`
             tar chZf `cat .fname`.tar.Z `cat .fname`
             -rm -rf `cat .fname` .fname
     
     tar.zoo: $(SRCS) $(AUX)
             -rm -rf tmp.dir
             -mkdir tmp.dir
             -rm tar.zoo
             for X in $(SRCS) $(AUX) ; do \
                 echo $$X ; \
                 sed 's/$$/^M/' $$X \
                 > tmp.dir/$$X ; done
             cd tmp.dir ; zoo aM ../tar.zoo *
             -rm -rf tmp.dir