help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

VPATH, GPATH and implicit rules


From: Collins, Paul
Subject: VPATH, GPATH and implicit rules
Date: Wed, 23 Feb 2005 13:33:50 -0500

Hello,

I'm experimenting with some makefiles on HPUX and Linux and I would like to
ask a question about the impact of GPATH. I've got a setup something like
the following:

./Makefile.OK
./src/test_floor.c
./obj/

where test_floor.c is just a short C program and I want the object file and
executable 'test_floor' to go in obj/. I realise this is breaking "Paul's
Third Rule of Makefiles" (http://make.paulandlesley.org/rules.html#rule3),
but I'm finding that a bit restrictive. Anyway, with the following makefile:

.SUFFIXES: 
.SUFFIXES: .o .c

# compile source and put object file in $(OBJDIR)
.c.o:
                @echo $(CC) $(CCFLAGS) -c $(<F)
                @$(CC) $(CCFLAGS) -c $< -o $(OBJDIR)/$(@F)

SRCDIR = src
OBJDIR = obj

VPATH   = $(OBJDIR):$(SRCDIR)

#GPATH  = $(VPATH)

test_floor:     test_floor.o
                cd $(OBJDIR); gcc -o $@ test_floor.o -lm

test_floor.o: test_floor.c

updating src/test_floor.c will work OK. However adding the line
GPATH=$(VPATH) and updating src/test_floor.c causes make to miss the change.
The debug output is as follows: (without GPATH on the left, with it on the
right)


GNU Make 3.80                                                    (
Copyright (C) 2002  Free Software Foundation, Inc.               (
This is free software; see the source for copying conditions.    (
There is NO warranty; not even for MERCHANTABILITY or FITNESS FO (
PARTICULAR PURPOSE.                                              (
Reading makefiles...                                             (
Reading makefile `Makefile.OK'...                                (
Updating makefiles....                                           (
 Considering target file `Makefile.OK'.                          (
  Looking for an implicit rule for `Makefile.OK'.                (
  No implicit rule found for `Makefile.OK'.                      (
  Finished prerequisites of target file `Makefile.OK'.           (
 No need to remake target `Makefile.OK'.                         (
Updating goal targets....                                        (
Considering target file `test_floor'.                            (
  Considering target file `test_floor.o'.                        |
Considering target file `obj/test_floor.o'.
   Looking for an implicit rule for `test_floor.o'.              |
Looking for an implicit rule for `obj/test_floor.o'.
   Trying pattern rule with stem `test_floor'.                   (
   Trying implicit prerequisite `test_floor.c'.                  |
Trying implicit prerequisite `obj/test_floor.c'.
   Found an implicit rule for `test_floor.o'.                    |
Trying pattern rule with stem `test_floor'.
                                                                 >
Trying implicit prerequisite `obj/test_floor.c'.
                                                                 >
Looking for a rule with intermediate file `obj/test_floor.c'.
                                                                 >
Avoiding implicit rule recursion.
                                                                 >     No
implicit rule found for `obj/test_floor.o'.
    Considering target file `src/test_floor.c'.                  (
     Looking for an implicit rule for `src/test_floor.c'.        (
     No implicit rule found for `src/test_floor.c'.              (
     Finished prerequisites of target file `src/test_floor.c'.   (
    No need to remake target `src/test_floor.c'.                 (
    Pruning file `src/test_floor.c'.                             |
Finished prerequisites of target file `obj/test_floor.o'.
   Finished prerequisites of target file `test_floor.o'.         |
Prerequisite `src/test_floor.c' is newer than target `obj/tes
   Prerequisite `src/test_floor.c' is newer than target `test_fl |    No
commands for `obj/test_floor.o' and no prerequisites actual
   Prerequisite `src/test_floor.c' is newer than target `test_fl |    No
need to remake target `obj/test_floor.o'.
  Must remake target `test_floor.o'.                             |
Finished prerequisites of target file `obj/test_floor'.
  Ignoring VPATH name `obj/test_floor.o'.                        |
Prerequisite `obj/test_floor.o' is older than target `obj/test_
Putting child 0x08070a90 (test_floor.o) PID 21829 on the chain.  |  No need
to remake target `obj/test_floor'.
Live child 0x08070a90 (test_floor.o) PID 21829                   |  make:
`obj/test_floor' is up to date.
cc -c test_floor.c                                               <
Got a SIGCHLD; 1 unreaped children.                              <
Reaping winning child 0x08070a90 PID 21829                       <
Live child 0x08070a90 (test_floor.o) PID 21831                   <
Got a SIGCHLD; 1 unreaped children.                              <
Reaping winning child 0x08070a90 PID 21831                       <
Removing child 0x08070a90 PID 21831 from chain.                  <
  Successfully remade target file `test_floor.o'.                <
 Finished prerequisites of target file `test_floor'.             <
 Prerequisite `test_floor.o' of target `test_floor' does not exi <
Must remake target `test_floor'.                                 <
  Ignoring VPATH name `obj/test_floor'.                          <
cd obj; gcc -o test_floor test_floor.o -lm                       <
Putting child 0x08070a90 (test_floor) PID 21834 on the chain.    <
Live child 0x08070a90 (test_floor) PID 21834                     <
Got a SIGCHLD; 1 unreaped children.                              <
Reaping winning child 0x08070a90 PID 21834                       <
Removing child 0x08070a90 PID 21834 from chain.                  <
Successfully remade target file `test_floor'.                    <


Note that with GPATH=$(VPATH) the new prerequisite src/test_floor.c is
'found', but that there are:

No commands for `obj/test_floor.o' and no prerequisites actually changed.

My question is: Is this correct?

My reading of the make manual (How Directory Searches are Performed) is that
GPATH is meant to emulate simpler make algorithms (presumably such as the
one on HPUX) and so I should be able to set it to VPATH and not have any
problems. I realise that I could ignore GPATH for this particular case, but
there are more complicated examples where it seems to be required (e.g.
having test_floor.o also depend on a secondary file that is also kept in
obj/ and whose commands are always run, but without necessarily updating the
file; -- without GPATH it is never found after being 're-made' and so
test_floor.o is always re-made regardless; -- with GPATH we have the same
results as above where the updated prerequisites are recognised, but the
implicit rule is missed).

Many thanks for any insight and responses, and my apologies if this is old
hat to everyone.

Paul.

============================================
Paul Collins, GPS-Geodesist
Geodetic Survey Division, Geomatics Canada,
615 Booth Street, Ottawa, Ontario, K1A 0E9
Phone:(613)-947-3474; Fax: (613)-995-3215
E-mail: address@hidden
============================================ 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]