[comp.unix.questions] make SUFFIXES question.....

morreale@bierstadt.scd.ucar.edu (Peter Morreale) (08/12/90)

Ok all you make wizards, I've got a good one for ya....

Consider the following makefile:

---------------------clip here-------------------------

.pp.o:
	cp $*.pp $*.f

.SUFFIXES:  $(SUFFIXES) .pp
FILES= f1.o 

compile: $(FILES)
	@echo "Why isn't .f.o  applied?"

clean:
	-rm -f $(FILES)  *.f
----------------------clip here--------------------------

Create "f1.pp" and type make.

You'll notice that the ".pp.o" rule is executed, and then the 
compile rule.  The question is:  Why isn't the default ".f.o" rule 
executed before the "compile" target?  (If you type make again, the 
".f.o" rule is executed and all is well....)

It seems to me that the sequence of events should be:

    .pp.o
    .f.o
    compile

I did a make -dd on this to obtain a listing, but I can't seem to 
decifer the output.  It (the output is enclosed below)  

I executed this makefile on SunOS 4.0.3c and UNICOS 5.1 with identical 
results.  

Thanks for any and all help,
-PWM

----------------"make -dd" output-------------------------

MAKEFLAGS value: 
stat(default.mk)
doname(default.mk)
 Looking for % rule for default.mk
 find_double_suffix_rule(default.mk)
 find_suffix_rule(default.mk,default.mk,)
stat(/usr/include/make/default.mk)
doname(/usr/include/make/default.mk)
 Looking for % rule for /usr/include/make/default.mk
 find_double_suffix_rule(/usr/include/make/default.mk)
 find_suffix_rule(/usr/include/make/default.mk,/usr/include/make/default.mk,)
