[comp.sys.mac.programmer] MPW Make file weirdness

mdtaylor@Apple.COM (Mark Taylor) (12/03/90)

The source code for my C program is divided into several files (let's say
file1.c, file2.c, etc.,) each with its own header file (file1.h, file2.h,
etc.)  Each .c file #includes the .h files it needs, and my makefile reflects
these dependencies so that if I modify, say, file2.h, only those .c files
that #include file2.h are re-compiled.

So far, so good.

But then it occurs to me that, say, file2.h itself #includes a basic header
file, called, say, basic.h.  I would like my makefile to reflect this
dependency.  So I create one dependency rule in my makefile that says, simply:

file2.h <option-f> basic.h

This doesn't work as I expect.  After the first make using this new makefile,
then no matter what I do (or don't do), all the .c files that include file2.h
are always recompiled.  Even if I start a second make immediately after the
first, without changing anything, all my .c files that include file2.h are
recompiled!

The only fix is to put basic.h in the dependency rule of each .c file that
already contains file2.h.

Why doesn't the way I tried work, and/or what is the proper way to do this?

Thanks in advance,

- Mark

kaufman@Neon.Stanford.EDU (Marc T. Kaufman) (12/04/90)

In article <11406@goofy.Apple.COM> mdtaylor@Apple.COM (Mark Taylor) writes:

>But then it occurs to me that, say, file2.h itself #includes a basic header
>file, called, say, basic.h.  I would like my makefile to reflect this
>dependency.  So I create one dependency rule in my makefile that says, simply:

>file2.h <option-f> basic.h

>This doesn't work as I expect.

Try the following:

	file2.h <option-f> basic.h
		setfile -m file2.h

This will change the modification date of file2.h (like the UN*X 'touch'
command), so that it is newer than basic.h and will cause the desired
compiles.

Marc Kaufman (kaufman@Neon.stanford.edu)

Garance_Drosehn@mts.rpi.edu (Garance Drosehn) (12/04/90)

In article <11406@goofy.Apple.COM> 
           mdtaylor@Apple.COM (Mark Taylor) writes:
> But then it occurs to me that, say, file2.h itself #includes a basic 
> header file, called, say, basic.h.  I would like my makefile to reflect
> this dependency.  So I create one dependency rule in my makefile that 
> says, simply:
> 
> file2.h <option-f> basic.h
> 
> This doesn't work as I expect.  After the first make using this new 
> makefile, then no matter what I do (or don't do), all the .c files 
> that include file2.h are always recompiled.  Even if I start a second
> make immediately after the first, without changing anything, all 
> my .c files that include file2.h are recompiled!

What that rule basically says is "make file2.h if it has not changed since 
basic.h has changed".  However, you do nothing to file2.h when doing this, 
so the last-modified time of it does not change.  Thus, the next time you 
make it, it will still be true that file2.h has not changed since basic.h 
has changed.

You can either do something with Setfile to change the last-modified time 
of file2.h, or use a different tactic.  My preference is to use a 
different tactic, because strictly speaking the file file2.h does *not* 
depend on basic.h, it's just that other files which depend on file2.h may 
also depend on basic.h.  You'll end up with a file2.h that is constantly 
"changing", even though you may never change any of the text actually in 
it.

The different tactic I would use is to add a variable in your processing.  
Eg:

FILE2.Hs = File2.h Basic.h

And then, in whatever dependencies where you currently use "file2.h" 
change that to "{FILE2.Hs}".  Effectively this is the same as what you did 
by adding Basic.h to each dependency, except that it makes it clearer 
*why* it's being added to them.  It's also easier to change (in case you 
change File2.h to include some other files).

Garance_Drosehn@mts.rpi.edu
ITS Systems Programmer
Rensselaer Polytechnic Institute; Troy, NY.  USA

rmh@apple.com (Rick Holzgrafe) (12/04/90)

In article <11406@goofy.Apple.COM> mdtaylor@Apple.COM (Mark Taylor) writes:
> But then it occurs to me that, say, file2.h itself #includes a basic 
header
> file, called, say, basic.h.  I would like my makefile to reflect this
> dependency.  So I create one dependency rule in my makefile that says, 
simply:
> 
> file2.h <option-f> basic.h
> 
> This doesn't work as I expect.

Right. An <option-f> production says to re-make the stuff on the left 
whenever it's older than the stuff on the right... but you don't want to 
re-make file2.h. You want to re-make file2.c.o. So the correct thing to 
do, as you tried, is:

file2.c.o <option-f> file2.h basic.h

Agreed, it's a pain; fully correct makefiles are always a pain. You can 
reduce the pain either by careful use of macros (as Garance just 
suggested, I think) or by using a tool to generate dependencies 
automatically. There's one called "MakeMake" on the Developer's CD (ever 
since vol. 3, I think) that automates building and maintaining entire 
makefiles, including full dependency lists. It's not all things to all 
people, but it's pretty good if I say so myself. (I'm a co-author of it 
along with scott douglass.)

If you're interested in MakeMake, see if you can find a friend with a 
reasonably recent Developer's CD ("A Disc Called Wanda" or later version) 
to get it from. Please don't ask me to E-mail it, as it's a largish MPW 
tool and would consume a lot of bandwidth (as well as a lot of my limited
time).

==========================================================================
Rick Holzgrafe              |    {sun,voder,nsc,mtxinu,dual}!apple!rmh
Software Engineer           | AppleLink HOLZGRAFE1          rmh@apple.com
Apple Computer, Inc.        |  "All opinions expressed are mine, and do
20525 Mariani Ave. MS: 3-PK |    not necessarily represent those of my
Cupertino, CA 95014         |        employer, Apple Computer Inc."

ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) (12/04/90)

In <1990Dec3.172201.17768@Neon.Stanford.EDU>, kaufman@Neon.Stanford.EDU
(Marc T. Kaufman) suggests a Make rule for updating the dependency
of one .h file on another.

He gets it *almost* correct, only missing a ".". Here is the correct
form of the rule:

	file2.h \f file1.h
	    SetFile -m . file2.h

("\f" = option-f -- see the MPW tools I posted a week or two back.)
I have encountered the same situation myself, and the above rule
(changing the modification date on file2.h to be "now") seems the
simplest solution.

Lawrence "If it can't be done with MPW, it isn't worth doing" D'Oliveiro
Computer Services Dept                              fone: +64-71-562-889
University of Waikato                                fax: +64-71-384-066
Hamilton, New Zealand                   electric mail: ldo@waikato.ac.nz