[comp.sources.wanted] anyone want to redesign make?

slehar@park.bu.edu (Steve Lehar) (04/18/91)

There are  two major  problems  with the current  concept of  make and
makefiles.  I was wondering whether  anyone  else sees these problems,
and whether anyone has addressed them already, or even, whether anyone
wants to fix the make problem.

The first problem with  the make concept  is  that although the source
code  is  often nearly  useless  without it's makefile,   the makefile
resides primarily in a  directory, whereas  the source code  should be
free to travel around as needed.  If I wish to copy a program from one
directory to  another, I  must not  only copy the  source and  all its
dependancies, but   I must  also  cut  the   pertinant lines  from the
makefile in the source directory and paste them into a makefile in the
destination  directory.  Of course  any symbolic definition  conflicts
must be resolved.

The solution would  be simple- the  makefile should be appended to the
front of the source code,  like a header,  carefully shielded from the
compiler   by comment  delimiters,  and  flagged  by specific makefile
delimiters.  For instance, "program.c" might contain the lines...

/* %M	program: program.c subr.c			*/
/* %M	cc -c -o subr.o subr.c				*/
/* %M   cc -o program program.c subr.o			*/

where %M, for instance, could flag the make program to interpret these
lines, while the /* */ would flag the compiler to ignore  these lines.
With  this simple modification,  the source code  itself would contain
the  information   about    all its   dependancies,    and compilation
instructions.  You  could  now copy   programs  from one directory  to
another without having to touch any makefiles.  You could even write a
simple "copy with dependancies"  command that  would copy the original
source and automatically copy  all the dependancies with  it.  So, for
instance, the command...

  cwd dir1/program.c dir2

would automatically copy program.c and subr.c into dir2,  and complain
if it found a dependancy missing.

