语言: 日本語 | Español | Français | Português | 中文 | English
上一章 | 下一章 | 目录 | 英文原版(gnu.org)

附录C 复杂的 Makefile 示例

这里介绍 GNU 的 tar 程序所使用的 makefile。这是一个中等复杂程度的 makefile 示例。开头的第 1 行使用 #! 这一设定,使该 makefile 可以直接执行。

由于这条规则是第一个目标,因此默认目标 (goal) 为 ‘all’。这个 makefile 有趣的一点是,testpad.h 是由名为 testpad 的程序自动生成的源文件。而 testpad 本身又是从 testpad.c 编译生成的。

如果输入 ‘make’ 或 ‘make all’,make 就会生成 tar 可执行文件、提供远程磁带访问的 rmt 守护进程,以及名为 tar.info 的 Info 文件。

如果输入 ‘make install’,make 不仅会生成 tarrmttar.info,还会将它们安装到位。

如果输入 ‘make clean’,make 会删除 ‘.o’ 文件,以及 tarrmttestpadtestpad.hcore 各个文件。

如果输入 ‘make distclean’,make 除了删除 ‘make clean’ 所删除的相同文件外,还会删除 TAGSMakefileconfig.status 各个文件。(虽然从表中看不出来,但这个 makefile(以及 config.status)是由用户使用 tar 发行版中提供的 configure 程序在本地生成的。不过 configure 本身这里并未列出。)

如果输入 ‘make realclean’,make 会删除 ‘make distclean’ 所删除的相同文件,并进一步删除从 tar.texinfo 生成的 Info 文件群。

除此之外,还准备了用于创建发行套件的 shar 目标和 dist 目标。

#!/usr/bin/make -f
# 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

#### 系统配置部分的开始 ####

srcdir = .

# 如果使用 gcc,请运行随附的 fixincludes 脚本,
# 或者为 gcc 加上 -traditional 选项来使用。
# 否则在某些系统上 ioctl 调用
# 可能会被错误地编译。
CC = gcc -O
YACC = bison -y
INSTALL = /usr/local/bin/install -c
INSTALLDATA = /usr/local/bin/install -c -m 644


# 可以添加到 DEFS 的内容:
# -DSTDC_HEADERS        当有 ANSI C 的头文件和库
#                       时。
# -DPOSIX               当有 POSIX.1 的头文件和库
#                       时。
# -DBSD42               当有 sys/dir.h(使用 -DPOSIX 时
#                       除外)、sys/file.h,以及
#                       `struct stat' 的 st_blocks 时。
# -DUSG                 当有 System V/ANSI C 的字符串、
#                       内存函数与头文件、sys/sysmacros.h、
#                       fcntl.h、getcwd,且没有 valloc,
#                       并有 ndir.h(使用 -DDIRENT 时
#                       除外)时。
# -DNO_MEMORY_H         当为 USG 或 STDC_HEADERS 但不
#                       include memory.h 时。
# -DDIRENT              当为 USG 且有 dirent.h 而非
#                       ndir.h 时。
# -DSIGTYPE=int         当信号处理函数返回 int 而非
#                       void 时。
# -DNO_MTIO             当没有 sys/mtio.h(磁带的 ioctl)
#                       时。
# -DNO_REMOTE           当没有远程 shell 或 rexec
#                       时。
# -DUSE_REXEC           当远程磁带操作使用 rexec 而非
#                       fork rsh 或 remsh
#                       时。
# -DVPRINTF_MISSING     当没有 vprintf 函数(但有 _doprnt)
#                       时。
# -DDOPRNT_MISSING      当没有 _doprnt 函数时。
#                       这时还需要定义
#                       -DVPRINTF_MISSING。
# -DFTIME_MISSING       当没有 ftime 系统调用时。
# -DSTRSTR_MISSING      当没有 strstr 函数时。
# -DVALLOC_MISSING      当没有 valloc 函数时。
# -DMKDIR_MISSING       当没有 mkdir 和 rmdir 系统调用
#                       时。
# -DRENAME_MISSING      当没有 rename 系统调用时。
# -DFTRUNCATE_MISSING   当没有 ftruncate 系统调用
#                       时。
# -DV7                  在 Version 7 Unix 上(很久
#                       没有测试了)。
# -DEMUL_OPEN3          当没有三参数版的 open,且想用
#                       手头的系统调用来模拟它
#                       时。
# -DNO_OPEN3            当没有三参数的 open,且想禁用
#                       tar 的 -k 选项而非模拟 open
#                       时。
# -DXENIX               当有 sys/inode.h,且需要在 94 处
#                       include 它时。

DEFS =  -DSIGTYPE=int -DDIRENT -DSTRSTR_MISSING \
        -DVPRINTF_MISSING -DBSD42
# 如果没有定义 NO_REMOTE,就把它设为 rtapelib.o。
# 如果定义了,请保持为空。
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
# 为每个安装的程序加上的前缀,
# 通常为空或 `g'。
binprefix =

# 安装 tar 的目录。
bindir = $(prefix)/bin

# 安装 info 文件的目录。
infodir = $(prefix)/info


#### 系统配置部分的结束 ####

SRCS_C  = tar.c create.c extract.c buffer.c   \
          getoldopt.c update.c gnu.c mangle.c \
          version.c list.c names.c diffarch.c \
          port.c wildmat.c getopt.c getopt1.c \
          regex.c
SRCS_Y  = getdate.y
SRCS    = $(SRCS_C) $(SRCS_Y)
OBJS    = $(SRCS_C:.c=.o) $(SRCS_Y:.y=.o) $(RTAPELIB)
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

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 有 8 个 shift/reduce 冲突。


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

上一章 | 下一章 | 目录 | 英文原版(gnu.org)