Pergunta

I want to set some variables based on whether or not parallel builds are enabled, so I tried this:

jobs:
»·echo "executing jobs job"

ifneq (,$(findstring -j,$(MAKEFLAGS)))
»·$(warning "parallel!")
else
»·$(warning "not parallel!")
endif

And this is what happens:

$ make -j2
Makefile:2: "not parallel!"
echo "executing jobs job"
executing jobs job

I also tried testing $(JOBS), but no luck.

Is there a way for me to tell inside a Makefile that the --jobs parameter was used?


Additional info:

$ make --version
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for x86_64-pc-linux-gnu
Foi útil?

Solução

Surprisingly, ${MAKEFLAGS} will only gain the -j when it is expanded at recipe expansion time.

Makefile:

$(warning [${MAKEFLAGS}])

.PHONY: all
all:
    $(warning [${MAKEFLAGS}])
    echo Now do something useful

Run:

$ make -j5
1:1: []
1:5: [ -j --jobserver-fds=3,4]
echo Now do something useful
Now do something useful

Outras dicas

About the MAKEFLAGS expansion in @bobbogo's answer: If we look at the code I think I can explain the behavior:

Looking at the code, main function of make calls the define_makeflags function several times.

/* Define the MAKEFLAGS and MFLAGS variables to reflect the settings of the
   command switches.  Include options with args if ALL is nonzero.
   Don't include options with the 'no_makefile' flag set if MAKEFILE.  */

static struct variable *
define_makeflags (int all, int makefile)
{
......

Call locations in main:

1)

 /* Set up the MAKEFLAGS and MFLAGS variables for makefiles to see.
    Initialize it to be exported but allow the makefile to reset it.  */
 define_makeflags (0, 0)->export = v_export;

2)

 /* Set up MAKEFLAGS and MFLAGS again, so they will be right.  */

 define_makeflags (1, 0);

3)

 /* Set up 'MAKEFLAGS' specially while remaking makefiles.  */
 define_makeflags (1, 1);

There are other calls in sub-functions but this should be enough to explain.

The first call sets all parameter to false. The others set to true. With all set to false, the define_makeflags function only parses "simple flags" and j is not one of them. In order to understand the parsing one needs to look into this switch statement and the definition of command line params.

My SWAG is like the following:

I presume the parsing of ifneq statements happen after the first call to define_makeflags but before the subsequent calls. I can guess the reason of keeping the MAKEFLAGS simple at the start is to continue to support documented Makefile patterns like the following.

From doc1, doc2:

archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
        +touch archive.a
        +ranlib -t archive.a
else
        ranlib archive.a
endif

If MAKEFLAGS contained long options or options that take parameters, then searching for single char flags in MAKEFLAGS would not be possible.

There is some guesstimate in my answer. Maybe someone who was involved in the design decision can also weigh in. Given this change Paul Smith may have an idea.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top