The  second  problem with  makefiles is    their  syntax, which  is so
complicated and obscure that even system  managers and unix gurus have
trouble  with them unless  they  adhere rigidly to  their own personal
conventions.  (When you ask them why your makefile doesn't work, their
response is always "Why are you doing it like that?  Try doing it this
way" to which you reply "Because the last guy said 'Why are  you doing
it like  that?  Try doing it this  way' and I  did!")  The  problem, I
have decided, is all of the automatic 'helpful' things  that make does
for you behind your back without being explicitly asked to do, such as
assuming  default  dependancies and assuming  specific file extensions
and  automatically naming output files and  so forth. These  work fine
when they work fine,  but when they  don't they become   the devil  to
debug because they are hidden.	 The simple solution would  be to make
the make function much more simple and direct, a "whizzywig" approach,
what you see is what you get.  Something like:

/* %M NAME	program					*/
/* %M DEP	program.c subr.o			*/
/* %M EXECUTE	cc -o program program.c subr.o		*/
/*							*/
/* %M NAME	subr					*/
/* %M DEP	subr.o					*/
/* %M EXECUTE	cc -c -o subr.c				*/

An additional advantage of this approach is that it would make the
make program much easier to write.

So, anyone want to try it, or has it already been done?


--
(O)((O))(((O)))((((O))))(((((O)))))(((((O)))))((((O))))(((O)))((O))(O)
(O)((O))(((               slehar@park.bu.edu               )))((O))(O)
(O)((O))(((    Steve Lehar Boston University Boston MA     )))((O))(O)
(O)((O))(((    (617) 424-7035 (H)   (617) 353-6741 (W)     )))((O))(O)
(O)((O))(((O)))((((O))))(((((O)))))(((((O)))))((((O))))(((O)))((O))(O)

pds@lemming.webo.dg.com (Paul D. Smith) (04/19/91)

This discussion is totally improper for comp.sources.wanted, put a
quick perusal didn't turn up another good group: makefiles exist on
PCs as well as UNIX, so ... if anyone has an idea, please let me know.

[] On 18 Apr 91 14:58:35 GMT, slehar@park.bu.edu (Steve Lehar) said:

SL> There are  two major  problems  with the current  concept of  make and
SL> makefiles.  I was wondering whether  anyone  else sees these problems,
SL> and whether anyone has addressed them already, or even, whether anyone
SL> wants to fix the make problem.

I agree that there are problems with make, but I don't agree with most
of the rest of your post; here's why:

SL> The first problem with  the make concept  is  that although the source
SL> code  is  often nearly  useless  without it's makefile,   the makefile
SL> resides primarily in a  directory, whereas  the source code  should be
SL> free to travel around as needed.  If I wish to copy a program from one
SL> directory to  another, I  must not  only copy the  source and  all its
SL> dependancies, but   I must  also  cut  the   pertinant lines  from the
SL> makefile in the source directory and paste them into a makefile in the
SL> destination  directory.  Of course  any symbolic definition  conflicts
SL> must be resolved.

I'm really afraid I don't see what you're talking about: why don't you
just copy the whole makefile as well?  Then you'll have the sources
and the makefile and everything will work just fine.  Right?

Unless you're talking about using the same source files in two
different programs which have different makefiles: and then why not
use libraries or some such?  At the very least, free programs which
will produce makefiles for you are abundant on the net...

Or maybe your makefiles use full pathnames instead of relative
pathnames, which is a no-no anyway: at least make the path prefix be a
variable so you can modify it easily.

SL> The  second  problem with  makefiles is    their  syntax, which  is so
SL> complicated and obscure that even system  managers and unix gurus have
SL> trouble  with them unless  they  adhere rigidly to  their own personal
SL> conventions.

I wouldn't go *that* far, but I do agree that makefile syntax is less
than ideal, especially in older make implementations which are
incredibly fussy about strange things.  New make programs (esp. things
like GNU make) are much better.

SL> ... The problem, I have decided, is all of the automatic 'helpful'
SL> things that make does for you behind your back without being
SL> explicitly asked to do, such as assuming default dependancies and
SL> assuming specific file extensions and automatically naming output
SL> files and so forth.

This is one of the *best* features of make.  Taking this out would
leave make relatively useless.  These things are really trivial to
understand if people take the time to learn them; the simple rule is:
if there's no rule specified, then make will try to pick one from its
list of default rules.  Which one is easily determined by looking at
the syntax of the TARGET and the first DEPENDANCY.  Then match them up
with the default rules listed in the man page (or you can make make
produce its default rule set itself).

Or better still, run it & see which one it uses.  One of the biggest
problems with make is there is no good manual--see the GNU make
product for a decent manual.  However, even most make man pages list
the default ruleset.

SL> These work fine when they work fine, but when
SL> they don't they become the devil to debug because they are
SL> hidden.

True, sort of, see above and below...

SL> The simple solution would be to make the make function
SL> much more simple and direct, a "whizzywig" approach, what you see
SL> is what you get.  Something like:

SL> /* %M NAME	program					*/
SL> /* %M DEP	program.c subr.o			*/
SL> /* %M EXECUTE	cc -o program program.c subr.o		*/
SL> /*							*/
SL> /* %M NAME	subr					*/
SL> /* %M DEP	subr.o					*/
SL> /* %M EXECUTE	cc -c -o subr.c				*/

SL> An additional advantage of this approach is that it would make the
SL> make program much easier to write.

This is even worse than the last!  All the flexibility is gone!!
Given your scheme, how would I then add a -DDEBUG option to the
command line?  How would I compile it for profiling or debugging or
even optimization?  I would have to go through each source file and
change it!  Ugh!  Putting make commands in the source file, for
anything except trivial one-file programs, is just asking for disaster
once something changes.

----------------------------------------

There are programs (public-domain ones) which can build a reasonable
makefile for you with no trouble at all.  Heck, even my compiler (gcc)
can output a simple make dependancy line:

- foo.c --------------------
#include <stdio.h>
#include <sys/time.h>
#include "foo.h"
#include "bar.h"

 ...
-------------------- foo.c -

    % gcc -MM foo.c > makefile

    % cat makefile
    foo.o : foo.c foo.h bar.h

    % make foo.o
            cc -c foo.c
    %

----------------------------------------

Here's my list of problems with make:

  * I *hate* the fact that the TAB character is the delimiter for
    rules.  What sadist thought of having an invisible character be so
    important?  Even a trivial change like "all rules must begin in
    column 1; any subsequent lines not beginning in column 1 are
    continuations of the rule" would be a vast improvement, and
    wouldn't break hardly any existing makefiles.  With the advent of
    editors which don't necessarily put a ^I in your file when you hit
    TAB, the TAB delimiter rule is a pain.

  * make programs could use a good dose of advanced error reporting!
    Most make programs output such cryptic errors when something
    happens that it's impossible to figure out from the message what
    (or even where) the problem really is.

  * make was not designed to work in large environments, i.e. ones
    where the source is spread out in many different directories.  In
    particular, I'd like to be able to do something like:

     1) Have a "stable" directory with valid, stable source in it.

     2) Have a working directory in which exist only the files I'm
        modifying.

     3) When I build, have make build a local copy of the target if I
        have a local copy of the dependancy.  If not, then make should
        use the stable version of the target if it exists.  If it
        doesn't, make should build a local copy of the target from the
        stable dependancy.

        Basically, I want make to "do the right thing" when I have
        only some of the source files in my working directory: it
        should never build anything in the stable directory, and it
        should use everything in the stable directory except what I
        have actually modified in the working directory.

    I have never been able to get this to work.  If you think you have
    a way to do it, please: send me an example makefile!  I'm not
    adverse to using more advanced make features such as those found
    in GNU make, either.

                                                                paul
