[comp.unix.questions] Strange makefile construct

chris@nrcvax.UUCP (Chris Grevstad) (09/02/87)

I was looking at some source that came across the net some time ago and
ran across a very strange construct in the makefile.  It appears that this
makefile is targeted for a SYSV system and I am familiar only with 4.2BSD
make.

This is the weirdness:

target: file1.o file2.o file3.o file4.o
	$(CC) $(CFLAGS) $(?:.o=.c)

Any suggestions?  I'm hacking on the 4.3BSD make and wouldn't mind putting
this in, if it does what I think it does.

My interpretation says:
	This:
		$(CC) $(CFLAGS) $(?:.o=.c)
	becomes this:
		$(CC) $(CFLAGS) file1.c file2.c file3.c file4.c

If my interpretation is correct, then exactly what does $(?:.o=.c) mean?
Does the colon signify merely a modifier for the $? macro?  Or is it some
perversion of the standard colon dependency?  And is the equals sign a
special instance of the regular macro definition construct?  Or does it just
specify a transform of all elements in $? that terminate in .o?

As an aside, can someone enumerate some of the differences between the 4.3BSD
make and the Fourth Generation Make (or whatever they call it) from AT&T?

Any informed answers are gratefully anticipated.


-- 
	Chris Grevstad
	hplabs!sdcrdcf!psivax!nrcvax!chris
	ihnp4!nrcvax!chris

Refund?  REFUND!? ..... REFUND!?!?!

boykin@custom.UUCP (Joseph Boykin) (09/04/87)

In article <1162@nrcvax.UUCP>, chris@nrcvax.UUCP (Chris Grevstad) writes:
> I was looking at some source that came across the net some time ago and
> ran across a very strange construct in the makefile.  It appears that this
> makefile is targeted for a SYSV system and I am familiar only with 4.2BSD
> make.
> 
> This is the weirdness:
> 
> target: file1.o file2.o file3.o file4.o
> 	$(CC) $(CFLAGS) $(?:.o=.c)
> 
> Any suggestions? [....]
> 
> My interpretation says:
> 	This:
> 		$(CC) $(CFLAGS) $(?:.o=.c)
> 	becomes this:
> 		$(CC) $(CFLAGS) file1.c file2.c file3.c file4.c

You're correct, except for one caveat. Here's what the PC/MAKE
documenation says about this:

	"The sequence :string1=string2 is a substitution
	sequence.  All occurrences of string1 which appear
	prior to a blank or tab are replaced by string2.  For
	example, substitute .c for all occurrences of .obj in the
	macro OBJECTS:
		$(OBJECTS:.obj=.c)

In the example you have, $(?.o=.c) will generate files with a .c
extension from those dependencies which were found to be newer
than the target.  The problem with this particular command is
that 'target' may now be compiled with only three (or less) files
instead of all four if one or more of the .o files was not modified;
given the command, this may cause an error.

Joe Boykin
Custom Software Systems
...necntc!custom!boykin

chris@nrcvax.UUCP (Chris Grevstad) (09/06/87)

In article <1162@nrcvax.UUCP>, I (Chris Grevstad) write:
> I was looking at some source that came across the net some time ago and
> ran across a very strange construct in the makefile.  It appears that this
> makefile is targeted for a SYSV system and I am familiar only with 4.2BSD
> make.
> 
> This is the weirdness:
> 
> target: file1.o file2.o file3.o file4.o
> 	$(CC) $(CFLAGS) $(?:.o=.c)
> 
> Any suggestions? [....]
> 
> My interpretation says:
> 	This:
> 		$(CC) $(CFLAGS) $(?:.o=.c)
> 	becomes this:
> 		$(CC) $(CFLAGS) file1.c file2.c file3.c file4.c

and boykin@custom.UUCP (Joseph Boykin) responds:
> [agreement as to my interpretation but has a caveat]
> ...
>than the target.  The problem with this particular command is
>that 'target' may now be compiled with only three (or less) files
>instead of all four if one or more of the .o files was not modified;
>given the command, this may cause an error.

