cmd:make 

Note Comment line syntax is the same as tcl, which means that a trailing '' will make next line comment too.

Help 

http://www.gnu.org/software/autoconf/manual/make/

Useful parameters 

-d             Display  the  reasons  why  make  chooses  to
               rebuild  a  target; make displays any and all
               dependencies that are  newer.   In  addition,
               make   displays  options  read  in  from  the
               MAKEFLAGS environment variable.
-dd            Display the dependency check  and  processing
               in vast detail.
-n             No execution mode.  Print  commands,  but  do
               not  execute them.
-p             Print out the complete set of  macro  defini-
               tions and target descriptions.
-p   Print  the  data  base  (rules and variable values) that results
     from reading the makefiles; then execute as usual or  as  other-
     wise  specified.  This also prints the version information given
     by the -v switch (see below).  To print the  data  base  without
     trying to remake any files, use make -p -f/dev/null.
-P             Merely  report  dependencies,   rather   than
               building them.
-W file
Pretend that the target file has just been modified.  When  used
with  the  -n flag, this shows you what would happen if you were
to modify that file.  Without -n, it is almost the same as  run-
ning  a  touch  command  on  the given file before running make,
except that the modification time is changed only in the  imagi-
nation of make.
Note -P not recognized by our GNU make, working copy.

`MAKE' Variable 

   Recursive `make' commands should always use the variable `MAKE', not
the explicit command name `make', as shown here:
subsystem:
        cd subdir && $(MAKE)
   The value of this variable is the file name with which `make' was
invoked.  If this file name was `/bin/make', then the command executed
is `cd subdir && /bin/make'.  If you use a special version of `make' to
run the top-level makefile, the same special version will be executed
for recursive invocations.

automatic variables (Dynamic Macros) 

Implicit Rules -> Pattern Rules -> Automatic Variables

Here is a table of automatic variables:
`$@'
    The file name of the target of the rule.  If the target is an
    archive member, then `$@' is the name of the archive file.  In a
    pattern rule that has multiple targets (*note Introduction to
    Pattern Rules: Pattern Intro.), `$@' is the name of whichever
    target caused the rule's commands to be run.
`$%'
    The target member name, when the target is an archive member.
    *Note Archives::.  For example, if the target is `foo.a(bar.o)'
    then `$%' is `bar.o' and `$@' is `foo.a'.  `$%' is empty when the
    target is not an archive member.
`$<'
    The name of the first prerequisite.  If the target got its
    commands from an implicit rule, this will be the first
    prerequisite added by the implicit rule (*note Implicit Rules::.).
`$?'
    The names of all the prerequisites that are newer than the target,
    with spaces between them.  For prerequisites which are archive
    members, only the member named is used (*note Archives::.).
`$^'
    The names of all the prerequisites, with spaces between them.  For
    prerequisites which are archive members, only the member named is
    used (*note Archives::.).  A target has only one prerequisite on
    each other file it depends on, no matter how many times each file
    is listed as a prerequisite.  So if you list a prerequisite more
    than once for a target, the value of `$^' contains just one copy
    of the name.
`$+'
    This is like `$^', but prerequisites listed more than once are
    duplicated in the order they were listed in the makefile.  This is
    primarily useful for use in linking commands where it is
    meaningful to repeat library file names in a particular order.
`$*'
    The stem with which an implicit rule matches (*note How Patterns
    Match: Pattern Match.).  If the target is `dir/a.foo.b' and the
    target pattern is `a.%.b' then the stem is `dir/foo'.  The stem is
    useful for constructing names of related files.
In a static pattern rule, the stem is part of the file name that
matched the `%' in the target pattern.
In an explicit rule, there is no stem; so `$*' cannot be determined
in that way.  Instead, if the target name ends with a recognized
suffix (*note Old-Fashioned Suffix Rules: Suffix Rules.), `$*' is
set to the target name minus the suffix.  For example, if the
target name is `foo.c', then `$*' is set to `foo', since `.c' is a
suffix.  GNU `make' does this bizarre thing only for compatibility
with other implementations of `make'.  You should generally avoid
using `$*' except in implicit rules or static pattern rules.
If the target name in an explicit rule does not end with a
recognized suffix, `$*' is set to the empty string for that rule.

