-->
Previous Table of Contents Next


Suffix Rules

As mentioned earlier in the “Macros” section, make does not necessarily require everything to be spelled out for it in the makefile. Because make was designed to enhance software development in Linux, it knows how the compilers work, especially for C. For example, make knows that the C compiler expects to compile source code files having a .c suffix and that it generates object files having an .o suffix. This knowledge is encapsulated in a suffix rule: make examines the suffix of a target or dependent to determine what it should do next.

There are many suffix rules that are internal to make, most of which deal with the compilation of source and linking of object files. The default suffix rules that are applicable in your makefile are as follows:


.SUFFIXES: .o .c .s



.c.o:

      ${CC} ${CFLAGS} -c $<



.s.o:

      ${AS} ${ASFLAGS} -o $@ $<

The first line is a dependency line stating the suffixes for which make should try to find rules if none are explicitly written in the makefile. The second dependency line is terse: Essentially, it tells make to execute the associated C compile on any file with a .c suffix whose corresponding object file (.o) is out-of-date. The third line is a similar directive for assembler files. The new macro $< has a similar role to that of the $? directive, but can only be used in a suffix rule. It represents the dependency that the rule is currently being applied to.

These default suffix rules are powerful in that all you really have to list in your makefile are any relevant object files. make does the rest: Ifmain.o is out-of-date, make automatically searches for a main.c file to compile. This also works for the itquick.o object file. After the object files are updated, the compile of someonehappy can execute.

You can also specify your own suffix rules in order to have make perform other operations. Say, for instance, that you want to copy object files to another directory after they are compiled. You can explicitly write the appropriate suffix rule in the following way:


.c.o:

      ${CC} ${CFLAGS} -c $<

      cp $@ backup

The $@ macro, as you know, refers to the current target. Thus, on the dependency line shown, the target is a .o file, and the dependency is the corresponding .c file.

Now that you know how to exploit the suffix rule feature of make, you can rewrite your someonehappy makefile for the last time (you’re probably glad to hear that news).


# The final kick at the can

OBJS = main.o dothis.o itquick.o

YN = yes.h no.h

LIB_FILES = /usr/happy/lib/likeatree.a

someonehappy: ${OBJS} ${LIB_FILES}

      ${CC} -o $@ ${OBJS} ${LIB_FILES}

fresh:

      rm *.o

maybe.h: ${YN}

      cp $? /users/sue/

This makefile works as your first one did, and you can compile the entire program using the following:


$ make someonehappy

Or, just compile one component of it as follows:


$ make itquick.o

This discussion only scratches the surface of make. You should refer to the man page for make to further explore its many capabilities.

RCS

One of the other important factors involved in software development is the management of source code files as they evolve. On any type of software project, you might continuously release newer versions of a program as features are added or bugs are fixed. Larger projects usually involve several programmers, which can complicate versioning and concurrency issues even further. In the absence of a system to manage the versioning of source code on your behalf, it is very easy to lose track of the versions of files. This can lead to situations in which modifications are inadvertently wiped out or redundantly coded by different programmers. Fortunately, Linux provides just such a versioning system, called RCS (Revision Control System).

RCS is just one version control system. There are plenty of others, some public domain, some commercial. SCCS (Source Code Control System) was the first truly workable version control system developed for UNIX and is still in use. RCS is a better system than SCCS, adding many new features and abilities that the older system lacks. There are RCS systems available for most operating system platforms including all UNIX versions, DOS, Windows, and Windows NT. If you have to work on a project with many developers, there is a network-wide version of RCS available called CVS (Concurrent Versions System). CVS is included with many versions of Linux. The commands used by CVS are different than those used by RCS, and since most of you won’t be jumping into network-wide version control yet, we’ll focus on RCS here. The CVS man pages are included with versions of Linux than bundle CVS, if you are curious.

RCS can administer the versioning of files by controlling access to them. For anyone to update a particular file, the person must record in RCS who she is and why she is making the changes. RCS can then record this information along with the updates in an RCS file separate from the original version. Because the updates are kept independent from the original file, you can easily return to any previous version if necessary. This also has the benefit of conserving disk space because you don’t have to keep copies of the entire file around. This is certainly true for situations in which versions differ only by a few lines; it is less useful if there are only a few versions, each of which is largely different from the next.


Previous Table of Contents Next