-----
 ------------------------------------------------------------------
| Paul D. Smith                          | pds@lemming.webo.dg.com |
| Data General Corp.                     |                         |
| Network Systems Development Division   |   "Pretty Damn S..."    |
| Open Network Systems Development       |                         |
 ------------------------------------------------------------------

fangchin@elaine54.Stanford.EDU (Chin Fang) (04/21/91)

In article <PDS.91Apr18202635@lemming.webo.dg.com> pds@lemming.webo.dg.com (Paul D. Smith) writes:
[lots pros and cons of current make and GNU make, good and bad points]

Gentlemen/women:

Handling large project with src scattered all over the places has been a 
problem in the MIT Athena Project, and one solution proposed and now heavily
used is the imake(n) utility (should I put it in imake(1)?).  The learning
curve is steep but it DOES do what's designed to.  Have you guys looked into
it yet?  Just curious.

Jonathan of MIT Athena Project should be able to give all of us a better
perspective.  Hey Jonathan, please speak up.  (I am afraid Jim is too busy
to answer such)

Chin Fang
Mechanical Engineering Department
Stanford University
fangchin@leland.stanford.edu

jik@athena.mit.edu (Jonathan I. Kamens) (04/21/91)

  (Note cross-post and Followup-To.)

In article <1991Apr20.171401.16032@leland.Stanford.EDU> fangchin@elaine54.Stanford.EDU (Chin Fang) writes:

   Handling large project with src scattered all over the places has been a 
   problem in the MIT Athena Project,

"MIT Project Athena," not "the MIT Athena Project." :-)

   and one solution proposed and now heavily
   used is the imake(n) utility (should I put it in imake(1)?).

Yes.  One of the most important features of what Project Athena has
done is that since we support several different platforms, our source
code must compile on all of those platforms.  The same Makefile can't
be used on Multiple platforms, and the solution we ended up using is
Imake.

I suspect that the first big use of Imake was the X Consortium's --
The sources distributed by the Consortium (which, by the way, is now
separate from Project Athena, although X started out at Athena) are
completely Imake-based, and you have to build Imake and use it to
build the X distribution.  Since X started using it, Athena has
distributed the Kerberos, Zephyr and OLC packages using Imake too.

Imake does solve many of the problems in make.  However, in my opinion
it is not the optimal solution.

   The learning
   curve is steep

Yup.  This is one reason I'm not convinced it's the optimal solution.
What I've discovered is that the huge Imake template and rules files
that generally come with a distribution are very daunting and scare
people away from learning it.  However, when people realize that they
don't have to understand how all the rules files work, just how to
pick the right rules in their Imakefiles, things suddenly get much
easier.

   but it DOES do what's designed to.

Yes.  Unfortunately, I don't think it's designed to solve *all* of the
problems with make that have been mentioned here.

Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

mjf@mjm.mjm.com (Mark Fresolone) (04/22/91)

| pds@lemming.webo.dg.com (Paul D. Smith) /  7:26 pm  Apr 18, 1991 /
|  * make was not designed to work in large environments, i.e. ones
|    where the source is spread out in many different directories.  In
|    particular, I'd like to be able to do something like:
|     1) Have a "stable" directory with valid, stable source in it.
|     2) Have a working directory in which exist only the files I'm
|        modifying.
|     3) When I build, have make build a local copy of the target if I
|        have a local copy of the dependancy.  If not, then make should
|        use the stable version of the target if it exists.  If it
|        doesn't, make should build a local copy of the target from the
|        stable dependancy.

AT&T uses "nmake", an implementation with usability problems of its own,
but one which uses a PATH-style variable called VPATH for "view path"
to point to a list of dependency directories of the nature you describe.
You can leverage off off of existing binaries, as well as source from
other "more-stable" tops-of-trees, although there is (or was when I last
saw it) no checking for matching compiler options.  Some folks in AT&T
said it would be re-marketing nmake as of last year.

The most advanced, distributed, cycle-conserving build manager (actually
Configuration Manager) is probably DSEE from Apollo.  It's Binary Pools
automatically maintain not only versions of source, but compiler options
and version of the build tools (/bin/cc, etc.).  Of course, it is still
proprietary......

Make was state of the art fifteen years ago.  *make are sophisticated
hacks.  It is interresting to see new technology which provides no
real upward compatibility, yet adheres somehow to acient, outdated,
but venerated paradigms.  of course, in some cases, it's just
"code reuse gone amuk".

Mark Fresolone					mjf@mjm.com, rutgers!mjm!mjf
Melillo Consulting/MJM Software			908-873-0620/Fax 908-873-2250