For your convenience, GNU `make' sets the variable `CURDIR' to the pathname of the current working directory for you. If `-C' is in effect, it will contain the path of the new directory, not the original.

Two Flavors of Variables 

   There are two ways that a variable in GNU `make' can have a value;
we call them the two "flavors" of variables.  The two flavors are
distinguished in how they are defined and in what they do when expanded.
=<<, >>
   The first flavor of variable is a "recursively expanded" variable.
Variables of this sort are defined by lines using `=' (*note Setting
Variables: Setting.) or by the `define' directive (*note Defining
Variables Verbatim: Defining.).  The value you specify is installed
verbatim; if it contains references to other variables, these
references are expanded whenever this variable is substituted (in the
course of expanding some other string).  When this happens, it is
called "recursive expansion".
For example,
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:;echo $(foo)
will echo `Huh?': `$(foo)' expands to `$(bar)' which expands to
`$(ugh)' which finally expands to `Huh?'.
   This flavor of variable is the only sort supported by other versions
of `make'.  It has its advantages and its disadvantages.  An advantage
(most would say) is that:
CFLAGS = $(include_dirs) -O
include_dirs = -Ifoo -Ibar

will do what was intended: when `CFLAGS' is expanded in a command, it will expand to `-Ifoo -Ibar -O'. A major disadvantage is that you cannot append something on the end of a variable, as in

CFLAGS = $(CFLAGS) -O

