[comp.lang.c] Desperately Seeking Makefile Maker

nate@cpocd2.UUCP (Nathan Hess) (12/16/87)

I'm posting this request for a colleague.  Please mail any and all
responses to me, and I will forward them on to him.  Many thanks!


	Is there a program available that creates makefiles, preferrably
	written in C?


--woodstock
-- 
	   "How did you get your mind to tilt like your hat?"

...!{decwrl|hplabs!oliveb|pur-ee|qantel|amd}!intelca!mipos3!cpocd2!nate
<domainish> :   nate@cpocd2.intel.com		ATT :    (602) 961-2037

billc@prism.UUCP (12/17/87)

> I'm posting this request for a colleague.  Please mail any and all
> responses to me, and I will forward them on to him.  Many thanks!
> 
> 
> 	Is there a program available that creates makefiles, preferrably
> 	written in C?
> 
> 
> --woodstock
	
	Say, if you wouldn't mind, I'm sure that many of us would be
	interested in seeing a condensation of the replies.  I'm
	assuming that your colleague is interested in a Makefile maker
	for C libraries, since you posted here.


Bill C.		billc@mirror.TMC.COM
		{mit-eddie, ihnp4, wjh12, cca, cbosgd, seismo}!mirror!billc

creps@silver.bacs.indiana.edu (Steve Creps) (12/17/87)

In article <1034@cpocd2.UUCP> nate@cpocd2.UUCP (Nathan Hess) writes:
>	Is there a program available that creates makefiles, preferrably
>	written in C?

   I thought this may be of general interest to the group, so I'm posting
it here.
   This problem sounds like something that could be easily done using the
standard Unix utilities. If your only file dependencies come from #include
lines in the files, then this should work pretty well. Use fgrep to
find all the #include's, and pipe it to awk for prettying up.
You could say something like this:
fgrep #include *.c *.h | awk -f makefile.awk >makefile

and makefile.awk might look something like this:
BEGIN { ORS = " "; filename = 0 }
{ if ($1 != filename) { filename = $1; print "\n" filename,":",$3 }
  else print " " $3 }
END { print "\n" }

What I'm hoping is that fgrep will output records of the form
file1: #include "foo.h"
file1: #include "bar.h"
file2: #include "foo.h"

and that for example $1 will get file2, and $3 will get "foo.h". Also, note
how I changed the output record separator (ORS) from newline to space,
and then print a newline with a file name every time the file name changes.
What I'm trying to get as output for the above example is this:
file1 : "foo.h" "bar.h"
file2 : "foo.h"

I'm writing this on the fly, so it may be a little buggy, but it should
work with little or no modification. I'll test it after I post this, and
see how it works.

-	-	-	-	-	-	-	-	-
Steve Creps on the VAX 8650 running Ultrix 2.0-1 at Indiana University.
	creps@silver.bacs.indiana.edu
"F-14 Tomcat! There IS no substitute."

creps@silver.bacs.indiana.edu (Steve Creps) (12/17/87)

   What I posted previously on using fgrep and awk worked just fine,
except that I had to first edit the output from fgrep to change the
":"'s following the file names to spaces. Then all you'll have to do
is some minor editing to remove quote characters, and remove any
system include files which you probably don't want in your makefile.
Anyway, this method gave me a good makefile list of dependencies.

-	-	-	-	-	-	-	-	-
Steve Creps on the VAX 8650 running Ultrix 2.0-1 at Indiana University.
	creps@silver.bacs.indiana.edu
"F-14 Tomcat! There IS no substitute."

rsalz@bbn.com (Rich Salz) (12/18/87)

