[distcc] jobserver unavailable...

TMI-Concept tmi-concept at wanadoo.fr
Tue Mar 16 19:23:50 GMT 2004


Hi there,

I fully understand that this subject is for some people obsolete and is 
listed in the FAQ:

Error about "jobserver unavailable"
This indicates a problem with your Makefile or shell. See the 
explanation of this error from GNU make.


++the FAQ links to this post reply:

The message means that the child "make" program received information
implying that it was the child of another "make" program, and was to run
in parallel mode using the jobserver feature, but that when it tried to
connect to the jobserver it couldn't do so.

There are (at least?) three reasons why this might be so:

  1) The parent make didn't realize that the child process it was
     invoking was actually a "make" program.  In this case, it won't
     allow the child to connect to the jobserver.  This is typically
     because the command to invoke the child uses "make" or similar
     rather than the correct $(MAKE).  See the docs on the "+" token to
     understand the algorithm GNU make uses to determine if the child is
     a sub-make or not.

     Adding the "+" to the invocation in the parent will fix this; hence
     the message you got.

  2) You have changed your SHELL to use csh or tcsh.  These shells are
     fundamentally broken and cannot coexist with the jobserver.  You
     will need to use a different SHELL, preferable a Bourne-compatible
     one (sh, ksh, bash, zsh).

  3) There is something about the LSF implementation of GNU make that
     breaks this: note that for the jobserver to work correctly each
     sub-make _MUST_ be a direct fork/exec of its parent.  Running them
     on remote systems, invoking them from servers, etc. will not work.

++ So, as i didn't understand the meaning of this explanation, i went to 
the GNU make manual, appendix B error codes:

`warning: jobserver unavailable: using -j1. Add `+' to parent make rule.'
     In order for make processes to communicate, the parent will pass 
information to the child. Since this could result in problems if the 
child process isn't actually a make, the parent will only do this if it 
thinks the child is a make. The parent uses the normal algorithms to 
determine this (see section 5.6.1 How the MAKE Variable Works). If the 
makefile is constructed such that the parent doesn't know the child is a 
make process, then the child will receive only part of the information 
necessary. In this case, the child will generate this warning message 
and proceed with its build in a sequential manner.

++ And still, no hint to my poor technical knowledge. So i followed the 
" section 5.6.1 How the MAKE Variable Works":

[...] The special feature makes this do what you want: whenever a 
command line of a rule contains the variable MAKE, the flags `-t', `-n' 
and `-q' do not apply to that line. Command lines containing MAKE are 
executed normally despite the presence of a flag that causes most 
commands not to be run. The usual MAKEFLAGS mechanism passes the The 
special feature makes this do what you want: whenever a command line of 
a rule contains the variable MAKE, the flags `-t', `-n' and `-q' do not 
apply to that line. Command lines containing MAKE are executed normally 
despite the presence of a flag that causes most commands not to be run. 
The usual MAKEFLAGS mechanism passes the flags to the sub-make (see 
section 5.6.3 Communicating Options to a Sub-make), so your request to 
touch the files, or print the commands, is propagated to the subsystem.

++ This seems to be closer from what i seek, that is, passing the -j 
option to the make child, so I had a look to the "section 5.6.3 
Communicating Options to a Sub-make":

The `-j' option is a special case (see section 5.3 Parallel Execution). 
If you set it to some numeric value `N' and your operating system 
supports it (most any UNIX system will; others typically won't), the 
parent make and all the sub-makes will communicate to ensure that there 
are only `N' jobs running at the same time between them all. Note that 
any job that is marked recursive (see section 9.3 Instead of Executing 
the Commands) doesn't count against the total jobs (otherwise we could 
get `N' sub-makes running and have no slots left over for any real work!)

If your operating system doesn't support the above communication, then 
`-j 1' is always put into MAKEFLAGS instead of the value you specified. 
This is because if the `-j' option were passed down to sub-makes, you 
would get many more jobs running in parallel than you asked for. If you 
give `-j' with no numeric argument, meaning to run as many jobs as 
possible in parallel, this is passed down, since multiple infinities are 
no more than one.

++ Then to the "section 5.3 Parallel Execution", which, should tell me 
what i want to know:

5.3 Parallel Execution

GNU make knows how to execute several commands at once. Normally, make 
will execute only one command at a time, waiting for it to finish before 
executing the next. However, the `-j' or `--jobs' option tells make to 
execute many commands simultaneously.

On MS-DOS, the `-j' option has no effect, since that system doesn't 
support multi-processing.

If the `-j' option is followed by an integer, this is the number of 
commands to execute at once; this is called the number of job slots. If 
there is nothing looking like an integer after the `-j' option, there is 
no limit on the number of job slots. The default number of job slots is 
one, which means serial execution (one thing at a time).

One unpleasant consequence of running several commands simultaneously is 
that output generated by the commands appears whenever each command 
sends it, so messages from different commands may be interspersed.

Another problem is that two processes cannot both take input from the 
same device; so to make sure that only one command tries to take input 
from the terminal at once, make will invalidate the standard input 
streams of all but one running command. This means that attempting to 
read from standard input will usually be a fatal error (a `Broken pipe' 
signal) for most child processes if there are several.

It is unpredictable which command will have a valid standard input 
stream (which will come from the terminal, or wherever you redirect the 
standard input of make). The first command run will always get it first, 
and the first command started after that one finishes will get it next, 
and so on.

We will change how this aspect of make works if we find a better 
alternative. In the mean time, you should not rely on any command using 
standard input at all if you are using the parallel execution feature; 
but if you are not using this feature, then standard input works 
normally in all commands.

Finally, handling recursive make invocations raises issues. For more 
information on this, see section 5.6.3 Communicating Options to a Sub-make.

++ Now, My last alternative is to go back to the "section 5.6.3 
Communicating Options to a Sub-make." Looks like i finally won't find 
any simple answer to my problem, and even go to a brain deadlock.

So is there any possibility to have a simple and explicit example of 
what make expects in order to run a kernel compilation using distcc ? 
The example string listed in the "man distcc" led (lead?) me to this:

make -j4 CC=distcc bzImage:

make[1]: warning:jobserver unavailble: using -j1. Add `+' to parent make 
rule.

How do I  "Add `+' to parent make rule." in the command line ?
What variable / rule of the Makefile should I change to "Add `+' to 
parent make rule." ?

I once again apologize for such an indigest post, but this is how The 
Friendly Manual is. This post certainly written in poor english for it 
is not my native language, and i apologize for this too, but all over 
the web this place seems to be the only one where people should have the 
answer.

Thanks in advance and best regards,

G.Girard.

P.S: I'm using distcc 2.12.1 on a debian sarge with 2.4.24 kernel.
gcc version is 2.95.4-17, make version is 3.80-4. (according to debian 
packages).




More information about the distcc mailing list