because it will cause an infinite loop in the variable expansion. (Actually `make' detects the infinite loop and reports an error.)

   Another disadvantage is that any functions (*note Functions for
Transforming Text: Functions.)  referenced in the definition will be
executed every time the variable is expanded.  This makes `make' run
slower; worse, it causes the `wildcard' and `shell' functions to give
unpredictable results because you cannot easily control when they are
called, or even how many times.
:=<<, >>
   To avoid all the problems and inconveniences of recursively expanded
variables, there is another flavor: simply expanded variables.
   "Simply expanded variables" are defined by lines using `:=' (*note
Setting Variables: Setting.).  The value of a simply expanded variable
is scanned once and for all, expanding any references to other
variables and functions, when the variable is defined.  The actual
value of the simply expanded variable is the result of expanding the
text that you write.  It does not contain any references to other
variables; it contains their values _as of the time this variable was
defined_.  Therefore,
x := foo
y := $(x) bar
x := later

is equivalent to

y := foo bar
x := later
   When a simply expanded variable is referenced, its value is
substituted verbatim.
   Here is a somewhat more complicated example, illustrating the use of
`:=' in conjunction with the `shell' function.  (*Note The `shell'
Function: Shell Function.)  This example also shows use of the variable
`MAKELEVEL', which is changed when it is passed down from level to
level.  (*Note Communicating Variables to a Sub-`make':
Variables/Recursion, for information about `MAKELEVEL'.)
ifeq (0,${MAKELEVEL})
cur-dir   := $(shell pwd)
whoami    := $(shell whoami)
host-type := $(shell arch)
MAKE := ${MAKE} host-type=${host-type} whoami=${whoami}
endif

An advantage of this use of `:=' is that a typical `descend into a directory' command then looks like this:

${subdirs}:
      ${MAKE} cur-dir=${cur-dir}/$@ -C $@ all
   Simply expanded variables generally make complicated makefile
programming more predictable because they work like variables in most
programming languages.  They allow you to redefine a variable using its
own value (or its value processed in some way by one of the expansion
functions) and to use the expansion functions much more efficiently
(*note Functions for Transforming Text: Functions.).
Spaces 

Here the value of the variable `space' is precisely one space. The comment `# end of the line' is included here just for clarity. Since trailing space characters are _not_ stripped from variable values, just a space at the end of the line would have the same effect (but be rather hard to read). If you put whitespace at the end of a variable value, it is a good idea to put a comment like that at the end of the line to make your intent clear. Conversely, if you do _not_ want any whitespace characters at the end of your variable value, you must remember not to put a random comment on the end of the line after some whitespace, such as this:

dir := /foo/bar    # directory to put the frobs in

Here the value of the variable `dir' is `/foo/bar ' (with four trailing spaces), which was probably not the intention. (Imagine something like `$(dir)/file' with this definition!)

?=<<, >>
   There is another assignment operator for variables, `?='.  This is
called a conditional variable assignment operator, because it only has
an effect if the variable is not yet defined.  This statement:
FOO ?= bar

is exactly equivalent to this (*note The `origin' Function: Origin Function.):

ifeq ($(origin FOO), undefined)
  FOO = bar
endif
   Note that a variable set to an empty value is still defined, so `?='
will not set that variable.

Syntax of Conditionals 

CONDITIONAL-DIRECTIVE
TEXT-IF-TRUE
endif

The TEXT-IF-TRUE may be any lines of text, to be considered as part of the makefile if the condition is true. If the condition is false, no text is used instead.

Or,

CONDITIONAL-DIRECTIVE
TEXT-IF-TRUE
else
TEXT-IF-FALSE
endif

There are four different directives that test different conditions.

`ifeq (ARG1, ARG2)'

Expand all variable references in ARG1 and ARG2 and compare them.
If they are identical, the TEXT-IF-TRUE is effective; otherwise,
the TEXT-IF-FALSE, if any, is effective.
Often you want to test if a variable has a non-empty value.  When
the value results from complex expansions of variables and
functions, expansions you would consider empty may actually
contain whitespace characters and thus are not seen as empty.
However, you can use the `strip' function (*note Text Functions::)
to avoid interpreting whitespace as a non-empty value.  For
example:
ifeq ($(strip $(foo)),)
TEXT-IF-EMPTY
endif
will evaluate TEXT-IF-EMPTY even if the expansion of `$(foo)'
contains whitespace characters.

`ifneq (ARG1, ARG2)'

Expand all variable references in ARG1 and ARG2 and compare them.
If they are different, the TEXT-IF-TRUE is effective; otherwise,
the TEXT-IF-FALSE, if any, is effective.

`ifdef VARIABLE-NAME'

If the variable VARIABLE-NAME has a non-empty value, the
TEXT-IF-TRUE is effective; otherwise, the TEXT-IF-FALSE, if any,
is effective.  Variables that have never been defined have an
empty value.
Note that `ifdef' only tests whether a variable has a value.  It
does not expand the variable to see if that value is nonempty.
Consequently, tests using `ifdef' return true for all definitions
except those like `foo ='.  To test for an empty value, use
`ifeq ($(foo),)'.  For example,
bar =
foo = $(bar)
ifdef foo
frobozz = yes
else
frobozz = no
endif
sets `frobozz' to `yes', while:
foo =
ifdef foo
frobozz = yes
else
frobozz = no
endif
sets `frobozz' to `no'.

`ifndef VARIABLE-NAME' If the variable VARIABLE-NAME has an empty value, the TEXT-IF-TRUE is effective; otherwise, the TEXT-IF-FALSE, if any, is effective.

Introduction to Pattern Rules 

   A pattern rule contains the character `%' (exactly one of them) in
the target; otherwise, it looks exactly like an ordinary rule.  The
target is a pattern for matching file names; the `%' matches any
nonempty substring, while other characters match only themselves.
   For example, `%.c' as a pattern matches any file name that ends in
`.c'.  `s.%.c' as a pattern matches any file name that starts with
`s.', ends in `.c' and is at least five characters long.  (There must
be at least one character to match the `%'.)  The substring that the
`%' matches is called the "stem".
   `%' in a prerequisite of a pattern rule stands for the same stem
that was matched by the `%' in the target.  In order for the pattern
rule to apply, its target pattern must match the file name under
consideration, and its prerequisite patterns must name files that exist
or can be made.  These files become prerequisites of the target.
Thus, a rule of the form
%.o : %.c ; COMMAND...

specifies how to make a file `N.o', with another file `N.c' as its prerequisite, provided that `N.c' exists or can be made.

-- No need to specify .SUFFIX

wildcards 

hpp_files=$(wildcard *.hpp)

substitution 

substitution variable 

sources = foo.c bar.c
include $(sources:.c=.d)

This example uses a substitution variable reference to translate the list of source files `foo.c bar.c' into a list of prerequisite makefiles, `foo.d bar.d'.

subst 

%.dvi: %.tex %.chk
# no extension: in case for bibtex
      $(LATEX) $(subst .chk,,$<)

Multiple Dependant 

%.ps : %.dvi %.chk
        $(DVIPS) -o $@ $<

Automatically Prerequisites Generation 

   In the makefile for a program, many of the rules you need to write
often say only that some object file depends on some header file.  For
example, if `main.c' uses `defs.h' via an `#include', you would write:
main.o: defs.h

You need this rule so that `make' knows that it must remake `main.o' whenever `defs.h' changes. You can see that for a large program you would have to write dozens of such rules in your makefile. And, you must always be very careful to update the makefile every time you add or remove an `#include'.

   To avoid this hassle, most modern C compilers can write these rules
for you, by looking at the `#include' lines in the source files.
Usually this is done with the `-M' option to the compiler.  For
example, the command:
cc -M main.c

generates the output:

main.o : main.c defs.h

Thus you no longer have to write all those rules yourself. The compiler will do it for you.

   With old `make' programs, it was traditional practice to use this
compiler feature to generate prerequisites on demand with a command like
`make depend'.  That command would create a file `depend' containing
all the automatically-generated prerequisites; then the makefile could
use `include' to read them in (*note Include::).

In GNU `make', you need never tell `make' explicitly to regenerate the prerequisites, because it always regenerates any makefile that is out of date.

   The practice we recommend for automatic prerequisite generation is
to have one makefile corresponding to each source file.  For each
source file `NAME.c' there is a makefile `NAME.d' which lists what
files the object file `NAME.o' depends on.  That way only the source
files that have changed need to be rescanned to produce the new
prerequisites.
   Here is the pattern rule to generate a file of prerequisites (i.e.,
a makefile) called `NAME.d' from a C source file called `NAME.c':
%.d: %.c
        set -e; $(CC) -M $(CPPFLAGS) $< \
                  | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
                [ -s $@ ] || rm -f $@

*Note Pattern Rules::, for information on defining pattern rules. The `-e' flag to the shell makes it exit immediately if the `$(CC)' command fails (exits with a nonzero status). Normally the shell exits with the status of the last command in the pipeline (`sed' in this case), so `make' would not notice a nonzero status from the compiler.

   With the GNU C compiler, you may wish to use the `-MM' flag instead
of `-M'.  This omits prerequisites on system header files.  *Note
Options Controlling the Preprocessor: (gcc.info)Preprocessor Options,
for details.
The purpose of the `sed' command is to translate (for example):
main.o : main.c defs.h

into:

main.o main.d : main.c defs.h

This makes each `.d' file depend on all the source and header files that the corresponding `.o' file depends on. `make' then knows it must regenerate the prerequisites whenever any of the source or header files changes.

   Once you've defined the rule to remake the `.d' files, you then use
the `include' directive to read them all in.  *Note Include::.  For
example:
sources = foo.c bar.c
include $(sources:.c=.d)

(This example uses a substitution variable reference to translate the list of source files `foo.c bar.c' into a list of prerequisite makefiles, `foo.d bar.d'. *Note Substitution Refs::, for full information on substitution references.) Since the `.d' files are makefiles like any others, `make' will remake them as necessary with no further work from you. *Note Remaking Makefiles::.