The "SPMS Software Project Management System" provided on the 4.3BSD
source tape as user-contributed software provides a tool called mkmf
to create makefiles.  Folks without BSD sources should probably contact
the author (no, I don't have an email address):
	Peter J Nicklen
	Division of Structural Engineering and Structural Mechanics
	Department of Civil Engineering
	University of California, Berkeley
	Berkeley, California 94720

Followups to comp.sources.d...
	/r$
-- 
For comp.sources.unix stuff, mail to sources@uunet.uu.net.

ljz@fxgrp.UUCP (Lloyd Zusman, Master Byte Software) (12/18/87)

In article <538@silver.bacs.indiana.edu> creps@silver.UUCP (Steve Creps) writes:
>In article <1034@cpocd2.UUCP> nate@cpocd2.UUCP (Nathan Hess) writes:
>>	Is there a program available that creates makefiles, preferrably
>>	written in C?
> ...
>   This problem sounds like something that could be easily done using the
>standard Unix utilities.  ...
> ...
>You could say something like this:
>fgrep #include *.c *.h | awk -f makefile.awk >makefile
> ...

This sort of thing is fine as far as it goes, but what about nested
includes?  What about the differences between #includes that use
double quotes and those that use angle brackets?

There is something much better called 'mkmf' that makes makefiles.  It
handles the above cases just fine and produces a useful makefile.  As
far as I know, it's "netware", which means it's public domain and is
distributed over the net.  We have it here at my installation, and as
soon as I can determine if it truly *is* netware, I could shar it up
and email it to whomever is interested, source and all.  Contact me at
the address below if you want this, but *PLEASE* check here on the net
first to see if it's in one of the source archives, as it would be
better to get it from there.

In addition, I have a program I developed for the IBM PC that also
generates makefiles.  Its advantage is that it uses regular expression
syntax to define the format of an include statement, and each file
suffix can have such a regular expression (or group thereof)
associated with it.  This allows the utility also to be used for
programs written in languages other than C, most notably assembly
language and Pascal on the IBM PC.  This program handles nested
includes, but right now doesn't do anything special to distinguish
angle-bracket and double-quote includes.  This is because the various
C compilers on the IBM PC don't handle these in a uniform manner.  An
added feature of this program is for it to produce an include map for
all the source files processed by it.  This is particularly useful for
figuring out what's going on with nested includes.

This program of mine is not quite ready for distribution, as I have
not yet tried to port it to unix and because it is not fully tested.
I would distribute it as is to anyone who might want it, but I refuse
to support it until I've done more work on it.  Anyone who is
interested in this program please contact me at the address below.  Be
sure to give a nice, long, accurate uucp return address in your
posting, as I have extremely limited access to network maps.  The
only way to access my site is via 'ames' in California.

-------------------------------------------------------------------------
 Lloyd Zusman
 Master Byte Software
 Los Gatos, California	    	    	Internet:   fxgrp!ljz@ames.arpa
 "We take things well in hand."	    	UUCP:	    ...!ames!fxgrp!ljz

hunt@spar.SPAR.SLB.COM (Neil Hunt) (12/19/87)

In article <1034@cpocd2.UUCP> nate@cpocd2.UUCP (Nathan Hess) writes:
>	Is there a program available that creates makefiles, preferrably
>	written in C?

Here is a makefile maker which I have been using for a year or so.
It is based upon a version from Steve Rubin at Schlumberger, which may
be based upon something else...

Enjoy - Neil/.

#! /bin/csh
#
#	Script to make makefile entries for C source files.
#	Neil Hunt, Schlumberger Palo Alto Research 1986.
#	Ideas from Steve Rubin at Schlumberger.
#
# note: source files must spell /^#include/ with no spaces, and nested
#	includes are not supported. <files> are assumed stable, and
#	are not included in the dependency listing.
#
# example% depend file1.c file2.c >> Makefile
#
# egrep searches for include lines in source files; /dev/null is included
#	to force the filename to be printed even for a single source file.
#
# sed edits the lines to a form 'file.c: file.o include.h'
#
# awk assembles the lines into makefile format:
#	prev holds the previous file.c arg
#	doit holds a line of the form '   cc -c ${CFLAGS} file.c'
#	rec is a record initialised when a new 'file.c' is found,
#	and built up over the next few lines until its length would be > 75
#

egrep '^#include.*".*"' /dev/null $* | \
sed -e 's/\(.*\).c:[^"]*"\([^"]*\)".*/\1.o: \1.c \2/' | \
awk ' \
{ \
	if ($1 != prev) \
	{ \
		if (rec != "") \
		{ \
			print rec; \
			print doit; \
			print ""; \
		} \
		rec = $0; \
		prev = $1; \
		doit = "	cc -c ${CFLAGS} " $2; \
	} \
	else \
	{ \
		if (length(rec $3) > 75) \
		{ \
			print rec " \\"; \
			rec = "          " $3; \
		} \
		else rec = rec " " $3 \
	} \
} \
END { print rec; print doit; print ""; } '

nicklin@hpcilzb.HP.COM (Peter Nicklin) (12/19/87)

/ hpcilzb:comp.lang.c / rsalz@bbn.com (Rich Salz) / 11:25 am  Dec 17, 1987 /

> The "SPMS Software Project Management System" provided on the 4.3BSD
> source tape as user-contributed software provides a tool called mkmf
> to create makefiles.  Folks without BSD sources should probably contact
> the author (no, I don't have an email address):
> 	Peter J Nicklen
> 	Division of Structural Engineering and Structural Mechanics
> 	Department of Civil Engineering
> 	University of California, Berkeley
> 	Berkeley, California 94720

The author is now at the following address:

	Peter Nicklin
	Hewlett-Packard
	5301 Stevens Creek Boulevard
	Santa Clara, CA 95052
	(408) 553-2982
	nicklin%hpdtc@hplabs.hp.com
	ucbvax!hplabs!hpdtc!nicklin

Mkmf is in the public domain. It does not contain any proprietary
source code. The 4.3BSD version may be distributed without restriction.
	
	-pjn

PEPRBV%CFAAMP.BITNET@husc6.harvard.EDU (Bob Babcock) (12/19/87)

>>    Is there a program available that creates makefiles...

A makefile generator might be useful, but what would really be useful
is a makefile checker.  All my makefiles for work in progress are filled
with comments and special cases (program too large to put temporary
files in a RAM disk, etc.).  So a utility which could read an existing
makefile (and sources) and verify that the dependencies were correct
and that no extra routines were included in the linker lists would
be helpful.

-------
Bob Babcock
BITNET mail to PEPRBV@CFAAMP
            or PEPAP@CFA2  (autoforwarded to above)
other nets     PEPRBV%CFAAMP.BITNET@TALCOTT.HARVARD.EDU

dougs@sequent.UUCP (Doug Schwartz) (12/19/87)

O'Reilly and Associates have a book out called "UNIX Text Processing",
which is published by Hayden, that has a shell script on page 566 that
builds a makefile.  Of course, this is oriented toward n/troff tasks,
but you can modify it for any environment.  This is left as an exercise
for the reader :-).

If you fancy yourself as a n/troff hacker or want to know more about
UNIX text processing, I highly recommend this book.  It and Gehani's
"Document Formatting & Typesetting on the UNIX System", Silicon Press,
are the best I've seen.

Doug Schwartz
Sequent Computer
Beaverton, Oregon
tektronix!ogcvax!sequent!dougs

jgy@hropus.UUCP (John Young) (12/19/87)

> In article <1034@cpocd2.UUCP> nate@cpocd2.UUCP (Nathan Hess) writes:
> >	Is there a program available that creates makefiles, preferrably
> >	written in C?
> 
>    I thought this may be of general interest to the group, so I'm posting
> it here.
>    This problem sounds like something that could be easily done using the
> standard Unix utilities. If your only file dependencies come from #include
> lines in the files, then this should work pretty well. Use fgrep to
> find all the #include's, and pipe it to awk for prettying up.
> You could say something like this:
> fgrep #include *.c *.h | awk -f makefile.awk >makefile
> 
> and makefile.awk might look something like this:
> BEGIN { ORS = " "; filename = 0 }
> { if ($1 != filename) { filename = $1; print "\n" filename,":",$3 }
>   else print " " $3 }
> END { print "\n" }
> 
> 
	.......
> 
> -	-	-	-	-	-	-	-	-
> Steve Creps on the VAX 8650 running Ultrix 2.0-1 at Indiana University.
> 	creps@silver.bacs.indiana.edu
> "F-14 Tomcat! There IS no substitute."
> 

The major issue here (for C programs) is #include files of course;
As pointed out they may be nested and they also may have dependencies
of the #ifdef, and -I (or #if) nature .  Therefore the way to
reliably determine include files is in the environment that
the compilation is desired. Therefore:

	cc -Dwhatever -Dotherstuff -Iwhatever/path -E filename.c |
		sed -n -e 's/^# 1 .*"\(.*\)"/\1/p' | sort -u

Is what you need to find the #include files necessary for a particular
style of compilation.  If you have a fairly recent version of a AT&T
C compiler you can use the -H flag instead of the -E to just get
desired info.

john young

creps@silver.bacs.indiana.edu (Steve Creps) (12/19/87)

   Note: followups to this discussion have been routed to comp.unix.questions,
so you may want to hit "n" now.

In article <178@fxgrp.UUCP> fxgrp!ljz@ames.arpa (Lloyd Zusman, Master Byte Software) writes:
>In article <538@silver.bacs.indiana.edu> creps@silver.UUCP (Steve Creps) writes:
>>In article <1034@cpocd2.UUCP> nate@cpocd2.UUCP (Nathan Hess) writes:
>>>	Is there a program available that creates makefiles, preferrably
>>>	written in C?
>> ...
>>You could say something like this:
>>fgrep #include *.c *.h | awk -f makefile.awk >makefile
>> ...
>
>This sort of thing is fine as far as it goes, but what about nested
>includes?  What about the differences between #includes that use
>double quotes and those that use angle brackets?

   I thought that make was smart enough that if you do have nested
#includes, it would pick this up. Am I wrong about this? That is, if
you have the following lines in the makefile:

aaa.c : bbb.h
bbb.h : ccc.h

and modified ccc.h, won't it know to recompile aaa.c? If so, the fgrep
method should be OK.
   As for the #include's with < >'s (system includes), I don't think
these are ever included in makefiles. If that's the case, then piping
the output from the "fgrep #include" through an "fgrep -v \<" should
take care of that problem. Anyway, I don't mean to argue about this;
the program you mentioned is probably a good thing to have.
   This discussion is really getting off from what the groups involved
are for, so I'm routing followups to comp.unix.questions.

-	-	-	-	-	-	-	-	-
Steve Creps on the VAX 8650 running Ultrix 2.0-1 at Indiana University.
	creps@silver.bacs.indiana.edu
"F-14 Tomcat! There IS no substitute."

wfp@dasys1.UUCP (William Phillips) (12/21/87)

Have you looked into SCCS?  The "makef" function of this source code
control system will create your Makefile for you.  The "help" function
leaves a lot to be desired, though :-)