Yes, that is true if the target is supposed to be some sort of executable.
In the application that I found this, the target is in fact a library, and
the $(CC) line is followed by a few lines that either create the library
or update the library, whichever is needed.

Guy Harris (I think it was Guy, I have since deleted the mail) also responded
to the latter part of my posting about the 4th generation make by pointing
out something to me that I had forgotten, which is that there is a very good
description of the new make in the proceeedings for the Portland Usenix
conference.

-- 
	Chris Grevstad
	cit-vax!elroy!nrcvax!chris@rutgers.edu
	hplabs!sdcrdcf!psivax!nrcvax!chris
	ihnp4!nrcvax!chris

allbery@ncoast.UUCP (09/07/87)

As quoted from <1162@nrcvax.UUCP> by chris@nrcvax.UUCP (Chris Grevstad):
+---------------
| I was looking at some source that came across the net some time ago and
| ran across a very strange construct in the makefile.  It appears that this
| makefile is targeted for a SYSV system and I am familiar only with 4.2BSD
| make.
| 
| This is the weirdness:
| 
| target: file1.o file2.o file3.o file4.o
| 	$(CC) $(CFLAGS) $(?:.o=.c)
| 
| Any suggestions?  I'm hacking on the 4.3BSD make and wouldn't mind putting
| this in, if it does what I think it does.
+---------------

The `:' signals a substitution:

$(?:.o=.c) means "in all words in $?, change instances of `.o' into `.c'.

Note that, to my knowledge (which may be faulty), there is no way to prevent
this macro from changing `foo.obj.c' to `foo.cbj.c'.
-- 
	    Brandon S. Allbery, moderator of comp.sources.misc
  {{harvard,mit-eddie}!necntc,well!hoptoad,sun!mandrill!hal}!ncoast!allbery
ARPA: necntc!ncoast!allbery@harvard.harvard.edu  Fido: 157/502  MCI: BALLBERY
   <<ncoast Public Access UNIX: +1 216 781 6201 24hrs. 300/1200/2400 baud>>
All opinions in this message are random characters produced when my cat jumped
(-:		      up onto the keyboard of my PC.			   :-)

woolsey@nsc.nsc.com (Jeff Woolsey) (09/09/87)

In article <1162@nrcvax.UUCP> chris@nrcvax.UUCP (Chris Grevstad) writes:
>This is the weirdness:
>
>target: file1.o file2.o file3.o file4.o
>	$(CC) $(CFLAGS) $(?:.o=.c)
>
>My interpretation says:
>	This:
>		$(CC) $(CFLAGS) $(?:.o=.c)
>	becomes this:
>		$(CC) $(CFLAGS) file1.c file2.c file3.c file4.c
>

All I need now is something that turns

FILES = one two three four

into

	$(CC) $(CFLAGS) one.c two.c three.c four.c

and a default rule to go along with it.  I know about basename(1), but
it doesn't do what I want.
-- 
"Gloria has a visible organism."  - B. Kliban.

Jeff Woolsey	National Semiconductor Corporation
...!nsc!woolsey -or- woolsey@nsc.COM -or- woolsey@umn-cs.ARPA

egb@mitisft.Convergent.COM (E. G. Bradford ) (09/15/87)

in article <4475@ncoast.UUCP>, allbery@ncoast.UUCP (Brandon Allbery) says:
> 
> As quoted from <1162@nrcvax.UUCP> by chris@nrcvax.UUCP (Chris Grevstad):
> +---------------
> 
> $(?:.o=.c) means "in all words in $?, change instances of `.o' into `.c'.
> 
> Note that, to my knowledge (which may be faulty), there is no way to prevent
> this macro from changing `foo.obj.c' to `foo.cbj.c'.

