GNU make - C. Complex Makefile Example

Go to the first, previous, next, last section, table of contents.

# C. Complex Makefile Example

Here is the makefile for the GNU `tar` program. This is a moderately complex makefile.

Because it is the first target, the default goal is ``all'`. An interesting feature of this makefile is that ``testpad.h'` is a source file automatically created by the `testpad` program, itself compiled from ``testpad.c'`.

If you type ``make'` or ``make all'`, then `make` creates the ``tar'` executable, the ``rmt'` daemon that provides remote tape access, and the ``tar.info'` Info file.

If you type ``make install'`, then `make` not only creates ``tar'`, ``rmt'`, and ``tar.info'`, but also installs them.

If you type ``make clean'`, then `make` removes the ``.o'` files, and the ``tar'`, ``rmt'`, ``testpad'`, ``testpad.h'`, and ``core'` files.

If you type ``make distclean'`, then `make` not only removes the same files as does ``make clean'` but also the ``TAGS'`, ``Makefile'`, and ``config.status'` files. (Although it is not evident, this makefile (and ``config.status'`) is generated by the user with the `configure` program, which is provided in the `tar` distribution, but is not shown here.)

If you type ``make realclean'`, then `make` removes the same files as does ``make distclean'` and also removes the Info files generated from ``tar.texinfo'`.

In addition, there are targets `shar` and `dist` that create distribution kits.

    # 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

    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

    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)

    clean:
            rm -f *.o tar rmt testpad testpad.h core

    distclean: clean
            rm -f TAGS Makefile config.status

    realclean: distclean
            rm -f tar.info*

    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

    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`
            -rm -rf `cat .fname` .fname
            tar chZf `cat .fname`.tar.Z `cat .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

Go to the first, previous, next, last section, table of contents.