[comp.bugs.sys5] make bug?

rogerc@ncrcae.Columbia.NCR.COM (Roger Collins) (01/18/88)

When make is executed with the following description file,

-------------------------------------------
x :	x.o

x.o :	x.c

x.c :
	echo "main(){}" >x.c
-------------------------------------------

	1. x.c gets made by the explicit "echo ..." command
	2. x.o gets made by the default .c.o rule
	3. nothing is done to make x (because of the explicit nothing?)

Why does no-command mean use default rule in one case, yet it means do
nothing in another case?

I added the explicit rule ".o: cc $< -o $@" to the beginning of
the description file; no change.  Just for fun I added the explicit 
rule ".c.o: cc -c $<".  Then only the the .c file was made.

I am running Sys5.2.

This seems like a bug to me.  I think no-command should mean if rule exists,
use it, otherwise print diagnostic.  What do you think?

--
Roger Collins
NCR - E&M Columbia - TOWER Systems
rogerc@ncrcae.Columbia.NCR.COM

bww@K.GP.CS.CMU.EDU (Bradley White) (01/19/88)

In article <2979@ncrcae.Columbia.NCR.COM>, rogerc@ncrcae.Columbia.NCR.COM (Roger Collins) writes:
> Why does no-command mean use default rule in one case, yet it means do
> nothing in another case?

Because one is a double suffix rule and the other a single suffix
rule.  Single suffix rules are only used if a target has no commands
AND no explicit dependents in it's FIRST entry.  So, add "x:" before
"x: x.o" while adding ".o:; cc $< -o $@", and everything should work
as you expect.  (There is usually no built-in ".o:" rule.)

> This seems like a bug to me.  I think no-command should mean if rule exists,
> use it, otherwise print diagnostic.  What do you think?

I agree.  Or at least that EVERY entry should be tested for dependents.
-- 
Bradley White <bww@cs.cmu.edu>         +1-412-268-3060
CMU Computer Science Department  40 26'33"N 79 56'48"W

worley@dana.UUCP (John Worley) (01/20/88)

> 
> When make is executed with the following description file,
> 
> -------------------------------------------
> x :	x.o
> 
> x.o :	x.c
> 
> x.c :
> 	echo "main(){}" >x.c
> -------------------------------------------
> 
> Why does no-command mean use default rule in one case, yet it means do
> nothing in another case?
> 
> I added the explicit rule ".o: cc $< -o $@" to the beginning of
> the description file; no change.  Just for fun I added the explicit 
> rule ".c.o: cc -c $<".  Then only the the .c file was made.
> 
> This seems like a bug to me.  I think no-command should mean if rule exists,
> use it, otherwise print diagnostic.  What do you think?

    When you type an empty action line, it means exactly that - do nothing.
In make, it is possible to specify multiple dependency lines:

	OBJ = x.o y.o z.o

	$(OBJ): all.h global.h
		cc -DBLAH -c $<

	x.o:	x.h

	y.o:	y.h

	z.o:	z.h

    Exactly zero or one of these can have an action - otherwise the order
of execution is ambiguous.  For some common dependencies, however, make has
a default action which it checks IFF there is no action specified on any
line containing the target.

    Making the NULL rule and error would break the following common, and
prefectly valid, makefile organization

	all:	a b c

	a:	a.o
		cc -o a a.o

	b:	b.o
		cc -o b b.o

	c:	c.o
		cc -o c c.o

	a.o b.o c.o:	global.h

    Therefore, the NULL action is and should be perfectly acceptable.
If, after performing the actions, the dependencies are not satisfied,
make will print the "Don't know how to make ...".  Your problem would
best be solved by adding the line

	all:	x

				Regards,
				John S. Worley
				Ardent Computer, Inc.
				hplabs!dana!worley	till 1/31/88
				hplabs!ardent!worley	after

chip@ateng.UUCP (Chip Salzenberg) (01/22/88)

In article <292@dana.UUCP> worley@dana.UUCP (John Worley) writes:
>
>In make, it is possible to specify multiple dependency lines:
>
>       [example deleted]
>
>    Exactly zero or one of these can have an action...

This is only true for "normal" dependencies.  If you specify a dependency
with two colons instead of one, then you can have a different action for
each dependency line:

	# If bar1 is newer than foo, do this
	foo::   bar1
		echo bar1

	# If bar2 is newer than foo, do this
	foo::   bar2
		echo bar2

I've never had a need for this feature, but it seems like it should be
useful for _something_. :-)
-- 
Chip Salzenberg                 UUCP: "{codas,uunet}!ateng!chip"
A T Engineering                 My employer's opinions are a trade secret.
       "Anything that works is better than anything that doesn't."

wesommer@athena.mit.edu (William E. Sommerfeld) (01/24/88)

In article <158@ateng.UUCP> chip@ateng.UUCP (Chip Salzenberg) writes:
>If you specify a [make] dependency
>with two colons instead of one, then you can have a different action for
>each dependency line ...
>I've never had a need for this feature, but it seems like it should be
>useful for _something_. :-)

Yep, it is.  The X version 11 distribution uses a tool called `imake'
(written by Todd Brunhoff of Tektronix), which runs a file through the
C preprocessor, then a `cleanup' filter (which gets rid of the # line
directives and extra vertical whitespace, and turns `@@' into newline,
permitting multiple-line macros), and then through `make'.

You can define macros like the following:

#define simple(pgm,locallibs,syslibs)					@@\
									@@\
all:: pgm								@@\
									@@\
pgm: concat(pgm,.c) locallibs						@@\
	$(CC) $(CFLAGS) -o $@ $@.c locallibs syslibs			@@\
									@@\
clean::									@@\
	$(RM) pgm concat(pgm,.o) 					@@\
									@@\
instal::								@@\
	$(INSTALL) pgm $(INSTALLDIR)

and invoke it several times in an Imakefile without running into
difficulty.

					- Bill