Speed up 

If your machine has 16 or more Megabytes of RAM, there is a useful speed-up that can be done, which is to permit the kernel to compile two or modules in parallel. This will increase the load on the machine whilst the kernel is being recompiled, but will reduce the time during which the compilation will be taking place.

Experience has shown that the optimum value depends on the amount of RAM in your system according to the following formula, at least for systems with up to 32 Megabytes of RAM, although it may be a little conservative for systems with larger amounts of RAM:

N = [RAM in Megabytes] / 8 + 1

When you have decided on the correct number, edit the file /usr/src/linux/Makefile and find the line that currently reads:

MAKE=make

Replace it with one reading:

MAKE=make -j N

where N is the number determined above.

Phony Targets 

http://www.gnu.org/software/autoconf/manual/make/Phony-Targets.html

   A phony target is one that is not really the name of a file.  It is
just a name for some commands to be executed when you make an explicit
request.  There are two reasons to use a phony target: to avoid a
conflict with a file of the same name, and to improve performance.
   If you write a rule whose commands will not create the target file,
the commands will be executed every time the target comes up for
remaking.  Here is an example:
clean:
        rm *.o temp

Because the `rm' command does not create a file named `clean', probably no such file will ever exist. Therefore, the `rm' command will be executed every time you say `make clean'. The phony target will cease to work if anything ever does create a file named clean in this directory. Since it has no prerequisites, the file clean would inevitably be considered up to date, and its commands would not be executed. To avoid this problem, you can explicitly declare the target to be phony, using the special target .PHONY (see Special Built-in Target Names) as follows:

.PHONY : clean

Once this is done, `make clean' will run the commands regardless of whether there is a file named clean.