-- 
William Phillips                 {allegra,philabs,cmcl2}!phri\
Big Electric Cat Public Unix           {bellcore,cmcl2}!cucard!dasys1!wfp
New York, NY, USA                (-: Just say "NO" to OS/2! :-)

garys@bunker.UUCP (Gary M. Samuelson) (12/22/87)

In article <538@silver.bacs.indiana.edu> creps@silver.UUCP (Steve Creps) writes:
>In article <1034@cpocd2.UUCP> nate@cpocd2.UUCP (Nathan Hess) writes:
>>	Is there a program available that creates makefiles, preferrably
>>	written in C?
>
>   I thought this may be of general interest to the group, so I'm posting
>it here.
>   This problem sounds like something that could be easily done using the
>standard Unix utilities. If your only file dependencies come from #include
>lines in the files, then this should work pretty well. Use fgrep to
>find all the #include's, and pipe it to awk for prettying up.
>You could say something like this:
>fgrep #include *.c *.h | awk -f makefile.awk >makefile
>
>and makefile.awk might look something like this:
>BEGIN { ORS = " "; filename = 0 }
>{ if ($1 != filename) { filename = $1; print "\n" filename,":",$3 }
>  else print " " $3 }
>END { print "\n" }

Besides being buggy (for example, foo.c doesn't depend on bar.h,
foo.o does), this doesn't cover several things which I would consider
important in such a utility, (in roughly decreasing order of importance):

