[comp.lang.c] Compiler gen'd depends

john@iastate.edu (Hascall John Paul) (04/17/91)

   For those with Ultrix, you may want to check out the undocumented
(in my old docs anyhow) option "-Em", as in this simple-minded example:

      $(CC) -Em $(CFLAGS) $(DEFINES) $(CSOURCES) >>Makefile

John

--
John Hascall                        An ill-chosen word is the fool's messenger.
Project Vincent
Iowa State University Computation Center                       john@iastate.edu
Ames, IA  50011                                                  (515) 294-9551

geels@cs.vu.nl (Arnold Geels) (04/17/91)

john@iastate.edu (Hascall John Paul) writes:

>   For those with Ultrix, you may want to check out the undocumented
>(in my old docs anyhow) option "-Em", as in this simple-minded example:
>
>      $(CC) -Em $(CFLAGS) $(DEFINES) $(CSOURCES) >>Makefile
>
>John

Gcc and cc (Sun) both have a documented -M flag that tells the compiler to
generate makefile dependencies. Gcc also has the -MM flag (exclude system
header files).

Arno1d.

----------------
Arnold Geels
Vrije Universiteit Amsterdam
The Netherlands.

scs@adam.mit.edu (Steve Summit) (04/19/91)

One of the things you discover when you start writing a Makefile
dependency generator (one that scans source files automatically
for #include directives) is that you have to reimplement an
uncomfortably large fraction of a full-blown C preprocessor to do
so.  (I handled #define and #ifdef, and fell back and punted when
it came to #if.)  Therefore, it becomes reasonable to inquire
whether the "real" C preprocessor could be coaxed into helping
out.  To do so begins to encroach on the "Unix Philosophy" (each
tool should do one job, and do it well), since helping to build
Makefiles has not much to do with the task of preprocessing C source.
In this case, I'd say it's justified, if not carried too far.

In article <1991Apr17.003928.23530@news.iastate.edu> john@iastate.edu (Hascall John Paul) writes:
>   For those with Ultrix, you may want to check out the undocumented
>(in my old docs anyhow) option "-Em", as in this simple-minded example:
>
>      $(CC) -Em $(CFLAGS) $(DEFINES) $(CSOURCES) >>Makefile

This is doubtless related to the cpp -M flag, which was
introduced (I believe) by Berkeley.  Though motivated by good
intentions mirroring the discussion above, the behavior of this
option, as implemented, goes too far.  It's one thing to add an
option to a preprocessor/compiler meaning "don't preprocess or
compile; just emit names of #include files read."  This is still
within the "job" of preprocessing, if only marginally.

It's quite another thing to have the names emitted via lines of
the form

	<name-of-source-file-with-.c-replaced-by-.o> <colon> <included-file>

This couples the preprocessor unnecessarily and unacceptably to the
make utility's syntax.  It would be far better simply to emit the
#include lines themselves, or to emit lines of the form

	<name-of-source-file> <included-file> <flag>

where flag indicates whether the #include used the "" or <>
syntax (and perhaps whether -I, or a standard include directory,
was involved).

(Another clue that there's something wrong here:

	/lib/cpp /dev/tty

works as expected, while

	/lib/cpp -M /dev/tty

complains about a "missing component name on /dev/tty", because
it can't replace .c with .o .  cpp is not a general-purpose
preprocessor, but it shouldn't be playing with filenames in this
way.)

If my objection were only philosophical, I'd stew quietly and not
bring it up.  However, while trying to make things convenient for
a simpleminded >> Makefile build (but since when has Unix held
your hand?), this overprocessed output format, by losing
information, precludes alternate, more flexible dependency
generation strategies.  For instance, I like not to clutter my
Makefiles with dependencies on the header files in /usr/include
(if they ever change, one had better delete every .o file
everywhere and rebuild everything), and to treat other <>
dependencies (which typically refer to files in directories
specified with -I) differently.

In article <9734@star.cs.vu.nl> geels@cs.vu.nl (Arnold Geels) writes:
>Gcc also has the -MM flag (exclude system
>header files).

This is (sort of) a step in the right direction, giving one a bit
of control over the "" vs. <> distinction, but it's not fine-
grained enough.  Nothing derived from -M (as currently defined)
could be; gaining full control requires taking a step back and
having the "emit dependencies" option to the preprocessor emit
the dependency information in a lower-level, unprocessed form.

To be sure, doing so would require the insertion of an awk or sed
script in even simple Makefile builds, but it would not be a
difficult or complicated script.  Changing ".c" to ".o", inserting
colons, and making decisions based on strings ("" vs. <>) is
those tools' job.

Unfortunately, the current definition of the -M flag is a de
facto standard now, and many, many Makefiles depend (sic) on it.
I suppose I should have complained more loudly when 4.3bsd first
came out; it's a bit late to be whining about it now.

This has little to do with C; I've redirected followups to
comp.unix.programmer .

                                            Steve Summit
                                            scs@adam.mit.edu

dave@aspect.UUCP (Dave Corcoran) (04/25/91)

In article <9734@star.cs.vu.nl>, geels@cs.vu.nl (Arnold Geels) writes:
> john@iastate.edu (Hascall John Paul) writes:
> >   For those with Ultrix, you may want to check out the undocumented
> >(in my old docs anyhow) option "-Em", as in this simple-minded example:
> >
> Gcc and cc (Sun) both have a documented -M flag that tells the compiler to
> generate makefile dependencies. Gcc also has the -MM flag (exclude system
> header files).
> 

Sun make also has a target name ".KEEP_STATE:" which when found in your
makefile will interrogate the compliler for dependencies and keep them
hidden from view in a file named ".make.state"; tis very nice.
-- 
David Corcoran		      -@@
uunet!aspect!dave	        ~
In a society where anything goes eventually everything will.