I did that particluar gem to make. It will not substitute
for foo.obj.c. "word" is delimited by white space or end of string.

		Ed Bradfichw

sue@encore.UUCP (Sue LoVerso) (09/15/87)

In article <4624@nsc.nsc.com> woolsey@nsc.UUCP (Jeff Woolsey) writes:
>All I need now is something that turns
>
>FILES = one two three four
>
>into
>
>	$(CC) $(CFLAGS) one.c two.c three.c four.c
>

On a Multimax, running Mach:


Script started on Tue Sep 15 11:48:27 1987
multimax >> src.test 27 >> cat makefile

FILES=	one two three four

all:
	$(CC) $(CFLAGS) $(FILES:=.c)

multimax >> src.test 28 >> /usr/cs/bin/make -n
cc  one.c two.c three.c four.c
multimax >> src.test 29 >> exit
Script ended on Tue Sep 15 11:49:14 1987


-- 
Susan J. LoVerso		Encore Computer Corp.
sue@multimax.arpa		
encore!sue

wagner@iaoobelix.UUCP (09/17/87)

/***** iaoobelix:comp.unix.ques / nsc!woolsey / 12:13 am  Sep  9, 1987*/
> All I need now is something that turns
> 
> FILES = one two three four
> 
> into
> 
> 	$(CC) $(CFLAGS) one.c two.c three.c four.c
> 
> and a default rule to go along with it.  I know about basename(1), but
> it doesn't do what I want.
...
> Jeff Woolsey	National Semiconductor Corporation

Ok. So, how about using a default rule, anyway? You want to have some
object files depending on some source files. As far as transformations
between source and object file names are restricted to mere suffix
substitution (exception: under SYSV and on Suns you can use the empty
suffix), it shouldn't be the least bit difficult to write such a dependency.

OBJS	= one.o two.o three.o four.o

foo:	$(OBJS)
	$(CC) $(LDFLAGS) -o foo $(OBJS)

.c.o:	
	$(CC) $(CFLAGS) -c $*.c

Or what were your intentions with the construct above?
Did you want to get four separate programs with that single
dependency (sorry, I am just asking)? In that case, you
have to write (under SYSV and friends):

BINS	= one two three four

.c:	
	$(CC) $(LDFLAGS) -o $* $*.o

.c.o:	
	$(CC) $(CFLAGS) -c $*.c

I hope this helps.

Juergen Wagner,		     (USENET) ...seismo!unido!iaoobel!wagner
("Gandalf")			 Fraunhofer Institute IAO, Stuttgart

bww@k.gp.cs.cmu.edu (Bradley White) (09/20/87)

In article <1942@encore.UUCP>, sue@encore.UUCP (Sue LoVerso) writes:
> In article <4624@nsc.nsc.com> woolsey@nsc.UUCP (Jeff Woolsey) writes:
> >All I need now is something that turns
> >
> >FILES = one two three four
> >
> >into
> >
> >	$(CC) $(CFLAGS) one.c two.c three.c four.c
> >
> 
> On a Multimax, running Mach:
> 
> Script started on Tue Sep 15 11:48:27 1987
> multimax >> src.test 27 >> cat makefile
> 
> FILES=	one two three four
> 
> all:
> 	$(CC) $(CFLAGS) $(FILES:=.c)
> 
> multimax >> src.test 28 >> /usr/cs/bin/make -n
> cc  one.c two.c three.c four.c
> multimax >> src.test 29 >> exit
> Script ended on Tue Sep 15 11:49:14 1987

As far as I know, using a NULL "from" string in a macro translation
only works with the CMU-CS/Mach version of "make", as shown above.
This version is a modification of that distributed with 4.3BSD and
supports all "known" SysV features (the archive making rules are
slightly different) plus RCS files and a fixed $VPATH.
-- 
Bradley White <bww@cs.cmu.edu>         +1-412-268-3060
CMU Computer Science Department  40 26'33"N 79 56'48"W