SUFFIXES= .o .c .c~ .s .s~ .S .S~ .ln .f .f~ .F .F~ .l .l~ .mod .mod~ .sym .def .def~ .p .p~ .r .r~ .y .y~ .h .h~ .sh .sh~ .cps .cps~
OUTPUT_OPTION =
CC= cc
CFLAGS =
CPPFLAGS =
LINT= lint
LINTFLAGS =
COMPILE.c= $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
LINK.c= $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
LINT.c= $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)
YACC= yacc
YFLAGS =
YACC.y= $(YACC) $(YFLAGS)
LEX= lex
LFLAGS =
LEX.l= $(LEX) $(LFLAGS) -t
FC= f77
FFLAGS =
COMPILE.f= $(FC) $(FFLAGS) $(TARGET_ARCH) -c
LINK.f= $(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH)
COMPILE.F= $(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
LINK.F= $(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
RFLAGS =
COMPILE.r= $(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -c
LINK.r= $(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) $(TARGET_ARCH)
M2C= m2c
M2FLAGS =
MODFLAGS =
DEFFLAGS =
COMPILE.def= $(M2C) $(M2FLAGS) $(DEFFLAGS) $(TARGET_ARCH)
COMPILE.mod= $(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH)
PC= pc
PFLAGS =
COMPILE.p= $(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
LINK.p= $(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
AS= as
ASFLAGS =
COMPILE.s= $(AS) $(ASFLAGS) $(TARGET_MACH)
COMPILE.S= $(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c
LD= ld
LDFLAGS =
LDLIBS =
MAKE= make
RM= rm -f
AR= ar
ARFLAGS= rv
GET= /usr/sccs/get
GFLAGS =
HOME= /u1/morreale
TERM= adm3a
USER= morreale
PATH= /u3/gnu/sun4/usr/local/bin:/bin:/usr/ucb:/u1/morreale/bin:.:/usr/bin/X11:/usr/bin:/usr/etc:/usr/local/bin
LOGNAME= morreale
PWD= /u1/morreale/flatau
DISPLAY= laplata:0.0
TERMCAP= la|adm3a|3a:am:do=^J:le=^H:bs:cm=\E=%+\040%+\040:cl=1^Z:co#80:ho=^^:li#24:ma=^K^P:nd=^L:up=^K:
EDITOR= /usr/ucb/vi
EKBD= vt100
GRAPHCAP= X11
MAP3270= /u1/morreale/.map3270
VISUAL= /usr/ucb/vi
PRINTER= scdimagen
VIRTUAL_ROOT= /
stat(.make.state)
MAKEFLAGS= 
stat(makefile)
doname(makefile)
 Looking for % rule for makefile
 find_double_suffix_rule(makefile)
 find_suffix_rule(makefile,makefile,)
FILES= f1.o
stat(.INIT)
doname(.INIT)
 Looking for % rule for .INIT
 find_double_suffix_rule(.INIT)
 stat(compile)
 doname(compile)
@ =
  stat(f1.o)
  doname(f1.o)
   Looking for % rule for f1.o
   find_double_suffix_rule(f1.o)
   find_suffix_rule(f1.o,f1,.o)
   build_suffix_list(.o) .c.o .s.o .S.o .f.o .F.o .l.o .mod.o .p.o .r.o .y.o .pp.o 
   Trying f1.c
   Trying f1.s
   Trying f1.S
   Trying f1.f
   Trying f1.F
   Trying f1.l
   Trying f1.mod
   Trying f1.p
   Trying f1.r
   Trying f1.y
   Trying f1.pp
   stat(f1.pp)
   doname(f1.pp)
    Looking for % rule for f1.pp
    find_double_suffix_rule(f1.pp)
    find_suffix_rule(f1.pp,f1,.pp)
    build_suffix_list(.pp) 
   Found f1.pp
   Date(f1.pp)=Sat Aug 11 18:23:07 1990 Date-dependencies(f1.o)=File does not exist
   Building f1.o using suffix rule for .pp.o because it is out of date relative to f1.pp
   find_suffix_rule(f1.o,f1.o,)
   build_suffix_list() .c .f .F .l .mod .p .r .y .sh 
   Trying f1.o.c
   Trying f1.o.f
   Trying f1.o.F
   Trying f1.o.l
   Trying f1.o.mod
   Trying f1.o.p
   Trying f1.o.r
   Trying f1.o.y
   Trying f1.o.sh
@= f1.o
*= f1
<= f1.pp
% =
? = f1.pp
@ =
* =
< =
% =
? =
cp f1.pp f1.f
   stat(.make.state)
   stat(f1.o)
  Date(f1.o)=Younger than any file Date-dependencies(compile)=File does not exist
  Building compile because it is out of date relative to f1.o
  Looking for % rule for compile
  find_double_suffix_rule(compile)
@= compile
* =
< =
% =
? = f1.o
@ =
* =
< =
% =
? =
Why .f.o is not being applied
  stat(.make.state)
  stat(compile)
 stat(.DONE)
 doname(.DONE)
  Looking for % rule for .DONE
  find_double_suffix_rule(.DONE)
--
------------------------------------------------------------------
Peter W. Morreale                  email:  morreale@ncar.ucar.edu
Nat'l Center for Atmos Research    voice:  (303) 497-1293
Scientific Computing Division     

andre@targon.UUCP (andre) (08/14/90)

In article <8212@ncar.ucar.edu> morreale@bierstadt.scd.ucar.edu (Peter Morreale) writes:
 >Consider the following makefile:
 >
 >.pp.o:
 >       cp $*.pp $*.f
 >
 >.SUFFIXES:  $(SUFFIXES) .pp
 >FILES= f1.o
 >
 >compile: $(FILES)
 >       @echo "Why isn't .f.o  applied?"
 >
 >clean:
 >       -rm -f $(FILES)  *.f

 >You'll notice that the ".pp.o" rule is executed, and then the
 >compile rule.  The question is:  Why isn't the default ".f.o" rule
 >executed before the "compile" target?  (If you type make again, the
 >".f.o" rule is executed and all is well....)

This is because you told make how to make a .o file from a .pp file.
after the commands involved are executed, make goes on because it just
did what you told it to do to get an object out of an .pp file.
But! you created an .f file and no .o file. this means that you should
tell make that you make a .f file or make the .o file:

.pp.o:
	cp $< $*.f
	$(FCOMP) -o $*.o $*.f
	  ^-- whatever you need to go from .f to .o (fortran?)
OR

.pp.f:
	cp $< $*.f

In the second case make should add up both the .pp.f and .f.o rules
to make your .o out of .pp.

-- 
The mail|    AAA         DDDD  It's not the kill, but the thrill of the chase.
demon...|   AA AAvv   vvDD  DD        Ketchup is a vegetable.
hits!.@&|  AAAAAAAvv vvDD  DD                    {nixbur|nixtor}!adalen.via
--more--| AAA   AAAvvvDDDDDD    Andre van Dalen, uunet!hp4nl!targon!andre

volpe@underdog.crd.ge.com (Christopher R Volpe) (08/15/90)

In article <1446@targon.UUCP>, andre@targon.UUCP (andre) writes:
|>In article <8212@ncar.ucar.edu> morreale@bierstadt.scd.ucar.edu (Peter
Morreale) writes:
|> >Consider the following makefile:
|> >
|> >.pp.o:
|> >       cp $*.pp $*.f
|> >
|> >.SUFFIXES:  $(SUFFIXES) .pp
|> >FILES= f1.o
|> >
|> >compile: $(FILES)
|> >       @echo "Why isn't .f.o  applied?"
|> >
|> >clean:
|> >       -rm -f $(FILES)  *.f
|>
|> >You'll notice that the ".pp.o" rule is executed, and then the
|> >compile rule.  The question is:  Why isn't the default ".f.o" rule
|> >executed before the "compile" target?  (If you type make again, the
|> >".f.o" rule is executed and all is well....)
|>
|>This is because you told make how to make a .o file from a .pp file.
|>after the commands involved are executed, make goes on because it just
|>did what you told it to do to get an object out of an .pp file.
|>But! you created an .f file and no .o file. this means that you should
|>tell make that you make a .f file or make the .o file:
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
           not good enough!!!                
|>
|>.pp.o:
|>	cp $< $*.f
|>	$(FCOMP) -o $*.o $*.f
|>	  ^-- whatever you need to go from .f to .o (fortran?)
|>OR
|>
|>.pp.f:
|>	cp $< $*.f
|>
|>In the second case make should add up both the .pp.f and .f.o rules
|>to make your .o out of .pp.

No, it won't. At least not on a Sun. From the Make User's Guide:
      There is no transitive closure for suffix rules. If you had
      a suffix rule for building, say, a .Y file from a .X file, and
      another for building a .Z file from a .Y file, make would not
      combine the rules to build a .Z file from a .X file. You must
      specify the intermediate steps as targets, although their entries
      may have null rules:
          trans.Z:
          trans.Y:

If all you have is a .pp.f rule and a .f.o rule, and you say "make f1.o",
one of the following must be true:
a) there exists a f1.f file, or
b) f1.f is EXPLICITLY listed as a target *AND* file f1.pp exists

Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com                                           

dik@cwi.nl (Dik T. Winter) (08/15/90)

In article <1446@targon.UUCP> andre@targon.UUCP (andre) writes:
 > 	$(FCOMP) -o $*.o $*.f
 > 	  ^-- whatever you need to go from .f to .o (fortran?)

Please, use $(FC) which is predefined on most systems, and evaluates to the
fortran compiler (which can be named f77, fort, fc, fortran, ...).
--
dik t. winter, cwi, amsterdam, nederland
dik@cwi.nl