When one phony target is a prerequisite of another, it serves as a subroutine of the other. For example, here `make cleanall' will delete the object files, the difference files, and the file program:

.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff
        rm program
cleanobj :
        rm *.o
cleandiff :
        rm *.diff

Force Targets 

http://www.gnu.org/software/autoconf/manual/make/Force-Targets.html

If a rule has no prerequisites or commands, and the target of the rule is a nonexistent file, then make imagines this target to have been updated whenever its rule is run. This implies that all targets depending on this one will always have their commands run.

An example will illustrate this:

clean: FORCE
        rm $(objects)
FORCE:

Here the target `FORCE' satisfies the special conditions, so the target clean that depends on it is forced to run its commands. There is nothing special about the name `FORCE', but that is one name commonly used this way.

As you can see, using `FORCE' this way has the same results as using

.PHONY: clean

Using `.PHONY' is more explicit and more efficient. However, other versions of make do not support `.PHONY'; thus `FORCE' appears in many makefiles.

Empty Target Files 

http://www.gnu.org/software/autoconf/manual/make/Empty-Targets.html

When you ask to remake the empty target, the commands are executed if any prerequisite is more recent than the target; in other words, if a prerequisite has changed since the last time you remade the target. Here is an example:

print: foo.c bar.c
        lpr -p $?
        touch print

With this rule, `make print' will execute the lpr command if either source file has changed since the last `make print'. The automatic variable `$?' is used to print only those files that have changed.

What Name to Give Your Makefile 

*Tags*: gnu make makefile file name order

make looks for the makefile in order: `GNUmakefile', `makefile' and `Makefile'.

Normally you should call your makefile either `makefile' or `Makefile'. (We recommend `Makefile' because it appears prominently near the beginning of a directory listing, right near other important files such as `README'.) The first name checked, `GNUmakefile', is not recommended for most makefiles.

If you want to use a nonstandard name for your makefile, you can specify the makefile name with the `-f' or `—file' option. You can specify several makefiles using more than one `-f' or `—file' option. All the makefiles are effectively concatenated in the order specified.

Makefile : .c.o and %.o: %.c 

Newsgroups: comp.unix.programmer,gnu.utils.help
> What is the difference between :
> .c.o:
>     $(CC) <stuff>
> and
> %.o:  %.c ; $(CC) <stuff>

In this case, nothing. Assuming that, in the first case, you have .c and .o in your .SUFFIXES list, of course :).

I guess I should also point out a few other differences:

  1. The suffix form can be removed via the empty .SUFFIXES target; the pattern form can only be removed with the -r option.

  2. The pattern form isn't valid POSIX.2 make.

  3. The pattern form is much more flexible, which doesn't matter in this case as you've stated it but matters very much in other situations… like if you wanted the .o to go into a different directory for example.

Paul D. Smith

Makefile : .c.o and %.o: %.c 

>  3) The pattern form is much more flexible, which doesn't matter in this
>     case as you've stated it but matters very much in other
>     situations... like if you wanted the .o to go into a different
>     directory for example.

Good point, I had always been wondering how this is being done, but never succeeded doing so. Therefore my java makefile is really dumb, like this:

${CLASSFDIR}/AdvReader.class: AdvReader.java
        javac -d ${CLASSFDIR} AdvReader.java
${CLASSFDIR}/DbHandler.class: DbHandler.java
        javac -d ${CLASSFDIR} DbHandler.java
${CLASSFDIR}/Token.class: Token.java
        javac -d ${CLASSFDIR} Token.java

Makefile : %.class: %.java 

..
> ${CLASSFDIR}/%.class: %.java
>         javac -d ${CLASSFDIR} $<

Thanks.

> >PS. I tried
> >${CLASSFDIR}/%.class: %.java
> >
> >and it didn't seem to work. Can't remember why tho.
>
> Well, we certainly can't figure it out either, if that's all the
> information you provide....

Oh, at last I recalled why it failed. It has nothing to do with the OP though. It is really a java issue — The above will not work if the java program belongs to a package. The generated .class file make always recompile.

Here is an example of explicit rule:

${CLASSFDIR}/knn/DbKnn.class: knn/DbKnn.java
        javac -d ${CLASSFDIR} knn/DbKnn.java
${CLASSFDIR}/knn/Knn.class: knn/Knn.java
        javac -d ${CLASSFDIR} knn/Knn.java

Any idea that can make 'make' work this way?

Makefile : %.class: %.java 

>Any idea that can make 'make' work this way?

I am not sure what the problem is. The rule I already gave you should work just fine:

${CLASSFDIR}/%.class: %.java
        javac -d ${CLASSFDIR} $<

Note that there's nothing special about slashes as far as '%' is concerned — it's a generic wildcard. In the examples you gave above, it would match "knn/DbKnn" the first time or "knn/Knn" the second time.

Jonathan Kamens

Help on make rules 

Implicit Rules
   When a target has no entry in the makefile, make attempts to
   determine  its  class  (if  any) and apply the rule for that
   class.  An implicit rule describes how to build  any  target
   of  a  given class, from an associated dependency file.  The
   class of a target can be determined either by a pattern,  or
   by  a  suffix;  the  corresponding dependency file (with the
   same basename) from which such a target might be built.   In
   addition  to a predefined set of implicit rules, make allows
   you to define your own, either by pattern, or by suffix.
Suffix Rules
   When no pattern matching rule applies, make checks the  tar-
   get  name  to see if it ends with a suffix in the known suf-
   fixes list.  If so, make checks for  any  suffix  rules,  as
   well  as a dependency file with same root and another recog-
   nized suffix, from which to build it.
The target entry for a suffix rule takes the form:
DsTs:
     rule
where Ts is the suffix of the target, Ds is  the  suffix  of
the  dependency  file,  and  rule is the rule for building a
target in the class.  Both Ds and Ts must appear in the suf-
fixes  list.   (A  suffix  need  not begin with a `.'  to be
recognized.)
A suffix rule with only one suffix describes how to build  a
target  having  a null (or no) suffix from a dependency file
with the indicated suffix.  For instance, the .c rule  could
be  used  to build an executable program named file from a C
source file named `file.c'.  If a target with a null  suffix
has an explicit dependency, make omits the search for a suf-
fix rule.
__________________________________________________________________________
                Table of Standard Implicit (Suffix) Rules
__________________________________________________________________________
              .c.o                 $(COMPILE.c) $(OUTPUT_OPTION) $<
             _____________________________________________________________
              .l.c                 $(RM) $@
                                   $(LEX.l) $< > $@
             _____________________________________________________________
make reads in the standard set of implicit  rules  from  the
file /usr/share/lib/make/make.rules, unless -r is in effect,
or there is a make.rules file in the  local  directory  that
does not include that file.
The Suffixes List
   The suffixes list is given as the list of  dependencies  for
   the `.SUFFIXES:'  special-function target.  The default list
   is contained in the SUFFIXES macro (See Table of  Predefined
   Macros  for  the standard list of suffixes).  You can define
   additional .SUFFIXES: targets; a .SUFFIXES  target  with  no
   dependencies clears the list of suffixes.  Order is signifi-
   cant within the list; make selects a rule  that  corresponds
   to  the target's suffix and the first dependency-file suffix
   found in the list.  To place suffixes at  the  head  of  the
   list,  clear  the list and replace it with the new suffixes,
   followed by the default list:
.SUFFIXES:
.SUFFIXES: suffixes $(SUFFIXES)
A tilde (~) indicates that if a  dependency  file  with  the
indicated suffix (minus the ~) is under SCCS its most recent
version should be retrieved, if necessary, before the target
is processed.
Predefined Macros
  C Compiler      CC             cc
  Commands        CFLAGS
                  CPPFLAGS
                  COMPILE.c      $(CC) $(CFLAGS) $(CPPFLAGS) -c
                  LINK.c         $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
 ___________________________________________________________________________
| Suffixes List|  SUFFIXES    |  .o .c .c~ .cc .cc~ .y .y~ .l .l~          |
|              |              |  .s .s~ .sh .sh~ .S .S~ .ln .h .h~         |
|              |              |  ..f .f~ .F .F~ .mod .mod~ .sym            |
|              |              |  .def .def~ .p .p~ .r .r~                  |
|              |              |  .cps .cps~ .C .C~ .Y .Y~                  |
|              |              |  .L .L .f90 .f90~ .ftn .ftn~               |

Old-Fashioned Suffix Rules 

"Suffix rules" are the old-fashioned way of defining implicit rules for `make'. Suffix rules are obsolete because pattern rules are more general and clearer. They are supported in GNU `make' for compatibility with old makefiles. They come in two kinds: "double-suffix" and "single-suffix".