1. Header files in a directory other than the one containing the
	makefile.
2. Source files other than 'foo.c' -- such as lex or yacc source.
3. The possibility that one makefile makes several different programs,
	each of which depends on different (but overlapping) subsets
	of include files.
4. Nested includes.  If bar.h includes baz.h, everything that depends
	on bar.h also depends on baz.h
5. The possibility of spaces or tabs between "#" and "include".  Easy
	to fix if you don't use fgrep, but this would hurt performance.
6. "#include" appearing in a comment.
7. "#include" in a conditional compilation context (should such includes
	be, ah, included in the dependencies?)

Of course, I don't know if the original poster considers these
requirements, but I would.

Such a script is bound to be slow.  It will have to be run before
make is run, every time a program is to be built, in case the actual
dependencies have changed (includes added or deleted).

We have a utility called 'gendepend' which generates a dependency list
and appends it to a makefile.  I don't know if it would be proper or
even desirable to post it, and offhand I'm not sure it handles all of
the cases I mentioned.  I know it handles nested includes, and I am
pretty sure it handles include files in other directories, but I am unsure
of the others.  (I personally don't use it that much.)  If there is
sufficient interest, I will look into it.

Gary Samuelson

tim@ora.UUCP (Tim O'Reilly) (12/23/87)

In article <3086@sequent.UUCP>, dougs@sequent.UUCP (Doug Schwartz) writes:
> 
> O'Reilly and Associates have a book out called "UNIX Text Processing",
> which is published by Hayden, that has a shell script on page 566 that
> builds a makefile.  Of course, this is oriented toward n/troff tasks,
> but you can modify it for any environment.  This is left as an exercise
> for the reader :-).
> 
> If you fancy yourself as a n/troff hacker or want to know more about
> UNIX text processing, I highly recommend this book.  

While I appreciate the plug for my book, I have to say that
the makefile generator Doug refers to is quite crude.  It is
aimed at people who don't know much about make, and probably
don't want to.  As a result, it takes a minimally
sophisticated, brute-force approach.  

In short, I wouldn't recommend that anyone get the book for 
pointers on how to use make!  For information on
troff, sed and awk, vi or any of the other text
processing utilities, yes...but the treatment of make (and
of shell programming) is mainly aimed at writers, not
programmers.   It is designed to tease people who might not
otherwise be comfortable with programming into "letting the
computer do the dirty work."

-- 
Tim O'Reilly (617) 527-4210
O'Reilly & Associates, Inc., Publishers of Nutshell Handbooks
981 Chestnut Street, Newton, MA 02164
UUCP:	uunet!ora!tim      ARPA:   tim@ora.uu.net

mmengel@cuuxb.ATT.COM (Marc W. Mengel) (12/24/87)

In article <538@silver.bacs.indiana.edu> creps@silver.UUCP (Steve Creps) writes:
>In article <1034@cpocd2.UUCP> nate@cpocd2.UUCP (Nathan Hess) writes:
>>	Is there a program available that creates makefiles, preferrably
>>	written in C?
>
>You could say something like this:
>fgrep #include *.c *.h | awk -f makefile.awk >makefile

Well, you could do what the maketd utility floating around Purdue
University did, and use the C preprocessor to include all of the
files for you, take the preprocessed output and grab all of the

# 1 "foo.h"
# 1 "/usr/include/bogus.h"

lines out of the file, and use them to generate your dependency lines.
It works quite well. (Maybe someone at Purdue would like to (re?)post
it...
-- 
 Marc Mengel	

 attmail!mmengel
 ...!{moss|lll-crg|mtune|ihnp4}!cuuxb!mmengel

rich@oxtrap.UUCP (K. Richard Magill) (12/31/87)

I once read about a (V8?) utility called build.  Did this ever leave
the author's machine?  or even (gasp) at&t? ;-).

rich.
----------
Real men write self-modifying code.