Subject: RE: B19.1 make.exe - mishandling set -e, excessive target activity
From: [email-masked] (Peter A. Vogel)

19 Oct 1998 07:56:43 -0700
Message-ID: <[email-masked]>
References: <[email-masked]>
Mime-Version: 1.0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
To: "Luke Kendall" <[email-masked]>,
        <[email-masked]>, <[email-masked]>

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]]On
> Behalf Of Luke Kendall
> Sent: Thursday, October 15, 1998 12:20 AM
> To: [email-masked]; [email-masked]
> Cc: [email-masked]
> Subject: B19.1 make.exe - mishandling set -e, excessive target activity
> 
> 
> Apologies if this is the wrong place(s) to report these problems.
> make.exe suggested the first address; reading between the lines
> of "reporting bugs" on the web pages suggests the 2nd...
> 
> I'm doing this under Windows NT4.0 sp3, using Cygnus Beta 19.1
> and therefore GNU Make version 3.75-B19.
> 
> Problem 1
> ---------
> The first problem is a peculiar difference between gmake under
> Unix and Windows.  In the makefile shown below, the first
> part of the main target is to make sure that errors are ignored
> or not in blocks of shell commands, by detecting -k.
> 
> The problem is that it works under Unix and fails on my machine.
> Deleting the "set -e" line makes it work under NT!
> 
> MAKE_MODE = UNIX
> SUBDIRS = a b c
> 
> #
> # Targets for various build tasks.
> #
> all :
>         @set -e;\
>         for flg in $(MAKEFLAGS) '';\
>         do\
>             case $$flg in\
>             *=*) ;;\
>             *k*) set +e;;\
>             esac;\
>         done;\
>         for d in $(SUBDIRS);\
>         do\
>             echo cd $$d;\
>             cd $$d;\
>             echo $(MAKE) $@;\
>             $(MAKE) $@;\
>             cd ..;\
>         done
> 

Note that there are far more efficient ways to check for -k!  
$(filter ) for example.   In general what you are doing is
not needed. 

> Problem 1b:
> ----------
> Another oddity is that if you change the early part to:
> 
> all :
>         @echo "subdirs are: $(SUBDIRS)";\
>         set -e;\
> 
> then it looks like some odd "echo" command is used
> that doesn't understand quoting or ";" separators, as
> it also grabs all the following lines for the "echo".
> 
> You'll note that this is despite the MAKE_MODE = UNIX
> 
> The second problem may be related.

Don't know what you're getting there, I don't see this problem.

> 
> Problem 2
> ---------
> If I make these two files:
> 
> --- file test.gmk ---
> 
> all:
> 	@echo all done
> 
> include other
> 
> --- file other ---
> 
> do_other:
> 	@echo other stuff
> 
> ----
> 
> And try:
> 	make -f test.gmk -d
> 
> The output (and the amount of time make takes) suggests
> that it is really trying to treat  "test.gmk" and "other"
> as targets!!

This is correct!  

Gnumake is a far better make than standard unix make, one of the
things it does it make sure that the makefile itself and any 
included makefiles are up to date.  This is really cool, since it
lets you do things like:

include $(SRCS:%.c=%.d)

With a rule like this in the makefile:

%.d: %.c
	gcc -MM $(CFLAGS) $< > $@

To make sure your dependencies are always up to date, and only
regenerate the ones that aren't.

> 
> This is true of gmake under Unix and Windows.

Yep.

> 
> Needless to say, the traditional Unix make doesn't
> behave this way.

Because it is older and more brain dead.  Gnumake represents
PROGRESS.

> 
> The reason I stumbled over this was while trying to debug
> a much more complex makefile, and in the debug output I
> saw attempts to find rules for files which shouldn't even
> have been included...
> 
> BTW, what's the SIGCHLD and unreaped child?  It looks worrying:

SIGCHLD indicates that a child process completed, an unreaped child
is a child process in gnumake's list of processes that have not
completed.   In general, if make is getting a SIGCHLD and it has
unreaped processes, the correct things are happening.  You need
to worry if gnumake gets a SIGCHLD and DOESN'T have any unreaped
processes.  

Let's walk through this:

> 
> Must remake target `all'.
> Putting child 0x02a7a1a0 PID 01001 on the chain.
> Live child 0x02a7a1a0 PID 1001

So, here gnumake has invoked a child process to do whatever
needs to be done to remake the target named "all".

> all done

This is presumably output from the child process

> Got a SIGCHLD; 1 unreaped children.

The child process finished, there is one child process expected 
(by gnumake to complete)

> Live child 0x02a7a1a0 PID 1001

This is the unreaped child.

> Reaping winning child 0x02a7a1a0 PID 1001

The SIGCHLD came from the process in gnumake's process chain
(i.e. we have a match, this is GOOD).

> Removing child 0x02a7a1a0 PID 1001 from chain.

We matched, so we remove the child from the process.

> Successfully remade target file `all'.

Since it was a "winning child" (i.e. exited with status==0) we
successfully remade the target.

Get the gnumake docs, read them, your questions illustrate that
you are new to gnumake, and possibly make in general, it's not
rocket science, but it does take some learning and the docs
are a good way to get what you need.  I'm also more than willing
to answer questions for you, as are others on the list, I'm sure.

-Peter
-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".