If you wish to eliminate the default known suffixes instead of just adding to them, write a rule for `.SUFFIXES' with no prerequisites. By special dispensation, this eliminates all existing prerequisites of `.SUFFIXES'. You can then write another rule to add the suffixes you want. For example,

.SUFFIXES:            # Delete the default suffixes
.SUFFIXES: .c .o .h   # Define our suffix list

Generating dumb make file 

COMPILER=javac
ls *.java | doeach.pl -q $echo "@'@n.class: @_\\n\\t$COMPILER @_\\n@'"
Note The dumb make is so stupid that it does re-compilation every time.

elegant solution 

CLASSFDIR=/java/classes

${CLASSFDIR}/%.class: %.java
        javac -d ${CLASSFDIR} $<

include classfiles.mk

all: ${CLASSFILES}

clean:
        rm *~ */*~ ${CLASSFILES}
Note

java is the worst system to utilize make.

cd /java/expresso/webapps/expresso/WEB-INF/classes/com/jcorporate/expresso/services/controller/dbmaint
javac -d . Lookup.java
javac -d ./ Lookup.java
javac -d `pwd` Lookup.java

All above commands actually yield .class file under /java/expresso/webapps/expresso/WEB-INF/classes/com/jcorporate/expresso/services/controller/dbmaint/com/jcorporate/expresso/services/controller/dbmaint

Example: File: classfiles.mk
CLASSFILES= ${CLASSFDIR}/AdvReader.class ${CLASSFDIR}/DbHandler.class ${CLASSFDIR}/Token.class ${CLASSFDIR}/knn/DbKnn.class ${CLASSFDIR}/knn/Knn.class ${CLASSFDIR}/knn/MessageClassifier.class ${CLASSFDIR}/knn/NeighborList.class ${CLASSFDIR}/knn/NeighborNode.class ${CLASSFDIR}/knn/inst_tst.class ${CLASSFDIR}/rand.class

Try to make dir 1st failed 

ifeq ($(strip $(TEX_DEST_DIR_EXIST)),0)
;
else
TEX_DEST_DIR_EXIST := $(mkdir -p ${TEX_DEST_DIR})
endif

documented on: 2004.01.29 Thu