Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I tell if --jobs is used inside a Makefile?

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
like image 793
onionjake Avatar asked Apr 03 '14 15:04

onionjake


People also ask

What does ?= In makefile mean?

?= 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"

How do you debug a makefile variable?

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.

How do I use IFEQ in makefile?

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.

What is at in makefile?

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.


2 Answers

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
like image 192
bobbogo Avatar answered Nov 14 '22 14:11

bobbogo


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.

like image 20
Hakan Baba Avatar answered Nov 14 '22 15:11

Hakan Baba