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
?= indicates to set the KDIR variable only if it's not set/doesn't have a value. For example: KDIR ?= "foo" KDIR ?= "bar" test: echo $(KDIR) Would print "foo"
Finally, you can also debug the Makefile by running Make with the debug flag: make -d . This will print all the rules (including built-in ones) that Make tries for each of the targets, and whether or not a rule needs to be run.
The ifeq directive begins the conditional, and specifies the condition. It contains two arguments, separated by a comma and surrounded by parentheses. Variable substitution is performed on both arguments and then they are compared.
The @ symbol is commonly seen at the beginning of an action lines and means that the action line itself is not be be echoed on the screen as it is executed. Macros are commonly used in makefiles to decrease the amount of typing required.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With